From e7546cd4af2cfa8b500ed987a388e459f1c6ccc3 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 2 Jun 2020 19:59:33 +0200 Subject: [PATCH 01/98] Remove LabelDef from BackendInterface --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 50 +------------------ .../tools/backend/jvm/BCodeSkelBuilder.scala | 43 ---------------- .../tools/backend/jvm/BCodeSyncAndTry.scala | 3 -- .../tools/backend/jvm/BackendInterface.scala | 19 ------- .../backend/jvm/DottyBackendInterface.scala | 12 ----- 5 files changed, 1 insertion(+), 126 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 54c14db8cc54..fdfa00f85159 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -258,8 +258,6 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case lblDf @ LabelDef(_, _, _) => genLabelDef(lblDf, expectedType) - case ValDef(_, `nme_THIS`, _, _) => debuglog("skipping trivial assign to _$this: " + tree) @@ -504,18 +502,6 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } } - private def genLabelDef(lblDf: LabelDef, expectedType: BType): Unit = lblDf match { - case LabelDef(_, _, rhs) => - - assert(int.hasLabelDefs) // scalac - - // duplication of LabelDefs contained in `finally`-clauses is handled when emitting RETURN. No bookkeeping for that required here. - // no need to call index() over lblDf.params, on first access that magic happens (moreover, no LocalVariableTable entries needed for them). - markProgramPoint(programPoint(lblDf.symbol)) - lineNumber(lblDf) - genLoad(rhs, expectedType) - } - private def genLabeled(tree: Labeled): BType = tree match { case Labeled(bind, expr) => @@ -755,11 +741,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case app @ Apply(fun, args) => val sym = fun.symbol - if (sym.isLabel) { // jump to a label - assert(int.hasLabelDefs) - genLoadLabelArguments(args, labelDef(sym), app.pos) - bc goTo programPoint(sym) - } else if (isPrimitive(fun)) { // primitive method call + if (isPrimitive(fun)) { // primitive method call generatedType = genPrimitiveOp(app, expectedType) } else { // normal method call val invokeStyle = @@ -1009,36 +991,6 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } } - /* Generate code that loads args into label parameters. */ - def genLoadLabelArguments(args: List[Tree], lblDef: LabelDef, gotoPos: Position) = lblDef match { - case LabelDef(_, param, _) => - - val aps = { - val params: List[Symbol] = param - assert(args.length == params.length, s"Wrong number of arguments in call to label at: $gotoPos") - - def isTrivial(kv: (Tree, Symbol)) = kv match { - case (This(_), p) if p.name == nme_THIS => true - case (arg @ Ident(_), p) if arg.symbol == p => true - case _ => false - } - - (args zip params) filterNot isTrivial - } - - // first push *all* arguments. This makes sure multiple uses of the same labelDef-var will all denote the (previous) value. - aps foreach { case (arg, param) => genLoad(arg, locals(param).tk) } // `locals` is known to contain `param` because `genDefDef()` visited `labelDefsAtOrUnder` - - // second assign one by one to the LabelDef's variables. - aps.reverse foreach { - case (_, param) => - // TODO FIXME a "this" param results from tail-call xform. If so, the `else` branch seems perfectly fine. And the `then` branch must be wrong. - if (param.name == nme_THIS) mnode.visitVarInsn(asm.Opcodes.ASTORE, 0) - else locals.store(param) - } - - } - def genLoadArguments(args: List[Tree], btpes: List[BType]): Unit = { (args zip btpes) foreach { case (arg, btpe) => genLoad(arg, btpe) } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index a16f3bed5057..3d704a8bd14d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -401,30 +401,6 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* ---------------- Part 2 of program points, ie Labels in the ASM world ---------------- */ - /* - * The semantics of try-with-finally and synchronized-expr require their cleanup code - * to be present in three forms in the emitted bytecode: - * (a) as normal-exit code, reached via fall-through from the last program point being protected, - * (b) as code reached upon early-return from an enclosed return statement. - * The only difference between (a) and (b) is their next program-point: - * the former must continue with fall-through while - * the latter must continue to the next early-return cleanup (if any, otherwise return from the method). - * Otherwise they are identical. - * (c) as exception-handler, reached via exceptional control flow, - * which rethrows the caught exception once it's done with the cleanup code. - * - * A particular cleanup may in general contain LabelDefs. Care is needed when duplicating such jump-targets, - * so as to preserve agreement wit the (also duplicated) jump-sources. - * This is achieved based on the bookkeeping provided by two maps: - * - `labelDefsAtOrUnder` lists all LabelDefs enclosed by a given Tree node (the key) - * - `labelDef` provides the LabelDef node whose symbol is used as key. - * As a sidenote, a related map is `jumpDest`: it has the same keys as `labelDef` but its values are asm.Labels not LabelDef nodes. - * - * Details in `emitFinalizer()`, which is invoked from `genLoadTry()` and `genSynchronized()`. - */ - var labelDefsAtOrUnder: scala.collection.Map[Tree, List[LabelDef]] = null - var labelDef: scala.collection.Map[Symbol, LabelDef] = null// (LabelDef-sym -> LabelDef) - // bookkeeping the scopes of non-synthetic local vars, to emit debug info (`emitVars`). var varsInScope: List[(Symbol, asm.Label)] = null // (local-var-sym -> start-of-scope) @@ -472,11 +448,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { case DefDef(_, _, _, _, _, rhs) => locals.reset(isStaticMethod = methSymbol.isStaticMember) jumpDest = immutable.Map.empty[ /* LabelDef */ Symbol, asm.Label ] - // populate labelDefsAtOrUnder - val ldf = getLabelDefOwners(rhs) - labelDefsAtOrUnder = ldf.withDefaultValue(Nil) - labelDef = labelDefsAtOrUnder(rhs).map(ld => (ld.symbol -> ld)).toMap // check previous invocation of genDefDef exited as many varsInScope as it entered. assert(varsInScope == null, "Unbalanced entering/exiting of GenBCode's genBlock().") // check previous invocation of genDefDef unregistered as many cleanups as it registered. @@ -574,21 +546,6 @@ trait BCodeSkelBuilder extends BCodeHelpers { // TODO needed? for(ann <- m.symbol.annotations) { ann.symbol.initialize } initJMethod(flags, params.map(p => p.symbol.annotations)) - /* Add method-local vars for LabelDef-params. - * - * This makes sure that: - * (1) upon visiting any "forward-jumping" Apply (ie visited before its target LabelDef), and after - * (2) grabbing the corresponding param symbols, - * those param-symbols can be used to access method-local vars. - * - * When duplicating a finally-contained LabelDef, another program-point is needed for the copy (each such copy has its own asm.Label), - * but the same vars (given by the LabelDef's params) can be reused, - * because no LabelDef ends up nested within itself after such duplication. - */ - for(ld <- labelDefsAtOrUnder(rhs); LabelDef(_, ldpl ,_) = ld; ldp <- ldpl; if !locals.contains(ldp)) { - // the tail-calls xform results in symbols shared btw method-params and labelDef-params, thus the guard above. - locals.makeLocal(ldp) - } if (!isAbstractMethod && !isNative) { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index 606e3ca8c1c3..73131e520acb 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -392,9 +392,6 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { var saved: immutable.Map[ /* LabelDef */ Symbol, asm.Label ] = null if (isDuplicate) { saved = jumpDest - for(ldef <- labelDefsAtOrUnder(finalizer)) { - jumpDest -= ldef.symbol - } } // when duplicating, the above guarantees new asm.Labels are used for LabelDefs contained in the finalizer (their vars are reused, that's ok) if (tmp != null) { locals.store(tmp) } diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index e04809cb510d..382aa4d25a1b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -29,7 +29,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { type Assign >: Null <: Tree type Ident >: Null <: Tree type If >: Null <: Tree - type LabelDef >: Null <: Tree type ValDef >: Null <: Tree type Throw >: Null <: Tree type Labeled >: Null <: Tree @@ -66,7 +65,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { implicit val AssignTag: ClassTag[Assign] implicit val IdentTag: ClassTag[Ident] implicit val IfTag: ClassTag[If] - implicit val LabelDefTag: ClassTag[LabelDef] implicit val ValDefTag: ClassTag[ValDef] implicit val ThrowTag: ClassTag[Throw] implicit val LabeledTag: ClassTag[Labeled] @@ -126,15 +124,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { /* dotty specific, see dotty.runtime.Arrays */ def isSyntheticArrayConstructor(s: Symbol) = false - /* - * Collects all LabelDef nodes enclosed (directly or not) by each node. - * - * In other words, this prepares a map giving - * all labelDefs (the entry-value) having a Tree node (the entry-key) as ancestor. - * The entry-value for a LabelDef entry-key always contains the entry-key. - */ - def getLabelDefOwners(t: Tree): Map[Tree, List[LabelDef]] - /* * Implementation of those methods is very specific to how annotations are represented * representations for Dotc and Scalac are to different to abstract over them @@ -162,7 +151,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { def targetPlatform: String def sourceFileFor(cu: CompilationUnit): String def informProgress(msg: String): Unit - def hasLabelDefs: Boolean // whether this compiler uses LabelDefs (i.e., scalac) /* backend actually uses free names to generate stuff. This should NOT mangled */ def newTermName(prefix: String): Name @@ -207,7 +195,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { val Labeled: LabeledDeconstructor val Return: ReturnDeconstructor val WhileDo: WhileDoDeconstructor - val LabelDef: LabelDeconstructor val Literal: LiteralDeconstructor val Typed: TypedDeconstrutor val Super: SuperDeconstructor @@ -385,12 +372,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { def _3: Tree } - abstract class LabelDeconstructor extends DeconstructorCommon[LabelDef]{ - def _1: Name - def _2: List[Symbol] - def _3: Tree - } - abstract class TypedDeconstrutor extends DeconstructorCommon[Typed]{ def _1: Tree def _2: Tree diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 895daa2a8980..4a2a8b996fd1 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -74,7 +74,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma type ArrayValue = tpd.JavaSeqLiteral type ApplyDynamic = Null type ModuleDef = Null - type LabelDef = Null type Closure = tpd.Closure val NoSymbol: Symbol = Symbols.NoSymbol @@ -186,7 +185,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma implicit val AssignTag: ClassTag[Assign] = ClassTag[Assign](classOf[Assign]) implicit val IdentTag: ClassTag[Ident] = ClassTag[Ident](classOf[Ident]) implicit val IfTag: ClassTag[If] = ClassTag[If](classOf[If]) - implicit val LabelDefTag: ClassTag[LabelDef] = ClassTag[LabelDef](classOf[LabelDef]) implicit val ValDefTag: ClassTag[ValDef] = ClassTag[ValDef](classOf[ValDef]) implicit val ThrowTag: ClassTag[Throw] = ClassTag[Throw](classOf[Throw]) implicit val LabeledTag: ClassTag[Labeled] = ClassTag[Labeled](classOf[Labeled]) @@ -398,8 +396,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def emitAsmp: Option[String] = None - def hasLabelDefs: Boolean = false - def dumpClasses: Option[String] = if (ctx.settings.Ydumpclasses.isDefault) None else Some(ctx.settings.Ydumpclasses.value) @@ -446,8 +442,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma if (found == null) None else Some(found) } - def getLabelDefOwners(tree: Tree): Map[Tree, List[LabelDef]] = Map.empty - // todo: remove def isMaybeBoxed(sym: Symbol): Boolean = { (sym == ObjectClass) || @@ -1110,12 +1104,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _3: Tree = field.finalizer } - object LabelDef extends LabelDeconstructor { - def _1: Name = ??? - def _2: List[Symbol] = ??? - def _3: Tree = ??? - } - object Typed extends TypedDeconstrutor { def _1: Tree = field.expr def _2: Tree = field.tpt From bc1225b1eed202b154fb955a91c5b98285449148 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 2 Jun 2020 20:03:58 +0200 Subject: [PATCH 02/98] Remove Modifiers from BackendInterface --- .../src/dotty/tools/backend/jvm/BackendInterface.scala | 9 ++++----- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index 382aa4d25a1b..4cced483a738 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -19,7 +19,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { type Type >: Null <: AnyRef type Annotation >: Null <: AnyRef type Tree >: Null <: AnyRef - type Modifiers >: Null <: AnyRef type TypeDef >: Null <: Tree type Apply >: Null <: Tree type Select >: Null <: Tree @@ -236,7 +235,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { } abstract class ClassDefDeconstructor extends DeconstructorCommon[ClassDef] { - def _1: Modifiers + def _1: Null def _2: Name def _3: List[TypeDef] def _4: Template @@ -254,13 +253,13 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { } abstract class ModuleDefDeconstructor extends DeconstructorCommon[ModuleDef]{ - def _1: Modifiers + def _1: Null def _2: Name def _3: Tree } abstract class DefDefDeconstructor extends DeconstructorCommon[DefDef]{ - def _1: Modifiers + def _1: Null def _2: Name def _3: List[TypeDef] def _4: List[List[ValDef]] @@ -353,7 +352,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { } abstract class ValDefDeconstructor extends DeconstructorCommon[ValDef]{ - def _1: Modifiers + def _1: Null def _2: Name def _3: Tree def _4: Tree diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 4a2a8b996fd1..42d679dff807 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -69,7 +69,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma type Bind = tpd.Bind type New = tpd.New type Super = tpd.Super - type Modifiers = Null type Annotation = Annotations.Annotation type ArrayValue = tpd.JavaSeqLiteral type ApplyDynamic = Null @@ -1030,7 +1029,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } object ValDef extends ValDefDeconstructor { - def _1: Modifiers = null + def _1: Null = null def _2: Name = field.name def _3: Tree = field.tpt def _4: Tree = field.rhs @@ -1140,7 +1139,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } object DefDef extends DefDefDeconstructor { - def _1: Modifiers = null + def _1: Null = null def _2: Name = field.name def _3: List[TypeDef] = field.tparams def _4: List[List[ValDef]] = field.vparamss @@ -1149,7 +1148,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } object ModuleDef extends ModuleDefDeconstructor { - def _1: Modifiers = ??? + def _1: Null = ??? def _2: Name = ??? def _3: Tree = ??? } @@ -1168,7 +1167,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } object ClassDef extends ClassDefDeconstructor { - def _1: Modifiers = null + def _1: Null = null def _2: Name = field.name def _4: Template = field.rhs.asInstanceOf[Template] def _3: List[TypeDef] = Nil From 2368884e2477df8185d5a86de649706538e09d47 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 2 Jun 2020 20:07:02 +0200 Subject: [PATCH 03/98] Remove ModuleDef from BackendInterface --- .../src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 2 -- .../src/dotty/tools/backend/jvm/BackendInterface.scala | 9 --------- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 8 -------- 3 files changed, 19 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 3d704a8bd14d..2001ded186e3 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -466,8 +466,6 @@ trait BCodeSkelBuilder extends BCodeHelpers { tree match { case EmptyTree => () - case ModuleDef(_, _, _) => abort(s"Modules should have been eliminated by refchecks: $tree") - case ValDef(mods, name, tpt, rhs) => () // fields are added in `genPlainClass()`, via `addClassFields()` case dd @ DefDef(_, _, _, _, _, _) => genDefDef(dd.asInstanceOf[DefDef]) diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index 4cced483a738..c8c41d5b4852 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -42,7 +42,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { type CaseDef >: Null <: Tree type Alternative >: Null <: Tree type DefDef >: Null <: Tree - type ModuleDef >: Null <: Tree type Template >: Null <: Tree type Name >: Null <: AnyRef type Position @@ -78,7 +77,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { implicit val ThisTag: ClassTag[This] implicit val AlternativeTag: ClassTag[Alternative] implicit val DefDefTag: ClassTag[DefDef] - implicit val ModuleDefTag: ClassTag[ModuleDef] implicit val NameTag: ClassTag[Name] implicit val TemplateTag: ClassTag[Template] implicit val BindTag: ClassTag[Bind] @@ -206,7 +204,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { val Constant: ConstantDeconstructor val ThrownException: ThrownException val DefDef: DefDefDeconstructor - val ModuleDef: ModuleDefDeconstructor val Template: TemplateDeconstructor val Bind: BindDeconstructor val ClassDef: ClassDefDeconstructor @@ -252,12 +249,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { def _3: List[Tree] } - abstract class ModuleDefDeconstructor extends DeconstructorCommon[ModuleDef]{ - def _1: Null - def _2: Name - def _3: Tree - } - abstract class DefDefDeconstructor extends DeconstructorCommon[DefDef]{ def _1: Null def _2: Name diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 42d679dff807..50996958a5d0 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -72,7 +72,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma type Annotation = Annotations.Annotation type ArrayValue = tpd.JavaSeqLiteral type ApplyDynamic = Null - type ModuleDef = Null type Closure = tpd.Closure val NoSymbol: Symbol = Symbols.NoSymbol @@ -198,7 +197,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma implicit val ThisTag: ClassTag[This] = ClassTag[This](classOf[This]) implicit val AlternativeTag: ClassTag[Alternative] = ClassTag[Alternative](classOf[Alternative]) implicit val DefDefTag: ClassTag[DefDef] = ClassTag[DefDef](classOf[DefDef]) - implicit val ModuleDefTag: ClassTag[ModuleDef] = ClassTag[ModuleDef](classOf[ModuleDef]) implicit val NameTag: ClassTag[Name] = ClassTag[Name](classOf[Name]) implicit val TemplateTag: ClassTag[Template] = ClassTag[Template](classOf[Template]) implicit val BindTag: ClassTag[Bind] = ClassTag[Bind](classOf[Bind]) @@ -1147,12 +1145,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _6: Tree = field.rhs } - object ModuleDef extends ModuleDefDeconstructor { - def _1: Null = ??? - def _2: Name = ??? - def _3: Tree = ??? - } - object Template extends TemplateDeconstructor { def _1: List[Tree] = field.parents def _2: ValDef = field.self From be3f4c39f4eeac2cf63c5a1fa1a92e4facf2a5bf Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 2 Jun 2020 20:09:12 +0200 Subject: [PATCH 04/98] Remove ApplyDynamic from BackendInterface --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 -- .../src/dotty/tools/backend/jvm/BackendInterface.scala | 9 --------- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 7 ------- 3 files changed, 18 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index fdfa00f85159..732156da93cf 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -323,8 +323,6 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case app @ Apply(_, _) => generatedType = genApply(app, expectedType) - case ApplyDynamic(qual, args) => sys.error("No invokedynamic support yet.") - case This(qual) => val symIsModuleClass = tree.symbol.isModuleClass assert(tree.symbol == claszSymbol || symIsModuleClass, diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index c8c41d5b4852..e73d8fd9aa5e 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -48,7 +48,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { type CompilationUnit <: AnyRef type Bind >: Null <: Tree type New >: Null <: Tree - type ApplyDynamic >: Null <: Tree type Super >: Null <: Tree type Closure >: Null <: Tree @@ -81,7 +80,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { implicit val TemplateTag: ClassTag[Template] implicit val BindTag: ClassTag[Bind] implicit val NewTag: ClassTag[New] - implicit val ApplyDynamicTag: ClassTag[ApplyDynamic] implicit val SuperTag: ClassTag[Super] implicit val ConstantClassTag: ClassTag[Constant] implicit val ClosureTag: ClassTag[Closure] @@ -185,7 +183,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { val ValDef: ValDefDeconstructor val Throw: ThrowDeconstructor val New: NewDeconstructor - val ApplyDynamic: ApplyDynamicDeconstructor val This: ThisDeconstructor val Ident: IdentDeconstructor val Try: TryDeconstructor @@ -350,12 +347,6 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { } - abstract class ApplyDynamicDeconstructor extends DeconstructorCommon[ApplyDynamic]{ - def _1: Tree - def _2: List[Tree] - } - - abstract class TryDeconstructor extends DeconstructorCommon[Try]{ def _1: Tree def _2: List[Tree] diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 50996958a5d0..f2eceebf923b 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -71,7 +71,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma type Super = tpd.Super type Annotation = Annotations.Annotation type ArrayValue = tpd.JavaSeqLiteral - type ApplyDynamic = Null type Closure = tpd.Closure val NoSymbol: Symbol = Symbols.NoSymbol @@ -201,7 +200,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma implicit val TemplateTag: ClassTag[Template] = ClassTag[Template](classOf[Template]) implicit val BindTag: ClassTag[Bind] = ClassTag[Bind](classOf[Bind]) implicit val NewTag: ClassTag[New] = ClassTag[New](classOf[New]) - implicit val ApplyDynamicTag: ClassTag[ApplyDynamic] = ClassTag[ApplyDynamic](classOf[ApplyDynamic]) implicit val SuperTag: ClassTag[Super] = ClassTag[Super](classOf[Super]) implicit val ConstantClassTag: ClassTag[Constant] = ClassTag[Constant](classOf[Constant]) implicit val ClosureTag: ClassTag[Closure] = ClassTag[Closure](classOf[Closure]) @@ -1033,11 +1031,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _4: Tree = field.rhs } - object ApplyDynamic extends ApplyDynamicDeconstructor { - def _1: Tree = ??? - def _2: List[Tree] = ??? - } - // todo: this product1s should also eventually become name-based pattn matching object Literal extends LiteralDeconstructor { def get: Constant = field.const From 615d670ec770a1d9806bfe53d87acfa4f3568830 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 2 Jun 2020 23:13:43 +0200 Subject: [PATCH 05/98] Remove implicit conversions from BackendInterface --- .../tools/backend/jvm/BCodeAsmCommon.scala | 30 +-- .../tools/backend/jvm/BCodeBodyBuilder.scala | 252 +++++++++--------- .../tools/backend/jvm/BCodeHelpers.scala | 62 ++--- .../tools/backend/jvm/BCodeSkelBuilder.scala | 98 +++---- .../tools/backend/jvm/BCodeSyncAndTry.scala | 12 +- .../tools/backend/jvm/BTypesFromSymbols.scala | 76 +++--- .../tools/backend/jvm/BackendInterface.scala | 22 +- .../tools/backend/jvm/BytecodeWriters.scala | 2 +- .../backend/jvm/DottyBackendInterface.scala | 2 +- 9 files changed, 278 insertions(+), 278 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index bdf74558a760..3a9e00522532 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -16,13 +16,13 @@ final class BCodeAsmCommon[I <: BackendInterface](val interface: I) { * null. */ def isAnonymousOrLocalClass(classSym: Symbol): Boolean = { - assert(classSym.isClass, s"not a class: $classSym") + assert(symHelper(classSym).isClass, s"not a class: $classSym") // Here used to be an `assert(!classSym.isDelambdafyFunction)`: delambdafy lambda classes are // always top-level. However, SI-8900 shows an example where the weak name-based implementation // of isDelambdafyFunction failed (for a function declared in a package named "lambda"). - classSym.isAnonymousClass || { - val originalOwnerLexicallyEnclosingClass = classSym.originalOwner.originalLexicallyEnclosingClass - originalOwnerLexicallyEnclosingClass != NoSymbol && !originalOwnerLexicallyEnclosingClass.isClass + symHelper(classSym).isAnonymousClass || { + val originalOwnerLexicallyEnclosingClass = symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass + originalOwnerLexicallyEnclosingClass != NoSymbol && !symHelper(originalOwnerLexicallyEnclosingClass).isClass } } @@ -50,13 +50,13 @@ final class BCodeAsmCommon[I <: BackendInterface](val interface: I) { * This is a source-level property, so we need to use the originalOwner chain to reconstruct it. */ private def enclosingMethodForEnclosingMethodAttribute(classSym: Symbol): Option[Symbol] = { - assert(classSym.isClass, classSym) + assert(symHelper(classSym).isClass, classSym) def enclosingMethod(sym: Symbol): Option[Symbol] = { - if (sym.isClass || sym == NoSymbol) None - else if (sym.isMethod) Some(sym) - else enclosingMethod(sym.originalOwner.originalLexicallyEnclosingClass) + if (symHelper(sym).isClass || sym == NoSymbol) None + else if (symHelper(sym).isMethod) Some(sym) + else enclosingMethod(symHelper(symHelper(sym).originalOwner).originalLexicallyEnclosingClass) } - enclosingMethod(classSym.originalOwner.originalLexicallyEnclosingClass) + enclosingMethod(symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass) } /** @@ -64,12 +64,12 @@ final class BCodeAsmCommon[I <: BackendInterface](val interface: I) { * property, this method looks at the originalOwner chain. See doc in BTypes. */ private def enclosingClassForEnclosingMethodAttribute(classSym: Symbol): Symbol = { - assert(classSym.isClass, classSym) + assert(symHelper(classSym).isClass, classSym) def enclosingClass(sym: Symbol): Symbol = { - if (sym.isClass) sym - else enclosingClass(sym.originalOwner.originalLexicallyEnclosingClass) + if (symHelper(sym).isClass) sym + else enclosingClass(symHelper(symHelper(sym).originalOwner).originalLexicallyEnclosingClass) } - enclosingClass(classSym.originalOwner.originalLexicallyEnclosingClass) + enclosingClass(symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass) } /*final*/ case class EnclosingMethodEntry(owner: String, name: String, methodDescriptor: String) @@ -85,10 +85,10 @@ final class BCodeAsmCommon[I <: BackendInterface](val interface: I) { def enclosingMethodAttribute(classSym: Symbol, classDesc: Symbol => String, methodDesc: Symbol => String): Option[EnclosingMethodEntry] = { if (isAnonymousOrLocalClass(classSym)) { val methodOpt = enclosingMethodForEnclosingMethodAttribute(classSym) - debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(_.enclClass)})") + debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(symHelper(_).enclClass)})") Some(EnclosingMethodEntry( classDesc(enclosingClassForEnclosingMethodAttribute(classSym)), - methodOpt.map(_.javaSimpleName.toString).orNull, + methodOpt.map(symHelper(_).javaSimpleName.toString).orNull, methodOpt.map(methodDesc).orNull)) } else { None diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 732156da93cf..d5d79331df52 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -58,16 +58,16 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { tree match { case Assign(lhs @ Select(qual, _), rhs) => - val isStatic = lhs.symbol.isStaticMember + val isStatic = symHelper(treeHelper(lhs).symbol).isStaticMember if (!isStatic) { genLoadQualifier(lhs) } - genLoad(rhs, symInfoTK(lhs.symbol)) + genLoad(rhs, symInfoTK(treeHelper(lhs).symbol)) lineNumber(tree) // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError - val receiverClass = qual.tpe.typeSymbol - fieldStore(lhs.symbol, receiverClass) + val receiverClass = typeHelper(treeHelper(qual).tpe).typeSymbol + fieldStore(treeHelper(lhs).symbol, receiverClass) case Assign(lhs, rhs) => - val s = lhs.symbol + val s = treeHelper(lhs).symbol val Local(tk, _, idx, _) = locals.getOrMakeLocal(s) genLoad(rhs, tk) lineNumber(tree) @@ -96,7 +96,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var resKind = tpeTK(larg) assert(resKind.isNumericType || (resKind == BOOL), - s"$resKind is not a numeric or boolean type [operation: ${fun.symbol}]") + s"$resKind is not a numeric or boolean type [operation: ${treeHelper(fun).symbol}]") import ScalaPrimitivesOps._ @@ -108,7 +108,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case POS => () // nothing case NEG => bc.neg(resKind) case NOT => bc.genPrimitiveArithmetic(Primitives.NOT, resKind) - case _ => abort(s"Unknown unary operation: ${fun.symbol.showFullName} code: $code") + case _ => abort(s"Unknown unary operation: ${symHelper(treeHelper(fun).symbol).showFullName} code: $code") } // binary operation @@ -135,7 +135,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case LSL | LSR | ASR => bc.genPrimitiveShift(code, resKind) - case _ => abort(s"Unknown primitive: ${fun.symbol}[$code]") + case _ => abort(s"Unknown primitive: ${treeHelper(fun).symbol}[$code]") } case _ => @@ -184,8 +184,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val success = new asm.Label val failure = new asm.Label - val hasElse = !elsep.isEmpty && (elsep match { - case Literal(value) if value.tag == UnitTag => false + val hasElse = !treeHelper(elsep).isEmpty && (elsep match { + case Literal(value) if constantHelper(value).tag == UnitTag => false case _ => true }) val postIf = if (hasElse) new asm.Label else failure @@ -211,9 +211,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genPrimitiveOp(tree: Apply, expectedType: BType): BType = tree match { case Apply(fun @ Select(receiver, _), _) => - val sym = tree.symbol + val sym = treeHelper(tree).symbol - val code = primitives.getPrimitive(tree, receiver.tpe) + val code = primitives.getPrimitive(tree, treeHelper(receiver).tpe) import ScalaPrimitivesOps._ @@ -243,7 +243,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { coercionTo(code) } else abort( - s"Primitive operation not handled yet: ${sym.showFullName}(${fun.symbol.name}) at: ${tree.pos}" + s"Primitive operation not handled yet: ${symHelper(sym).showFullName}(${symHelper(treeHelper(fun).symbol).name}) at: ${treeHelper(tree).pos}" ) } @@ -262,7 +262,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { debuglog("skipping trivial assign to _$this: " + tree) case ValDef(_, _, _, rhs) => - val sym = tree.symbol + val sym = treeHelper(tree).symbol /* most of the time, !locals.contains(sym), unless the current activation of genLoad() is being called while duplicating a finalizer that contains this ValDef. */ val loc = locals.getOrMakeLocal(sym) @@ -296,7 +296,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType = genThrow(expr) case New(tpt) => - abort(s"Unexpected New(${tpt.summaryString}/$tpt) reached GenBCode.\n" + + abort(s"Unexpected New(${typeHelper(tpt).summaryString}/$tpt) reached GenBCode.\n" + " Call was genLoad" + ((tree, expectedType))) case app @ Closure(env, call, functionalInterface) => @@ -306,7 +306,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t @ Ident(_) => (t, Nil) } - if (!fun.symbol.isStaticMember) { + if (!symHelper(treeHelper(fun).symbol).isStaticMember) { // load receiver of non-static implementation of lambda // darkdimius: I haven't found in spec `this` reference should go @@ -317,43 +317,43 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(prefix) } - genLoadArguments(env, fun.symbol.info.paramTypes map toTypeKind) - generatedType = genInvokeDynamicLambda(NoSymbol, fun.symbol, env.size, functionalInterface) + genLoadArguments(env, typeHelper(symHelper(treeHelper(fun).symbol).info).paramTypes map toTypeKind) + generatedType = genInvokeDynamicLambda(NoSymbol, treeHelper(fun).symbol, env.size, functionalInterface) case app @ Apply(_, _) => generatedType = genApply(app, expectedType) case This(qual) => - val symIsModuleClass = tree.symbol.isModuleClass - assert(tree.symbol == claszSymbol || symIsModuleClass, - s"Trying to access the this of another class: tree.symbol = ${tree.symbol}, class symbol = $claszSymbol compilation unit: $cunit") - if (symIsModuleClass && tree.symbol != claszSymbol) { + val symIsModuleClass = symHelper(treeHelper(tree).symbol).isModuleClass + assert(treeHelper(tree).symbol == claszSymbol || symIsModuleClass, + s"Trying to access the this of another class: tree.symbol = ${treeHelper(tree).symbol}, class symbol = $claszSymbol compilation unit: $cunit") + if (symIsModuleClass && treeHelper(tree).symbol != claszSymbol) { generatedType = genLoadModule(tree) } else { mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) generatedType = - if (tree.symbol == ArrayClass) ObjectReference + if (treeHelper(tree).symbol == ArrayClass) ObjectReference else classBTypeFromSymbol(claszSymbol) } case Select(Ident(`nme_EMPTY_PACKAGE_NAME`), module) => - assert(tree.symbol.isModule, s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.pos}") + assert(symHelper(treeHelper(tree).symbol).isModule, s"Selection of non-module from empty package: $tree sym: ${treeHelper(tree).symbol} at: ${treeHelper(tree).pos}") genLoadModule(tree) case Select(qualifier, _) => - val sym = tree.symbol + val sym = treeHelper(tree).symbol generatedType = symInfoTK(sym) val qualSafeToElide = isQualifierSafeToElide(qualifier) def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } } // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError - def receiverClass = qualifier.tpe.typeSymbol - if (sym.isModule) { + def receiverClass = typeHelper(treeHelper(qualifier).tpe).typeSymbol + if (symHelper(sym).isModule) { genLoadQualUnlessElidable() genLoadModule(tree) - } else if (sym.isStaticMember) { + } else if (symHelper(sym).isStaticMember) { genLoadQualUnlessElidable() fieldLoad(sym, receiverClass) } else { @@ -362,15 +362,15 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } case t @ Ident(name) => - val sym = tree.symbol + val sym = treeHelper(tree).symbol val tk = symInfoTK(sym) generatedType = tk val desugared = desugarIdent(t) desugared match { case None => - if (!sym.hasPackageFlag) { - if (sym.isModule) genLoadModule(sym) + if (!symHelper(sym).hasPackageFlag) { + if (symHelper(sym).isModule) genLoadModule(sym) else locals.load(sym) } case Some(t) => @@ -378,9 +378,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } case Literal(value) => - if (value.tag != UnitTag) (value.tag, expectedType) match { - case (IntTag, LONG ) => bc.lconst(value.longValue); generatedType = LONG - case (FloatTag, DOUBLE) => bc.dconst(value.doubleValue); generatedType = DOUBLE + if (constantHelper(value).tag != UnitTag) (constantHelper(value).tag, expectedType) match { + case (IntTag, LONG ) => bc.lconst(constantHelper(value).longValue); generatedType = LONG + case (FloatTag, DOUBLE) => bc.dconst(constantHelper(value).doubleValue); generatedType = DOUBLE case (NullTag, _ ) => bc.emit(asm.Opcodes.ACONST_NULL); generatedType = RT_NULL case _ => genConstant(value); generatedType = tpeTK(tree) } @@ -410,7 +410,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t: TypeApply => // dotty specific generatedType = genTypeApply(t) - case _ => abort(s"Unexpected tree in genLoad: $tree/${tree.getClass} at: ${tree.pos}") + case _ => abort(s"Unexpected tree in genLoad: $tree/${tree.getClass} at: ${treeHelper(tree).pos}") } // emit conversion @@ -436,12 +436,12 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * must-single-thread */ private def fieldOp(field: Symbol, isLoad: Boolean, specificReceiver: Symbol): Unit = { - val useSpecificReceiver = specificReceiver != null && !field.isScalaStatic + val useSpecificReceiver = specificReceiver != null && !symHelper(field).isScalaStatic - val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner) - val fieldJName = field.javaSimpleName.toString + val owner = internalName(if (useSpecificReceiver) specificReceiver else symHelper(field).owner) + val fieldJName = symHelper(field).javaSimpleName.toString val fieldDescr = symInfoTK(field).descriptor - val isStatic = field.isStaticMember + val isStatic = symHelper(field).isStaticMember val opc = if (isLoad) { if (isStatic) asm.Opcodes.GETSTATIC else asm.Opcodes.GETFIELD } else { if (isStatic) asm.Opcodes.PUTSTATIC else asm.Opcodes.PUTFIELD } @@ -457,38 +457,38 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * Otherwise it's safe to call from multiple threads. */ def genConstant(const: Constant): Unit = { - (const.tag/*: @switch*/) match { + (constantHelper(const).tag/*: @switch*/) match { - case BooleanTag => bc.boolconst(const.booleanValue) + case BooleanTag => bc.boolconst(constantHelper(const).booleanValue) - case ByteTag => bc.iconst(const.byteValue) - case ShortTag => bc.iconst(const.shortValue) - case CharTag => bc.iconst(const.charValue) - case IntTag => bc.iconst(const.intValue) + case ByteTag => bc.iconst(constantHelper(const).byteValue) + case ShortTag => bc.iconst(constantHelper(const).shortValue) + case CharTag => bc.iconst(constantHelper(const).charValue) + case IntTag => bc.iconst(constantHelper(const).intValue) - case LongTag => bc.lconst(const.longValue) - case FloatTag => bc.fconst(const.floatValue) - case DoubleTag => bc.dconst(const.doubleValue) + case LongTag => bc.lconst(constantHelper(const).longValue) + case FloatTag => bc.fconst(constantHelper(const).floatValue) + case DoubleTag => bc.dconst(constantHelper(const).doubleValue) case UnitTag => () case StringTag => - assert(const.value != null, const) // TODO this invariant isn't documented in `case class Constant` - mnode.visitLdcInsn(const.stringValue) // `stringValue` special-cases null, but not for a const with StringTag + assert(constantHelper(const).value != null, const) // TODO this invariant isn't documented in `case class Constant` + mnode.visitLdcInsn(constantHelper(const).stringValue) // `stringValue` special-cases null, but not for a const with StringTag case NullTag => emit(asm.Opcodes.ACONST_NULL) case ClazzTag => - val tp = toTypeKind(const.typeValue) + val tp = toTypeKind(constantHelper(const).typeValue) // classOf[Int] is transformed to Integer.TYPE by ClassOf assert(!tp.isPrimitive, s"expected class type in classOf[T], found primitive type $tp") mnode.visitLdcInsn(tp.toASMType) case EnumTag => - val sym = const.symbolValue - val ownerName = internalName(sym.owner) - val fieldName = sym.javaSimpleName.toString - val fieldDesc = toTypeKind(sym.tpe.underlying).descriptor + val sym = constantHelper(const).symbolValue + val ownerName = internalName(symHelper(sym).owner) + val fieldName = symHelper(sym).javaSimpleName.toString + val fieldDesc = toTypeKind(typeHelper(symHelper(sym).tpe).underlying).descriptor mnode.visitFieldInsn( asm.Opcodes.GETSTATIC, ownerName, @@ -505,7 +505,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val resKind = tpeTK(tree) genLoad(expr, resKind) - markProgramPoint(programPoint(bind.symbol)) + markProgramPoint(programPoint(treeHelper(bind).symbol)) resKind } @@ -528,7 +528,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (saveReturnValue) { // regarding return value, the protocol is: in place of a `return-stmt`, a sequence of `adapt, store, jump` are inserted. if (earlyReturnVar == null) { - earlyReturnVar = locals.makeLocal(returnType, "earlyReturnVar", expr.tpe, expr.pos) + earlyReturnVar = locals.makeLocal(returnType, "earlyReturnVar", treeHelper(expr).tpe, treeHelper(expr).pos) } locals.store(earlyReturnVar) } @@ -537,14 +537,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } } else { // return from labeled - assert(fromSym.isLabel, fromSym) - assert(!fromSym.isMethod, fromSym) + assert(symHelper(fromSym).isLabel, fromSym) + assert(!symHelper(fromSym).isMethod, fromSym) /* TODO At the moment, we disregard cleanups, because by construction we don't have return-from-labels * that cross cleanup boundaries. However, in theory such crossings are valid, so we should take care * of them. */ - val resultKind = toTypeKind(fromSym.info) + val resultKind = toTypeKind(symHelper(fromSym).info) genLoad(expr, resultKind) lineNumber(r) bc goTo programPoint(fromSym) @@ -565,7 +565,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { RT_NOTHING } else { val hasBody = cond match { - case Literal(value) if value.tag == UnitTag => false + case Literal(value) if constantHelper(value).tag == UnitTag => false case _ => true } @@ -591,11 +591,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genTypeApply(t: TypeApply): BType = t match { case TypeApply(fun@Select(obj, _), targs) => - val sym = fun.symbol + val sym = treeHelper(fun).symbol val cast = sym match { case Object_isInstanceOf => false case Object_asInstanceOf => true - case _ => abort(s"Unexpected type application $fun[sym: ${sym.showFullName}] in: $t") + case _ => abort(s"Unexpected type application $fun[sym: ${symHelper(sym).showFullName}] in: $t") } val l = tpeTK(obj) @@ -635,7 +635,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var elemKind = arr.elementType val argsSize = args.length if (argsSize > dims) { - error(app.pos, s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)") + error(treeHelper(app).pos, s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)") } if (argsSize < dims) { /* In one step: @@ -658,14 +658,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var generatedType = expectedType lineNumber(app) app match { - case Apply(_, args) if isSyntheticArrayConstructor(app.symbol) => + case Apply(_, args) if isSyntheticArrayConstructor(treeHelper(app).symbol) => val List(elemClaz, Literal(c: Constant), ArrayValue(_, dims)) = args - generatedType = toTypeKind(c.typeValue) + generatedType = toTypeKind(constantHelper(c).typeValue) mkArrayConstructorCall(generatedType.asArrayBType, app, dims) case Apply(t :TypeApply, _) => generatedType = - if (t.symbol ne Object_synchronized) genTypeApply(t) + if (treeHelper(t).symbol ne Object_synchronized) genTypeApply(t) else genSynchronized(app, expectedType) case Apply(fun @ Select(Super(_, _), _), args) => @@ -673,8 +673,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && jMethodName == INSTANCE_CONSTRUCTOR_NAME && - fun.symbol.javaSimpleName.toString == INSTANCE_CONSTRUCTOR_NAME && - claszSymbol.isStaticModuleClass) { + symHelper(treeHelper(fun).symbol).javaSimpleName.toString == INSTANCE_CONSTRUCTOR_NAME && + symHelper(claszSymbol).isStaticModuleClass) { isModuleInitialized = true mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) mnode.visitFieldInsn( @@ -693,7 +693,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // on the stack (contrary to what the type in the AST says). mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) genLoadArguments(args, paramTKs(app)) - generatedType = genCallMethod(fun.symbol, InvokeStyle.Super, app.pos) + generatedType = genCallMethod(treeHelper(fun).symbol, InvokeStyle.Super, treeHelper(app).pos) initModule() // 'new' constructor call: Note: since constructors are @@ -701,8 +701,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // we have to 'simulate' it by DUPlicating the freshly created // instance (on JVM, methods return VOID). case Apply(fun @ Select(New(tpt), `nme_CONSTRUCTOR`), args) => - val ctor = fun.symbol - assert(ctor.isClassConstructor, s"'new' call to non-constructor: ${ctor.name}") + val ctor = treeHelper(fun).symbol + assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${symHelper(ctor).name}") generatedType = toTypeKind(tpt) assert(generatedType.isRef, s"Non reference type cannot be instantiated: $generatedType") @@ -712,39 +712,39 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { mkArrayConstructorCall(arr, app, args) case rt: ClassBType => - assert(classBTypeFromSymbol(ctor.owner) == rt, s"Symbol ${ctor.owner.showFullName} is different from $rt") + assert(classBTypeFromSymbol(symHelper(ctor).owner) == rt, s"Symbol ${symHelper(symHelper(ctor).owner).showFullName} is different from $rt") mnode.visitTypeInsn(asm.Opcodes.NEW, rt.internalName) bc dup generatedType genLoadArguments(args, paramTKs(app)) - genCallMethod(ctor, InvokeStyle.Special, app.pos) + genCallMethod(ctor, InvokeStyle.Special, treeHelper(app).pos) case _ => abort(s"Cannot instantiate $tpt of kind: $generatedType") } - case Apply(fun, List(expr)) if isBox(fun.symbol) => + case Apply(fun, List(expr)) if isBox(treeHelper(fun).symbol) => val nativeKind = tpeTK(expr) genLoad(expr, nativeKind) val MethodNameAndType(mname, methodType) = asmBoxTo(nativeKind) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) - generatedType = boxResultType(fun.symbol) // was toTypeKind(fun.symbol.tpe.resultType) + generatedType = boxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.tpe.resultType) - case Apply(fun, List(expr)) if isUnbox(fun.symbol) => + case Apply(fun, List(expr)) if isUnbox(treeHelper(fun).symbol) => genLoad(expr) - val boxType = unboxResultType(fun.symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) + val boxType = unboxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) generatedType = boxType val MethodNameAndType(mname, methodType) = asmUnboxTo(boxType) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) case app @ Apply(fun, args) => - val sym = fun.symbol + val sym = treeHelper(fun).symbol if (isPrimitive(fun)) { // primitive method call generatedType = genPrimitiveOp(app, expectedType) } else { // normal method call val invokeStyle = - if (sym.isStaticMember) InvokeStyle.Static - else if (sym.isPrivate || sym.isClassConstructor) InvokeStyle.Special + if (symHelper(sym).isStaticMember) InvokeStyle.Static + else if (symHelper(sym).isPrivate || symHelper(sym).isClassConstructor) InvokeStyle.Special else InvokeStyle.Virtual if (invokeStyle.hasInstance) genLoadQualifier(fun) @@ -767,23 +767,23 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // Emitting `def f(c: C) = c.clone()` as `Object.clone()` gives a VerifyError. val target: String = tpeTK(qual).asRefBType.classOrArrayType val methodBType = asmMethodType(sym) - bc.invokevirtual(target, sym.javaSimpleName.toString, methodBType.descriptor) + bc.invokevirtual(target, symHelper(sym).javaSimpleName.toString, methodBType.descriptor) generatedType = methodBType.returnType } else { val receiverClass = if (!invokeStyle.isVirtual) null else { // receiverClass is used in the bytecode to as the method receiver. using sym.owner // may lead to IllegalAccessErrors, see 9954eaf / aladdin bug 455. - val qualSym = qual.tpe.typeSymbol + val qualSym = typeHelper(treeHelper(qual).tpe).typeSymbol if (qualSym == ArrayClass) { // For invocations like `Array(1).hashCode` or `.wait()`, use Object as receiver // in the bytecode. Using the array descriptor (like we do for clone above) seems // to work as well, but it seems safer not to change this. Javac also uses Object. // Note that array apply/update/length are handled by isPrimitive (above). - assert(sym.owner == ObjectClass, s"unexpected array call: $app") + assert(symHelper(sym).owner == ObjectClass, s"unexpected array call: $app") ObjectClass } else qualSym } - generatedType = genCallMethod(sym, invokeStyle, app.pos, receiverClass) + generatedType = genCallMethod(sym, invokeStyle, treeHelper(app).pos, receiverClass) } } } @@ -848,21 +848,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { switchBlocks ::= (switchBlockPoint, body) pat match { case Literal(value) => - flatKeys ::= value.intValue + flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint case Ident(`nme_WILDCARD`) => - assert(default == null, s"multiple default targets in a Match node, at ${tree.pos}") + assert(default == null, s"multiple default targets in a Match node, at ${treeHelper(tree).pos}") default = switchBlockPoint case Alternative(alts) => alts foreach { case Literal(value) => - flatKeys ::= value.intValue + flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint case _ => - abort(s"Invalid alternative in alternative pattern in Match node: $tree at: ${tree.pos}") + abort(s"Invalid alternative in alternative pattern in Match node: $tree at: ${treeHelper(tree).pos}") } case _ => - abort(s"Invalid pattern in Match node: $tree at: ${tree.pos}") + abort(s"Invalid pattern in Match node: $tree at: ${treeHelper(tree).pos}") } } @@ -983,7 +983,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { desugarIdent(t) match { case Some(sel) => genLoadQualifier(sel) case None => - assert(t.symbol.owner == this.claszSymbol) + assert(symHelper(treeHelper(t).symbol).owner == this.claszSymbol) } case _ => abort(s"Unknown qualifier $tree") } @@ -995,8 +995,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(tree: Tree): BType = { val module = ( - if (!tree.symbol.isPackageClass) tree.symbol - else tree.symbol.info.member(nme_PACKAGE) match { + if (!symHelper(treeHelper(tree).symbol).isPackageClass) treeHelper(tree).symbol + else typeHelper(symHelper(treeHelper(tree).symbol).info).member(nme_PACKAGE) match { case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree") case s => abort(s"SI-5604: found package class where package object expected: $tree") } @@ -1007,8 +1007,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genLoadModule(module: Symbol): Unit = { - def inStaticMethod = methSymbol != null && methSymbol.isStaticMember - if (claszSymbol == module.moduleClass && jMethodName != "readResolve" && !inStaticMethod) { + def inStaticMethod = methSymbol != null && symHelper(methSymbol).isStaticMember + if (claszSymbol == symHelper(module).moduleClass && jMethodName != "readResolve" && !inStaticMethod) { mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) } else { val mbt = symInfoTK(module).asClassBType @@ -1063,7 +1063,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { bc.genStartConcat for (elem <- concatenations) { val loadedElem = elem match { - case Apply(boxOp, value :: Nil) if isBox(boxOp.symbol) => + case Apply(boxOp, value :: Nil) if isBox(treeHelper(boxOp).symbol) => // Eliminate boxing of primitive values. Boxing is introduced by erasure because // there's only a single synthetic `+` method "added" to the string class. value @@ -1085,14 +1085,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * prevent an IllegalAccessError, (aladdin bug 455). */ def genCallMethod(method: Symbol, style: InvokeStyle, pos: Position = NoPosition, specificReceiver: Symbol = null): BType = { - val methodOwner = method.owner + val methodOwner = symHelper(method).owner // the class used in the invocation's method descriptor in the classfile val receiverClass = { if (specificReceiver != null) assert(style.isVirtual || specificReceiver == methodOwner, s"specificReceiver can only be specified for virtual calls. $method - $specificReceiver") - val useSpecificReceiver = specificReceiver != null && !specificReceiver.isBottomClass && !method.isScalaStatic + val useSpecificReceiver = specificReceiver != null && !symHelper(specificReceiver).isBottomClass && !symHelper(method).isScalaStatic val receiver = if (useSpecificReceiver) specificReceiver else methodOwner // workaround for a JVM bug: https://bugs.openjdk.java.net/browse/JDK-8154587 @@ -1111,23 +1111,23 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val isTraitMethodOverridingObjectMember = { receiver != methodOwner && // fast path - the boolean is used to pick either of these two, if they are the same it does not matter style.isVirtual && - receiver.isEmittedInterface && - Object_Type.decl(method.name).exists && { // fast path - compute overrideChain on the next line only if necessary - val syms = method.allOverriddenSymbols - !syms.isEmpty && syms.last.owner == ObjectClass + symHelper(receiver).isEmittedInterface && + symHelper(typeHelper(Object_Type).decl(symHelper(method).name)).exists && { // fast path - compute overrideChain on the next line only if necessary + val syms = symHelper(method).allOverriddenSymbols + !syms.isEmpty && symHelper(syms.last).owner == ObjectClass } } if (isTraitMethodOverridingObjectMember) methodOwner else receiver } - receiverClass.info // ensure types the type is up to date; erasure may add lateINTERFACE to traits + symHelper(receiverClass).info // ensure types the type is up to date; erasure may add lateINTERFACE to traits val receiverName = internalName(receiverClass) - val jname = method.javaSimpleName.toString + val jname = symHelper(method).javaSimpleName.toString val bmType = asmMethodType(method) val mdescr = bmType.descriptor - val isInterface = receiverClass.isEmittedInterface + val isInterface = symHelper(receiverClass).isEmittedInterface import InvokeStyle._ if (style == Super) { // DOTTY: this differ from how super-calls in traits are handled in the scalac backend, @@ -1158,7 +1158,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def liftStringConcat(tree: Tree): List[Tree] = tree match { case tree @ Apply(fun @ Select(larg, method), rarg) => if (isPrimitive(fun) && - primitives.getPrimitive(tree, larg.tpe) == ScalaPrimitivesOps.CONCAT) + primitives.getPrimitive(tree, treeHelper(larg).tpe) == ScalaPrimitivesOps.CONCAT) liftStringConcat(larg) ::: rarg else tree :: Nil @@ -1277,7 +1277,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genCond(rhs, success, failure, targetIfNoJump) } - primitives.getPrimitive(tree, lhs.tpe) match { + primitives.getPrimitive(tree, treeHelper(lhs).tpe) match { case ZNOT => genCond(lhs, failure, success, targetIfNoJump) case ZAND => genZandOrZor(and = true) case ZOR => genZandOrZor(and = false) @@ -1313,16 +1313,16 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * not using the rich equality is possible (their own equals method will do ok.) */ val mustUseAnyComparator: Boolean = { - val areSameFinals = l.tpe.isFinalType && r.tpe.isFinalType && (l.tpe =:= r.tpe) + val areSameFinals = typeHelper(treeHelper(l).tpe).isFinalType && typeHelper(treeHelper(r).tpe).isFinalType && (typeHelper(treeHelper(l).tpe) =:= treeHelper(r).tpe) - !areSameFinals && isMaybeBoxed(l.tpe.typeSymbol) && isMaybeBoxed(r.tpe.typeSymbol) + !areSameFinals && isMaybeBoxed(typeHelper(treeHelper(l).tpe).typeSymbol) && isMaybeBoxed(typeHelper(treeHelper(r).tpe).typeSymbol) } if (mustUseAnyComparator) { val equalsMethod: Symbol = { - if (l.tpe <:< BoxedNumberClass.tpe) { - if (r.tpe <:< BoxedNumberClass.tpe) externalEqualsNumNum - else if (r.tpe <:< BoxedCharacterClass.tpe) externalEqualsNumChar + if (typeHelper(treeHelper(l).tpe) <:< symHelper(BoxedNumberClass).tpe) { + if (typeHelper(treeHelper(r).tpe) <:< symHelper(BoxedNumberClass).tpe) externalEqualsNumNum + else if (typeHelper(treeHelper(r).tpe) <:< symHelper(BoxedCharacterClass).tpe) externalEqualsNumChar else externalEqualsNumObject } else externalEquals } @@ -1349,7 +1349,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genCZJUMP(success, failure, Primitives.NE, BOOL, targetIfNoJump) } else { // l == r -> if (l eq null) r eq null else l.equals(r) - val eqEqTempLocal = locals.makeLocal(ObjectReference, nme_EQEQ_LOCAL_VAR.mangledString, Object_Type, r.pos) + val eqEqTempLocal = locals.makeLocal(ObjectReference, nameHelper(nme_EQEQ_LOCAL_VAR).mangledString, Object_Type, treeHelper(r).pos) val lNull = new asm.Label val lNonNull = new asm.Label @@ -1379,38 +1379,38 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genInvokeDynamicLambda(ctor: Symbol, lambdaTarget: Symbol, environmentSize: Int, functionalInterface: Symbol): BType = { import java.lang.invoke.LambdaMetafactory.FLAG_SERIALIZABLE - debuglog(s"Using invokedynamic rather than `new ${ctor.owner}`") + debuglog(s"Using invokedynamic rather than `new ${symHelper(ctor).owner}`") val generatedType = classBTypeFromSymbol(functionalInterface) // Lambdas should be serializable if they implement a SAM that extends Serializable or if they // implement a scala.Function* class. - val isSerializable = functionalInterface.isSerializable || functionalInterface.isFunctionClass - val isInterface = lambdaTarget.owner.isEmittedInterface + val isSerializable = symHelper(functionalInterface).isSerializable || symHelper(functionalInterface).isFunctionClass + val isInterface = symHelper(symHelper(lambdaTarget).owner).isEmittedInterface val invokeStyle = - if (lambdaTarget.isStaticMember) asm.Opcodes.H_INVOKESTATIC - else if (lambdaTarget.isPrivate || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL + if (symHelper(lambdaTarget).isStaticMember) asm.Opcodes.H_INVOKESTATIC + else if (symHelper(lambdaTarget).isPrivate || symHelper(lambdaTarget).isClassConstructor) asm.Opcodes.H_INVOKESPECIAL else if (isInterface) asm.Opcodes.H_INVOKEINTERFACE else asm.Opcodes.H_INVOKEVIRTUAL val targetHandle = new asm.Handle(invokeStyle, - classBTypeFromSymbol(lambdaTarget.owner).internalName, - lambdaTarget.name.mangledString, + classBTypeFromSymbol(symHelper(lambdaTarget).owner).internalName, + nameHelper(symHelper(lambdaTarget).name).mangledString, asmMethodType(lambdaTarget).descriptor, /* itf = */ isInterface) - val (a,b) = lambdaTarget.info.paramTypes.splitAt(environmentSize) + val (a,b) = typeHelper(symHelper(lambdaTarget).info).paramTypes.splitAt(environmentSize) var (capturedParamsTypes, lambdaParamTypes) = if(int.doLabmdasFollowJVMMetafactoryOrder) (a,b) else (b,a) - if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = lambdaTarget.owner.info :: capturedParamsTypes + if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = symHelper(symHelper(lambdaTarget).owner).info :: capturedParamsTypes // Requires https://github.com/scala/scala-java8-compat on the runtime classpath - val returnUnit = lambdaTarget.info.resultType.typeSymbol == UnitClass + val returnUnit = typeHelper(typeHelper(symHelper(lambdaTarget).info).resultType).typeSymbol == UnitClass val functionalInterfaceDesc: String = generatedType.descriptor val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc // TODO specialization - val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(lambdaTarget.tpe.resultType)).toASMType - val abstractMethod = functionalInterface.samMethod() - val methodName = abstractMethod.name.mangledString + val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(typeHelper(symHelper(lambdaTarget).tpe).resultType)).toASMType + val abstractMethod = symHelper(functionalInterface).samMethod() + val methodName = nameHelper(symHelper(abstractMethod).name).mangledString val applyN = { val mt = asmMethodType(abstractMethod) mt.toASMType diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index f592e667b831..59de6866d07c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -39,10 +39,10 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ def getOutFolder(csym: Symbol, cName: String): AbstractFile = { try { - csym.outputDirectory + symHelper(csym).outputDirectory } catch { case ex: Throwable => - int.error(csym.pos, s"Couldn't create file for class $cName\n${ex.getMessage}") + int.error(symHelper(csym).pos, s"Couldn't create file for class $cName\n${ex.getMessage}") null } } @@ -192,12 +192,12 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // If the `sym` is a java module class, we use the java class instead. This ensures that we // register the class (instead of the module class) in innerClassBufferASM. // The two symbols have the same name, so the resulting internalName is the same. - val classSym = if (sym.isJavaDefined && sym.isModuleClass) sym.linkedClassOfClass else sym + val classSym = if (symHelper(sym).isJavaDefined && symHelper(sym).isModuleClass) symHelper(sym).linkedClassOfClass else sym getClassBTypeAndRegisterInnerClass(classSym).internalName } private def assertClassNotArray(sym: Symbol): Unit = { - assert(sym.isClass, sym) + assert(symHelper(sym).isClass, sym) assert(sym != ArrayClass || isCompilingArray, sym) } @@ -236,11 +236,11 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ final def asmMethodType(msym: Symbol): MethodBType = { - assert(msym.isMethod, s"not a method-symbol: $msym") + assert(symHelper(msym).isMethod, s"not a method-symbol: $msym") val resT: BType = - if (msym.isClassConstructor || msym.isConstructor) UNIT - else toTypeKind(msym.tpe.resultType) - MethodBType(msym.tpe.paramTypes map toTypeKind, resT) + if (symHelper(msym).isClassConstructor || symHelper(msym).isConstructor) UNIT + else toTypeKind(typeHelper(symHelper(msym).tpe).resultType) + MethodBType(typeHelper(symHelper(msym).tpe).paramTypes map toTypeKind, resT) } /** @@ -255,7 +255,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ final def symDescriptor(sym: Symbol): String = { getClassBTypeAndRegisterInnerClass(sym).descriptor } - final def toTypeKind(tp: Type): BType = tp.toTypeKind(BCodeHelpers.this)(this) + final def toTypeKind(tp: Type): BType = typeHelper(tp).toTypeKind(BCodeHelpers.this)(this) } // end of trait BCInnerClassGen @@ -309,8 +309,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ private def addForwarder(jclass: asm.ClassVisitor, module: Symbol, m: Symbol): Unit = { val moduleName = internalName(module) - val methodInfo = module.thisType.memberInfo(m) - val paramJavaTypes: List[BType] = methodInfo.paramTypes map toTypeKind + val methodInfo = typeHelper(symHelper(module).thisType).memberInfo(m) + val paramJavaTypes: List[BType] = typeHelper(methodInfo).paramTypes map toTypeKind // val paramNames = 0 until paramJavaTypes.length map ("x_" + _) /* Forwarders must not be marked final, @@ -320,17 +320,17 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // TODO: evaluate the other flags we might be dropping on the floor here. // TODO: ACC_SYNTHETIC ? val flags = GenBCodeOps.PublicStatic | ( - if (m.isVarargsMethod) asm.Opcodes.ACC_VARARGS else 0 + if (symHelper(m).isVarargsMethod) asm.Opcodes.ACC_VARARGS else 0 ) // TODO needed? for(ann <- m.annotations) { ann.symbol.initialize } val jgensig = getStaticForwarderGenericSignature(m, module) - val (throws, others) = m.annotations partition (_.symbol == ThrowsClass) + val (throws, others) = symHelper(m).annotations partition (annotHelper(_).symbol == ThrowsClass) val thrownExceptions: List[String] = getExceptions(throws) - val jReturnType = toTypeKind(methodInfo.resultType) + val jReturnType = toTypeKind(typeHelper(methodInfo).resultType) val mdesc = MethodBType(paramJavaTypes, jReturnType).descriptor - val mirrorMethodName = m.javaSimpleName.toString + val mirrorMethodName = symHelper(m).javaSimpleName.toString val mirrorMethod: asm.MethodVisitor = jclass.visitMethod( flags, mirrorMethodName, @@ -340,7 +340,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ) emitAnnotations(mirrorMethod, others) - emitParamAnnotations(mirrorMethod, m.info.params.map(_.annotations)) + emitParamAnnotations(mirrorMethod, typeHelper(symHelper(m).info).params.map(symHelper(_).annotations)) mirrorMethod.visitCode() @@ -369,24 +369,24 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def addForwarders(jclass: asm.ClassVisitor, jclassName: String, moduleClass: Symbol): Unit = { - assert(moduleClass.isModuleClass, moduleClass) + assert(symHelper(moduleClass).isModuleClass, moduleClass) debuglog(s"Dumping mirror class for object: $moduleClass") - val linkedClass = moduleClass.companionClass + val linkedClass = symHelper(moduleClass).companionClass lazy val conflictingNames: Set[Name] = { - (linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name }).toSet + (typeHelper(symHelper(linkedClass).info).members collect { case sym if nameHelper(symHelper(sym).name).isTermName => symHelper(sym).name }).toSet } debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") - for (m0 <- moduleClass.info.sortedMembersBasedOnFlags(required = Flag_METHOD, excluded = ExcludedForwarderFlags)) { - val m = if (m0.isBridge) m0.nextOverriddenSymbol else m0 + for (m0 <- typeHelper(symHelper(moduleClass).info).sortedMembersBasedOnFlags(required = Flag_METHOD, excluded = ExcludedForwarderFlags)) { + val m = if (symHelper(m0).isBridge) symHelper(m0).nextOverriddenSymbol else m0 if (m == NoSymbol) log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") - else if (m.isType || m.isDeferred || (m.owner eq ObjectClass) || m.isConstructor || m.isExpanded) + else if (symHelper(m).isType || symHelper(m).isDeferred || (symHelper(m).owner eq ObjectClass) || symHelper(m).isConstructor || symHelper(m).isExpanded) debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") - else if (conflictingNames(m.name)) - log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") - else if (m.hasAccessBoundary) + else if (conflictingNames(symHelper(m).name)) + log(s"No forwarder for $m due to conflict with ${typeHelper(symHelper(linkedClass).info).member(symHelper(m).name)}") + else if (symHelper(m).hasAccessBoundary) log(s"No forwarder for non-public member $m") else { log(s"Adding static forwarder for '$m' from $jclassName to '$moduleClass'") @@ -458,8 +458,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def genMirrorClass(moduleClass: Symbol, cunit: CompilationUnit): asm.tree.ClassNode = { - assert(moduleClass.isModuleClass) - assert(moduleClass.companionClass == NoSymbol, moduleClass) + assert(symHelper(moduleClass).isModuleClass) + assert(symHelper(moduleClass).companionClass == NoSymbol, moduleClass) innerClassBufferASM.clear() this.cunit = cunit val moduleName = internalName(moduleClass) // + "$" @@ -481,9 +481,9 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { null /* SourceDebugExtension */) } - val ssa = getAnnotPickle(mirrorName, moduleClass.companionSymbol) + val ssa = getAnnotPickle(mirrorName, symHelper(moduleClass).companionSymbol) mirrorClass.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) - emitAnnotations(mirrorClass, moduleClass.annotations ++ ssa) + emitAnnotations(mirrorClass, symHelper(moduleClass).annotations ++ ssa) addForwarders(mirrorClass, mirrorName, moduleClass) @@ -492,7 +492,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { mirrorClass.visitEnd() - moduleClass.name // this side-effect is necessary, really. + symHelper(moduleClass).name // this side-effect is necessary, really. mirrorClass } @@ -517,7 +517,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ def isAndroidParcelableClass(sym: Symbol) = (AndroidParcelableInterface != NoSymbol) && - (sym.parentSymbols contains AndroidParcelableInterface) + (symHelper(sym).parentSymbols contains AndroidParcelableInterface) /* * must-single-thread diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 2001ded186e3..03112bc835e0 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -64,15 +64,15 @@ trait BCodeSkelBuilder extends BCodeHelpers { def paramTKs(app: Apply, take: Int = -1): List[BType] = app match { case Apply(fun, _) => - val funSym = fun.symbol - (funSym.info.paramTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) + val funSym = treeHelper(fun).symbol + (typeHelper(symHelper(funSym).info).paramTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) } def symInfoTK(sym: Symbol): BType = { - toTypeKind(sym.info) // this tracks mentioned inner classes (in innerClassBufferASM) + toTypeKind(symHelper(sym).info) // this tracks mentioned inner classes (in innerClassBufferASM) } - def tpeTK(tree: Tree): BType = { toTypeKind(tree.tpe) } + def tpeTK(tree: Tree): BType = { toTypeKind(treeHelper(tree).tpe) } override def getCurrentCUnit(): CompilationUnit = { cunit } @@ -83,16 +83,16 @@ trait BCodeSkelBuilder extends BCodeHelpers { assert(cnode == null, "GenBCode detected nested methods.") innerClassBufferASM.clear() - claszSymbol = cd.symbol + claszSymbol = treeHelper(cd).symbol isCZParcelable = isAndroidParcelableClass(claszSymbol) - isCZStaticModule = claszSymbol.isStaticModuleClass + isCZStaticModule = symHelper(claszSymbol).isStaticModuleClass thisName = internalName(claszSymbol) cnode = new ClassNode1() initJClass(cnode) - val hasStaticCtor = cd.symbol.methodSymbols exists (_.isStaticConstructor) + val hasStaticCtor = symHelper(treeHelper(cd).symbol).methodSymbols exists (symHelper(_).isStaticConstructor) if (!hasStaticCtor) { // but needs one ... if (isCZStaticModule || isCZParcelable) { @@ -100,7 +100,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } } - val optSerial: Option[Long] = claszSymbol.serialVUID + val optSerial: Option[Long] = symHelper(claszSymbol).serialVUID if (optSerial.isDefined) { addSerialVUID(optSerial.get, cnode)} addClassFields() @@ -113,7 +113,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { AsmUtils.traceClass(cnode) cnode.innerClasses - assert(cd.symbol == claszSymbol, "Someone messed up BCodePhase.claszSymbol during genPlainClass().") + assert(treeHelper(cd).symbol == claszSymbol, "Someone messed up BCodePhase.claszSymbol during genPlainClass().") } // end of method genPlainClass() @@ -122,8 +122,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ private def initJClass(jclass: asm.ClassVisitor): Unit = { - val ps = claszSymbol.info.parents - val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(ps.head.typeSymbol) + val ps = typeHelper(symHelper(claszSymbol).info).parents + val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(typeHelper(ps.head).typeSymbol) val interfaceNames = classBTypeFromSymbol(claszSymbol).info.interfaces map { case classBType => if (classBType.isNestedClass) { innerClassBufferASM += classBType } @@ -132,7 +132,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val flags = javaFlags(claszSymbol) - val thisSignature = getGenericSignature(claszSymbol, claszSymbol.owner) + val thisSignature = getGenericSignature(claszSymbol, symHelper(claszSymbol).owner) cnode.visit(classfileVersion, flags, thisName, thisSignature, superClass, interfaceNames.toArray) @@ -149,7 +149,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val ssa = getAnnotPickle(thisName, claszSymbol) cnode.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) - emitAnnotations(cnode, claszSymbol.annotations ++ ssa) + emitAnnotations(cnode, symHelper(claszSymbol).annotations ++ ssa) if (isCZStaticModule || isCZParcelable) { @@ -157,16 +157,16 @@ trait BCodeSkelBuilder extends BCodeHelpers { } else { - val skipStaticForwarders = (claszSymbol.isInterface || claszSymbol.isModule || noForwarders) + val skipStaticForwarders = (symHelper(claszSymbol).isInterface || symHelper(claszSymbol).isModule || noForwarders) if (!skipStaticForwarders) { - val lmoc = claszSymbol.companionModule + val lmoc = symHelper(claszSymbol).companionModule // add static forwarders if there are no name conflicts; see bugs #363 and #1735 if (lmoc != NoSymbol) { // it must be a top level class (name contains no $s) - val isCandidateForForwarders = lmoc.shouldEmitForwarders + val isCandidateForForwarders = symHelper(lmoc).shouldEmitForwarders if (isCandidateForForwarders) { log(s"Adding static forwarders from '$claszSymbol' to implementations in '$lmoc'") - addForwarders(cnode, thisName, lmoc.moduleClass) + addForwarders(cnode, thisName, symHelper(lmoc).moduleClass) } } } @@ -227,22 +227,22 @@ trait BCodeSkelBuilder extends BCodeHelpers { * backend emits them as static). * No code is needed for this module symbol. */ - for (f <- claszSymbol.fieldSymbols) { + for (f <- symHelper(claszSymbol).fieldSymbols) { val javagensig = getGenericSignature(f, claszSymbol) val flags = javaFieldFlags(f) - assert(!f.isStaticMember || !claszSymbol.isInterface || !f.isMutable, + assert(!symHelper(f).isStaticMember || !symHelper(claszSymbol).isInterface || !symHelper(f).isMutable, s"interface $claszSymbol cannot have non-final static field $f") val jfield = new asm.tree.FieldNode( flags, - f.javaSimpleName.toString, + symHelper(f).javaSimpleName.toString, symInfoTK(f).descriptor, javagensig, null // no initial value ) cnode.fields.add(jfield) - emitAnnotations(jfield, f.annotations) + emitAnnotations(jfield, symHelper(f).annotations) } } // end of method addClassFields() @@ -278,7 +278,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ var jumpDest: immutable.Map[ /* Labeled or LabelDef */ Symbol, asm.Label ] = null def programPoint(labelSym: Symbol): asm.Label = { - assert(labelSym.isLabel, s"trying to map a non-label symbol to an asm.Label, at: ${labelSym.pos}") + assert(symHelper(labelSym).isLabel, s"trying to map a non-label symbol to an asm.Label, at: ${symHelper(labelSym).pos}") jumpDest.getOrElse(labelSym, { val pp = new asm.Label jumpDest += (labelSym -> pp) @@ -361,7 +361,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ def makeLocal(tk: BType, name: String, tpe: Type, pos: Position): Symbol = { - val locSym = methSymbol.freshLocal(cunit, name, tpe, pos, Flag_SYNTHETIC) // setInfo tpe + val locSym = symHelper(methSymbol).freshLocal(cunit, name, tpe, pos, Flag_SYNTHETIC) // setInfo tpe makeLocal(locSym, tk) locSym } @@ -377,10 +377,10 @@ trait BCodeSkelBuilder extends BCodeHelpers { private def makeLocal(sym: Symbol, tk: BType): Local = { assert(nxtIdx != -1, "not a valid start index") - val loc = Local(tk, sym.javaSimpleName.toString, nxtIdx, sym.isSynthetic) + val loc = Local(tk, symHelper(sym).javaSimpleName.toString, nxtIdx, symHelper(sym).isSynthetic) val existing = slots.put(sym, loc) if (existing.isDefined) - error(sym.pos, "attempt to create duplicate local var.") + error(symHelper(sym).pos, "attempt to create duplicate local var.") assert(tk.size > 0, "makeLocal called for a symbol whose type is Unit.") nxtIdx += tk.size loc @@ -429,8 +429,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { case _ => false } ) } def lineNumber(tree: Tree): Unit = { - if (!emitLines || !tree.pos.isDefined) return; - val nr = tree.pos.finalPosition.line + if (!emitLines || !positionHelper(treeHelper(tree).pos).isDefined) return; + val nr = positionHelper(positionHelper(treeHelper(tree).pos).finalPosition).line if (nr != lastEmittedLineNr) { lastEmittedLineNr = nr lastInsn match { @@ -446,7 +446,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // on entering a method def resetMethodBookkeeping(dd: DefDef) = dd match { case DefDef(_, _, _, _, _, rhs) => - locals.reset(isStaticMethod = methSymbol.isStaticMember) + locals.reset(isStaticMethod = symHelper(methSymbol).isStaticMember) jumpDest = immutable.Map.empty[ /* LabelDef */ Symbol, asm.Label ] // check previous invocation of genDefDef exited as many varsInScope as it entered. @@ -482,7 +482,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def initJMethod(flags: Int, paramAnnotations: List[List[Annotation]]): Unit = { val jgensig = getGenericSignature(methSymbol, claszSymbol) - val (excs, others) = methSymbol.annotations partition (_.symbol == ThrowsClass) + val (excs, others) = symHelper(methSymbol).annotations partition (annotHelper(_).symbol == ThrowsClass) val thrownExceptions: List[String] = getExceptions(excs) val bytecodeName = @@ -509,13 +509,13 @@ trait BCodeSkelBuilder extends BCodeHelpers { def genDefDef(dd: DefDef): Unit = dd match { case DefDef(_, _, _, vparamss, _, rhs) => // the only method whose implementation is not emitted: getClass() - if (dd.symbol.isGetClass) { return } + if (symHelper(treeHelper(dd).symbol).isGetClass) { return } assert(mnode == null, "GenBCode detected nested method.") - methSymbol = dd.symbol - jMethodName = methSymbol.javaSimpleName.toString - returnType = asmMethodType(dd.symbol).returnType - isMethSymStaticCtor = methSymbol.isStaticConstructor + methSymbol = treeHelper(dd).symbol + jMethodName = symHelper(methSymbol).javaSimpleName.toString + returnType = asmMethodType(treeHelper(dd).symbol).returnType + isMethSymStaticCtor = symHelper(methSymbol).isStaticConstructor resetMethodBookkeeping(dd) @@ -523,26 +523,26 @@ trait BCodeSkelBuilder extends BCodeHelpers { assert(vparamss.isEmpty || vparamss.tail.isEmpty, s"Malformed parameter list: $vparamss") val params = if (vparamss.isEmpty) Nil else vparamss.head - for (p <- params) { locals.makeLocal(p.symbol) } + for (p <- params) { locals.makeLocal(treeHelper(p).symbol) } // debug assert((params.map(p => locals(p.symbol).tk)) == asmMethodType(methSymbol).getArgumentTypes.toList, "debug") if (params.size > MaximumJvmParameters) { // SI-7324 - error(methSymbol.pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.") + error(symHelper(methSymbol).pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.") return } - val isNative = methSymbol.hasAnnotation(NativeAttr) - val isAbstractMethod = (methSymbol.isDeferred || (methSymbol.owner.isInterface && !methSymbol.isJavaDefaultMethod)) + val isNative = symHelper(methSymbol).hasAnnotation(NativeAttr) + val isAbstractMethod = (symHelper(methSymbol).isDeferred || (symHelper(symHelper(methSymbol).owner).isInterface && !symHelper(methSymbol).isJavaDefaultMethod)) val flags = GenBCodeOps.mkFlags( javaFlags(methSymbol), if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0, - if (methSymbol.isStrictFP) asm.Opcodes.ACC_STRICT else 0, + if (symHelper(methSymbol).isStrictFP) asm.Opcodes.ACC_STRICT else 0, if (isNative) asm.Opcodes.ACC_NATIVE else 0 // native methods of objects are generated in mirror classes ) // TODO needed? for(ann <- m.symbol.annotations) { ann.symbol.initialize } - initJMethod(flags, params.map(p => p.symbol.annotations)) + initJMethod(flags, params.map(p => symHelper(treeHelper(p).symbol).annotations)) if (!isAbstractMethod && !isNative) { @@ -555,7 +555,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { case Return(_) | Block(_, Return(_)) | Throw(_) | Block(_, Throw(_)) => () case EmptyTree => error(NoPosition, "Concrete method has no definition: " + dd + ( - if (settings_debug) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" + if (settings_debug) "(found: " + typeHelper(symHelper(symHelper(methSymbol).owner).info).decls.toList.mkString(", ") + ")" else "") ) case _ => @@ -575,7 +575,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { 0 ) } - for (p <- params) { emitLocalVarScope(p.symbol, veryFirstProgramPoint, onePastLastProgramPoint, force = true) } + for (p <- params) { emitLocalVarScope(treeHelper(p).symbol, veryFirstProgramPoint, onePastLastProgramPoint, force = true) } } if (isMethSymStaticCtor) { appendToStaticCtor(dd) } @@ -621,12 +621,12 @@ trait BCodeSkelBuilder extends BCodeHelpers { // call object's private ctor from static ctor if (isCZStaticModule) { // NEW `moduleName` - val className = internalName(methSymbol.enclClass) + val className = internalName(symHelper(methSymbol).enclClass) insnModA = new asm.tree.TypeInsnNode(asm.Opcodes.NEW, className) // INVOKESPECIAL - val callee = methSymbol.enclClass.primaryConstructor - val jname = callee.javaSimpleName.toString - val jowner = internalName(callee.owner) + val callee = symHelper(symHelper(methSymbol).enclClass).primaryConstructor + val jname = symHelper(callee).javaSimpleName.toString + val jowner = internalName(symHelper(callee).owner) val jtype = asmMethodType(callee).descriptor insnModB = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESPECIAL, jowner, jname, jtype, false) } @@ -645,9 +645,9 @@ trait BCodeSkelBuilder extends BCodeHelpers { null ) // INVOKESTATIC CREATOR(): android.os.Parcelable$Creator; -- TODO where does this Android method come from? - val callee = claszSymbol.companionModule.info.member(androidFieldName) - val jowner = internalName(callee.owner) - val jname = callee.javaSimpleName.toString + val callee = typeHelper(symHelper(symHelper(claszSymbol).companionModule).info).member(androidFieldName) + val jowner = internalName(symHelper(callee).owner) + val jname = symHelper(callee).javaSimpleName.toString val jtype = asmMethodType(callee).descriptor insnParcA = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESTATIC, jowner, jname, jtype, false) // PUTSTATIC `thisName`.CREATOR; diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index 73131e520acb..7780e916f2ed 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -22,13 +22,13 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { def genSynchronized(tree: Apply, expectedType: BType): BType = tree match { case Apply(TypeApply(fun, _), args) => - val monitor = locals.makeLocal(ObjectReference, "monitor", Object_Type, tree.pos) + val monitor = locals.makeLocal(ObjectReference, "monitor", Object_Type, treeHelper(tree).pos) val monCleanup = new asm.Label // if the synchronized block returns a result, store it in a local variable. // Just leaving it on the stack is not valid in MSIL (stack is cleaned when leaving try-blocks). val hasResult = (expectedType != UNIT) - val monitorResult: Symbol = if (hasResult) locals.makeLocal(tpeTK(args.head), "monitorResult", Object_Type, tree.pos) else null + val monitorResult: Symbol = if (hasResult) locals.makeLocal(tpeTK(args.head), "monitorResult", Object_Type, treeHelper(tree).pos) else null /* ------ (1) pushing and entering the monitor, also keeping a reference to it in a local var. ------ */ genLoadQualifier(fun) @@ -178,7 +178,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { pat match { case Typed(Ident(`nme_WILDCARD`), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) case Ident(`nme_WILDCARD`) => NamelessEH(ThrowableReference, caseBody) - case Bind(_, _) => BoundEH (pat.symbol, caseBody) + case Bind(_, _) => BoundEH (treeHelper(pat).symbol, caseBody) } } @@ -206,7 +206,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { * please notice `tmp` has type tree.tpe, while `earlyReturnVar` has the method return type. * Because those two types can be different, dedicated vars are needed. */ - val tmp = if (guardResult) locals.makeLocal(tpeTK(tree), "tmp", tree.tpe, tree.pos) else null + val tmp = if (guardResult) locals.makeLocal(tpeTK(tree), "tmp", treeHelper(tree).tpe, treeHelper(tree).pos) else null /* * upon early return from the try-body or one of its EHs (but not the EH-version of the finally-clause) @@ -316,7 +316,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { nopIfNeeded(startTryBody) val finalHandler = currProgramPoint() // version of the finally-clause reached via unhandled exception. protect(startTryBody, finalHandler, finalHandler, null) - val Local(eTK, _, eIdx, _) = locals(locals.makeLocal(ThrowableReference, "exc", Throwable_Type, finalizer.pos)) + val Local(eTK, _, eIdx, _) = locals(locals.makeLocal(ThrowableReference, "exc", Throwable_Type, treeHelper(finalizer).pos)) bc.store(eIdx, eTK) emitFinalizer(finalizer, null, isDuplicate = true) bc.load(eIdx, eTK) @@ -403,7 +403,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { } /* Does this tree have a try-catch block? */ - def mayCleanStack(tree: Tree): Boolean = tree exists { t => t match { + def mayCleanStack(tree: Tree): Boolean = treeHelper(tree) exists { t => t match { case Try(_, _, _) => true case _ => false } diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 62cdac980254..dac96bb24431 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -45,14 +45,14 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { */ final def classBTypeFromSymbol(classSym: Symbol): ClassBType = { assert(classSym != NoSymbol, "Cannot create ClassBType from NoSymbol") - assert(classSym.isClass, s"Cannot create ClassBType from non-class symbol $classSym") + assert(symHelper(classSym).isClass, s"Cannot create ClassBType from non-class symbol $classSym") assert( (!primitiveTypeMap.contains(classSym) || isCompilingPrimitive) && (classSym != NothingClass && classSym != NullClass), - s"Cannot create ClassBType for special class symbol ${classSym.showFullName}") + s"Cannot create ClassBType for special class symbol ${symHelper(classSym).showFullName}") convertedClasses.getOrElse(classSym, { - val internalName = classSym.javaBinaryName + val internalName = symHelper(classSym).javaBinaryName // We first create and add the ClassBType to the hash map before computing its info. This // allows initializing cylic dependencies, see the comment on variable ClassBType._info. val classBType = new ClassBType(internalName) @@ -62,21 +62,21 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { } private def setClassInfo(classSym: Symbol, classBType: ClassBType): ClassBType = { - val superClassSym = classSym.superClass + val superClassSym = symHelper(classSym).superClass assert( if (classSym == ObjectClass) superClassSym == NoSymbol - else if (classSym.isInterface) + else if (symHelper(classSym).isInterface) superClassSym == ObjectClass else // A ClassBType for a primitive class (scala.Boolean et al) is only created when compiling these classes. - ((superClassSym != NoSymbol) && !superClassSym.isInterface) || (isCompilingPrimitive && primitiveTypeMap.contains(classSym)), + ((superClassSym != NoSymbol) && !symHelper(superClassSym).isInterface) || (isCompilingPrimitive && primitiveTypeMap.contains(classSym)), s"Bad superClass for $classSym: $superClassSym" ) val superClass = if (superClassSym == NoSymbol) None else Some(classBTypeFromSymbol(superClassSym)) - val interfaces = classSym.superInterfaces.map(classBTypeFromSymbol) + val interfaces = symHelper(classSym).superInterfaces.map(classBTypeFromSymbol) val flags = javaFlags(classSym) @@ -95,7 +95,7 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { // The lambdalift phase lifts all nested classes to the enclosing class, so if we collect // member classes right after lambdalift, we obtain all nested classes, including local and // anonymous ones. - val nestedClasses = classSym.nestedClasses + val nestedClasses = symHelper(classSym).nestedClasses // If this is a top-level class, and it has a companion object, the member classes of the // companion are added as members of the class. For example: @@ -109,8 +109,8 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { // This is done by buildNestedInfo, the reason is Java compatibility, see comment in BTypes. // For consistency, the InnerClass entry for D needs to be present in C - to Java it looks // like D is a member of C, not C$. - val linkedClass = classSym.linkedClass - val companionModuleMembers = classSym.companionModuleMembers + val linkedClass = symHelper(classSym).linkedClass + val companionModuleMembers = symHelper(classSym).companionModuleMembers nestedClasses ++ companionModuleMembers } @@ -122,10 +122,10 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { * Here we get rid of the module class B, making sure that the class B is present. */ val nestedClassSymbolsNoJavaModuleClasses = nestedClassSymbols.filter(s => { - if (s.isJavaDefined && s.isModuleClass) { + if (symHelper(s).isJavaDefined && symHelper(s).isModuleClass) { // We could also search in nestedClassSymbols for s.linkedClassOfClass, but sometimes that // returns NoSymbol, so it doesn't work. - val nb = nestedClassSymbols.count(mc => mc.name == s.name && mc.owner == s.owner) + val nb = nestedClassSymbols.count(mc => symHelper(mc).name == symHelper(s).name && symHelper(mc).owner == symHelper(s).owner) // this assertion is specific to how ScalaC works. It doesn't apply to dotty, as n dotty there will be B & B$ // assert(nb == 2, s"Java member module without member class: $s - $nestedClassSymbols") false @@ -142,34 +142,34 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { - assert(innerClassSym.isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") + assert(symHelper(innerClassSym).isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") - val isNested = !innerClassSym.rawowner.isPackageClass + val isNested = !symHelper(symHelper(innerClassSym).rawowner).isPackageClass if (!isNested) None else { // See comment in BTypes, when is a class marked static in the InnerClass table. - val isStaticNestedClass = innerClassSym.originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner + val isStaticNestedClass = symHelper(symHelper(symHelper(innerClassSym).originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner // After lambdalift (which is where we are), the rawowoner field contains the enclosing class. - val enclosingClassSym = innerClassSym.enclosingClassSym + val enclosingClassSym = symHelper(innerClassSym).enclosingClassSym val enclosingClass: ClassBType = classBTypeFromSymbol(enclosingClassSym) val outerName: Option[String] = { if (isAnonymousOrLocalClass(innerClassSym)) { None } else { - val outerName = innerClassSym.rawowner.javaBinaryName + val outerName = symHelper(symHelper(innerClassSym).rawowner).javaBinaryName // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. val outerNameModule = - if (innerClassSym.rawowner.isTopLevelModuleClass) dropModule(outerName) + if (symHelper(symHelper(innerClassSym).rawowner).isTopLevelModuleClass) dropModule(outerName) else outerName Some(outerNameModule.toString) } } val innerName: Option[String] = { - if (innerClassSym.isAnonymousClass || innerClassSym.isAnonymousFunction) None - else Some(innerClassSym.rawname + innerClassSym.moduleSuffix) // moduleSuffix for module classes + if (symHelper(innerClassSym).isAnonymousClass || symHelper(innerClassSym).isAnonymousFunction) None + else Some(symHelper(innerClassSym).rawname + symHelper(innerClassSym).moduleSuffix) // moduleSuffix for module classes } Some(NestedInfo(enclosingClass, outerName, innerName, isStaticNestedClass)) @@ -197,42 +197,42 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { final def javaFlags(sym: Symbol): Int = { - val privateFlag = sym.getsJavaPrivateFlag + val privateFlag = symHelper(sym).getsJavaPrivateFlag - val finalFlag = sym.getsJavaFinalFlag + val finalFlag = symHelper(sym).getsJavaFinalFlag import asm.Opcodes._ GenBCodeOps.mkFlags( if (privateFlag) ACC_PRIVATE else ACC_PUBLIC, - if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0, - if (sym.isInterface) ACC_INTERFACE else 0, + if (symHelper(sym).isDeferred || symHelper(sym).hasAbstractFlag) ACC_ABSTRACT else 0, + if (symHelper(sym).isInterface) ACC_INTERFACE else 0, if (finalFlag && // Primitives are "abstract final" to prohibit instantiation // without having to provide any implementations, but that is an // illegal combination of modifiers at the bytecode level so // suppress final if abstract if present. - !sym.hasAbstractFlag && + !symHelper(sym).hasAbstractFlag && // Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks - !sym.isBridge) + !symHelper(sym).isBridge) ACC_FINAL else 0, - if (sym.isStaticMember) ACC_STATIC else 0, - if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0, - if (sym.isArtifact) ACC_SYNTHETIC else 0, - if (sym.isClass && !sym.isInterface) ACC_SUPER else 0, - if (sym.hasEnumFlag) ACC_ENUM else 0, - if (sym.isVarargsMethod) ACC_VARARGS else 0, - if (sym.isSynchronized) ACC_SYNCHRONIZED else 0, - if (sym.isDeprecated) asm.Opcodes.ACC_DEPRECATED else 0, - if (sym.isEnum) asm.Opcodes.ACC_ENUM else 0 + if (symHelper(sym).isStaticMember) ACC_STATIC else 0, + if (symHelper(sym).isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0, + if (symHelper(sym).isArtifact) ACC_SYNTHETIC else 0, + if (symHelper(sym).isClass && !symHelper(sym).isInterface) ACC_SUPER else 0, + if (symHelper(sym).hasEnumFlag) ACC_ENUM else 0, + if (symHelper(sym).isVarargsMethod) ACC_VARARGS else 0, + if (symHelper(sym).isSynchronized) ACC_SYNCHRONIZED else 0, + if (symHelper(sym).isDeprecated) asm.Opcodes.ACC_DEPRECATED else 0, + if (symHelper(sym).isEnum) asm.Opcodes.ACC_ENUM else 0 ) } def javaFieldFlags(sym: Symbol) = { javaFlags(sym) | GenBCodeOps.mkFlags( - if (sym hasAnnotation TransientAttr) asm.Opcodes.ACC_TRANSIENT else 0, - if (sym hasAnnotation VolatileAttr) asm.Opcodes.ACC_VOLATILE else 0, - if (sym.isMutable) 0 else asm.Opcodes.ACC_FINAL + if (symHelper(sym) hasAnnotation TransientAttr) asm.Opcodes.ACC_TRANSIENT else 0, + if (symHelper(sym) hasAnnotation VolatileAttr) asm.Opcodes.ACC_VOLATILE else 0, + if (symHelper(sym).isMutable) 0 else asm.Opcodes.ACC_FINAL ) } } diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index e73d8fd9aa5e..70f76f15f8d8 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -166,14 +166,14 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { def getSingleOutput: Option[AbstractFile] - implicit def symHelper(sym: Symbol): SymbolHelper - implicit def typeHelper(tp: Type): TypeHelper - implicit def nameHelper(n: Name): NameHelper - implicit def annotHelper(a: Annotation): AnnotationHelper - implicit def treeHelper(a: Tree): TreeHelper + def symHelper(sym: Symbol): SymbolHelper + def typeHelper(tp: Type): TypeHelper + def nameHelper(n: Name): NameHelper + def annotHelper(a: Annotation): AnnotationHelper + def treeHelper(a: Tree): TreeHelper - implicit def constantHelper(a: Constant): ConstantHelper - implicit def positionHelper(a: Position): PositionHelper + def constantHelper(a: Constant): ConstantHelper + def positionHelper(a: Position): PositionHelper val Assign: AssignDeconstructor @@ -426,7 +426,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { * which we represent as classes. */ final def isEmittedInterface: Boolean = isInterface || - isJavaDefined && (isAnnotation || isModuleClass && companionClass.isInterface) + isJavaDefined && (isAnnotation || isModuleClass && symHelper(companionClass).isInterface) // tests def isClass: Boolean @@ -548,7 +548,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. */ def isOriginallyStaticOwner: Boolean = - isPackageClass || isModuleClass && originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner + isPackageClass || isModuleClass && symHelper(symHelper(originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner def samMethod(): Symbol @@ -728,7 +728,7 @@ abstract class BackendInterfaceDefinitions { self: BackendInterface => val ThrowsClass: Symbol = requiredClass[scala.throws[_]] // Module symbols used in backend - val StringModule: Symbol = StringClass.linkedClassOfClass + val StringModule: Symbol = symHelper(StringClass).linkedClassOfClass val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type] @@ -762,7 +762,7 @@ abstract class BackendInterfaceDefinitions { self: BackendInterface => case Literal(_) => true case _ => false } - def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((t.symbol ne null) && t.symbol.isModule) + def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((treeHelper(t).symbol ne null) && symHelper(treeHelper(t).symbol).isModule) def ifOneIsNull(l: Tree, r: Tree): Tree = if (isNull(l)) r else if (isNull(r)) l else null private val primitiveCompilationUnits = Set( diff --git a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala index 43c9e252cb57..b67baf8e96d4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala +++ b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala @@ -31,7 +31,7 @@ trait BytecodeWriters { ensureDirectory(dir) fileNamed pathParts.last + suffix } def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile = - getFile(sym.outputDirectory, clsName, suffix) + getFile(symHelper(sym).outputDirectory, clsName, suffix) def factoryNonJarBytecodeWriter(): BytecodeWriter = { val emitAsmp = int.emitAsmp diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index f2eceebf923b..4a153e8c733b 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -205,7 +205,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 (toDenot(annotHelper(annot).atp.typeSymbol).hasAnnotation(AnnotationRetentionAttr)) retentionPolicyOf(annot) == AnnotationRetentionRuntimeAttr else { // SI-8926: if the annotation class symbol doesn't have a @RetentionPolicy annotation, the From 05af70ba490b442f102cedce17460dc40132f2c6 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 2 Jun 2020 23:29:09 +0200 Subject: [PATCH 06/98] Rename BackendInterface extractors --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 124 +++++++++--------- .../tools/backend/jvm/BCodeHelpers.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 16 +-- .../tools/backend/jvm/BCodeSyncAndTry.scala | 14 +- .../tools/backend/jvm/BackendInterface.scala | 62 ++++----- .../backend/jvm/DottyBackendInterface.scala | 62 ++++----- 6 files changed, 140 insertions(+), 140 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index d5d79331df52..7c389daec115 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -57,7 +57,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case Assign(lhs @ Select(qual, _), rhs) => + case AssignBI(lhs @ SelectBI(qual, _), rhs) => val isStatic = symHelper(treeHelper(lhs).symbol).isStaticMember if (!isStatic) { genLoadQualifier(lhs) } genLoad(rhs, symInfoTK(treeHelper(lhs).symbol)) @@ -66,7 +66,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val receiverClass = typeHelper(treeHelper(qual).tpe).typeSymbol fieldStore(treeHelper(lhs).symbol, receiverClass) - case Assign(lhs, rhs) => + case AssignBI(lhs, rhs) => val s = treeHelper(lhs).symbol val Local(tk, _, idx, _) = locals.getOrMakeLocal(s) genLoad(rhs, tk) @@ -92,7 +92,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* Generate code for primitive arithmetic operations. */ def genArithmeticOp(tree: Tree, code: Int): BType = tree match{ - case Apply(fun @ Select(larg, _), args) => + case ApplyBI(fun @ SelectBI(larg, _), args) => var resKind = tpeTK(larg) assert(resKind.isNumericType || (resKind == BOOL), @@ -148,7 +148,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* Generate primitive array operations. */ def genArrayOp(tree: Tree, code: Int, expectedType: BType): BType = tree match{ - case Apply(Select(arrayObj, _), args) => + case ApplyBI(SelectBI(arrayObj, _), args) => import ScalaPrimitivesOps._ val k = tpeTK(arrayObj) genLoad(arrayObj, k) @@ -179,13 +179,13 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genLoadIf(tree: If, expectedType: BType): BType = tree match{ - case If(condp, thenp, elsep) => + case IfBI(condp, thenp, elsep) => val success = new asm.Label val failure = new asm.Label val hasElse = !treeHelper(elsep).isEmpty && (elsep match { - case Literal(value) if constantHelper(value).tag == UnitTag => false + case LiteralBI(value) if constantHelper(value).tag == UnitTag => false case _ => true }) val postIf = if (hasElse) new asm.Label else failure @@ -210,7 +210,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genPrimitiveOp(tree: Apply, expectedType: BType): BType = tree match { - case Apply(fun @ Select(receiver, _), _) => + case ApplyBI(fun @ SelectBI(receiver, _), _) => val sym = treeHelper(tree).symbol val code = primitives.getPrimitive(tree, treeHelper(receiver).tpe) @@ -258,10 +258,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case ValDef(_, `nme_THIS`, _, _) => + case ValDefBI(_, `nme_THIS`, _, _) => debuglog("skipping trivial assign to _$this: " + tree) - case ValDef(_, _, _, rhs) => + case ValDefBI(_, _, _, rhs) => val sym = treeHelper(tree).symbol /* most of the time, !locals.contains(sym), unless the current activation of genLoad() is being called while duplicating a finalizer that contains this ValDef. */ @@ -276,34 +276,34 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } generatedType = UNIT - case t @ If(_, _, _) => + case t @ IfBI(_, _, _) => generatedType = genLoadIf(t, expectedType) - case t @ Labeled(_, _) => + case t @ LabeledBI(_, _) => generatedType = genLabeled(t) - case r @ Return(_) => + case r @ ReturnBI(_) => genReturn(r) generatedType = expectedType - case t @ WhileDo(_, _) => + case t @ WhileDoBI(_, _) => generatedType = genWhileDo(t) - case t @ Try(_, _, _) => + case t @ TryBI(_, _, _) => generatedType = genLoadTry(t) - case Throw(expr) => + case ThrowBI(expr) => generatedType = genThrow(expr) - case New(tpt) => + case NewBI(tpt) => abort(s"Unexpected New(${typeHelper(tpt).summaryString}/$tpt) reached GenBCode.\n" + " Call was genLoad" + ((tree, expectedType))) - case app @ Closure(env, call, functionalInterface) => + case app @ ClosureBI(env, call, functionalInterface) => val (fun, args) = call match { - case Apply(fun, args) => (fun, args) - case t @ Select(_, _) => (t, Nil) - case t @ Ident(_) => (t, Nil) + case ApplyBI(fun, args) => (fun, args) + case t @ SelectBI(_, _) => (t, Nil) + case t @ IdentBI(_) => (t, Nil) } if (!symHelper(treeHelper(fun).symbol).isStaticMember) { @@ -313,17 +313,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // but I was able to derrive it by reading // AbstractValidatingLambdaMetafactory.validateMetafactoryArgs - val Select(prefix, _) = fun + val SelectBI(prefix, _) = fun genLoad(prefix) } genLoadArguments(env, typeHelper(symHelper(treeHelper(fun).symbol).info).paramTypes map toTypeKind) generatedType = genInvokeDynamicLambda(NoSymbol, treeHelper(fun).symbol, env.size, functionalInterface) - case app @ Apply(_, _) => + case app @ ApplyBI(_, _) => generatedType = genApply(app, expectedType) - case This(qual) => + case ThisBI(qual) => val symIsModuleClass = symHelper(treeHelper(tree).symbol).isModuleClass assert(treeHelper(tree).symbol == claszSymbol || symIsModuleClass, s"Trying to access the this of another class: tree.symbol = ${treeHelper(tree).symbol}, class symbol = $claszSymbol compilation unit: $cunit") @@ -337,11 +337,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { else classBTypeFromSymbol(claszSymbol) } - case Select(Ident(`nme_EMPTY_PACKAGE_NAME`), module) => + case SelectBI(IdentBI(`nme_EMPTY_PACKAGE_NAME`), module) => assert(symHelper(treeHelper(tree).symbol).isModule, s"Selection of non-module from empty package: $tree sym: ${treeHelper(tree).symbol} at: ${treeHelper(tree).pos}") genLoadModule(tree) - case Select(qualifier, _) => + case SelectBI(qualifier, _) => val sym = treeHelper(tree).symbol generatedType = symInfoTK(sym) val qualSafeToElide = isQualifierSafeToElide(qualifier) @@ -361,7 +361,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { fieldLoad(sym, receiverClass) } - case t @ Ident(name) => + case t @ IdentBI(name) => val sym = treeHelper(tree).symbol val tk = symInfoTK(sym) generatedType = tk @@ -377,7 +377,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(t, generatedType) } - case Literal(value) => + case LiteralBI(value) => if (constantHelper(value).tag != UnitTag) (constantHelper(value).tag, expectedType) match { case (IntTag, LONG ) => bc.lconst(constantHelper(value).longValue); generatedType = LONG case (FloatTag, DOUBLE) => bc.dconst(constantHelper(value).doubleValue); generatedType = DOUBLE @@ -385,23 +385,23 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case _ => genConstant(value); generatedType = tpeTK(tree) } - case blck @ Block(stats, expr) => + case blck @ BlockBI(stats, expr) => if(stats.isEmpty) genLoad(expr, expectedType) else genBlock(blck, expectedType) - case Typed(Super(_, _), _) => genLoad(This(claszSymbol), expectedType) + case TypedBI(SuperBI(_, _), _) => genLoad(ThisBI(claszSymbol), expectedType) - case Typed(expr, _) => genLoad(expr, expectedType) + case TypedBI(expr, _) => genLoad(expr, expectedType) - case Assign(_, _) => + case AssignBI(_, _) => generatedType = UNIT genStat(tree) - case av @ ArrayValue(_, _) => + case av @ ArrayValueBI(_, _) => generatedType = genArrayValue(av) - case mtch @ Match(_, _) => + case mtch @ MatchBI(_, _) => generatedType = genMatch(mtch) case EmptyTree => if (expectedType != UNIT) { emitZeroOf(expectedType) } @@ -501,7 +501,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } private def genLabeled(tree: Labeled): BType = tree match { - case Labeled(bind, expr) => + case LabeledBI(bind, expr) => val resKind = tpeTK(tree) genLoad(expr, resKind) @@ -510,7 +510,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } private def genReturn(r: Return): Unit = r match { - case Return(expr, fromSym) => + case ReturnBI(expr, fromSym) => if (NoSymbol == fromSym) { // return from enclosing method @@ -552,7 +552,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } // end of genReturn() def genWhileDo(tree: WhileDo): BType = tree match{ - case WhileDo(cond, body) => + case WhileDoBI(cond, body) => val isInfinite = cond == EmptyTree @@ -565,7 +565,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { RT_NOTHING } else { val hasBody = cond match { - case Literal(value) if constantHelper(value).tag == UnitTag => false + case LiteralBI(value) if constantHelper(value).tag == UnitTag => false case _ => true } @@ -589,7 +589,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genTypeApply(t: TypeApply): BType = t match { - case TypeApply(fun@Select(obj, _), targs) => + case TypeApplyBI(fun@SelectBI(obj, _), targs) => val sym = treeHelper(fun).symbol val cast = sym match { @@ -658,17 +658,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var generatedType = expectedType lineNumber(app) app match { - case Apply(_, args) if isSyntheticArrayConstructor(treeHelper(app).symbol) => - val List(elemClaz, Literal(c: Constant), ArrayValue(_, dims)) = args + case ApplyBI(_, args) if isSyntheticArrayConstructor(treeHelper(app).symbol) => + val List(elemClaz, LiteralBI(c: Constant), ArrayValueBI(_, dims)) = args generatedType = toTypeKind(constantHelper(c).typeValue) mkArrayConstructorCall(generatedType.asArrayBType, app, dims) - case Apply(t :TypeApply, _) => + case ApplyBI(t :TypeApply, _) => generatedType = if (treeHelper(t).symbol ne Object_synchronized) genTypeApply(t) else genSynchronized(app, expectedType) - case Apply(fun @ Select(Super(_, _), _), args) => + case ApplyBI(fun @ SelectBI(SuperBI(_, _), _), args) => def initModule(): Unit = { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && @@ -700,7 +700,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // thought to return an instance of what they construct, // we have to 'simulate' it by DUPlicating the freshly created // instance (on JVM, methods return VOID). - case Apply(fun @ Select(New(tpt), `nme_CONSTRUCTOR`), args) => + case ApplyBI(fun @ SelectBI(NewBI(tpt), `nme_CONSTRUCTOR`), args) => val ctor = treeHelper(fun).symbol assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${symHelper(ctor).name}") @@ -722,21 +722,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { abort(s"Cannot instantiate $tpt of kind: $generatedType") } - case Apply(fun, List(expr)) if isBox(treeHelper(fun).symbol) => + case ApplyBI(fun, List(expr)) if isBox(treeHelper(fun).symbol) => val nativeKind = tpeTK(expr) genLoad(expr, nativeKind) val MethodNameAndType(mname, methodType) = asmBoxTo(nativeKind) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) generatedType = boxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.tpe.resultType) - case Apply(fun, List(expr)) if isUnbox(treeHelper(fun).symbol) => + case ApplyBI(fun, List(expr)) if isUnbox(treeHelper(fun).symbol) => genLoad(expr) val boxType = unboxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) generatedType = boxType val MethodNameAndType(mname, methodType) = asmUnboxTo(boxType) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) - case app @ Apply(fun, args) => + case app @ ApplyBI(fun, args) => val sym = treeHelper(fun).symbol if (isPrimitive(fun)) { // primitive method call @@ -750,7 +750,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (invokeStyle.hasInstance) genLoadQualifier(fun) genLoadArguments(args, paramTKs(app)) - val Select(qual, _) = fun // fun is a Select, also checked in genLoadQualifier + val SelectBI(qual, _) = fun // fun is a Select, also checked in genLoadQualifier if (isArrayClone(fun)) { // Special-case Array.clone, introduced in 36ef60e. The goal is to generate this call // as "[I.clone" instead of "java/lang/Object.clone". This is consistent with javac. @@ -792,8 +792,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } // end of genApply() private def genArrayValue(av: ArrayValue): BType = av match { - case ArrayValue(tpt, elems) => - val ArrayValue(tpt, elems) = av + case ArrayValueBI(tpt, elems) => + val ArrayValueBI(tpt, elems) = av lineNumber(av) genArray(elems, tpt) @@ -831,7 +831,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * On a second pass, we emit the switch blocks, one for each different target. */ private def genMatch(tree: Match): BType = tree match { - case Match(selector, cases) => + case MatchBI(selector, cases) => lineNumber(tree) genLoad(selector, INT) val generatedType = tpeTK(tree) @@ -842,20 +842,20 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var switchBlocks: List[(asm.Label, Tree)] = Nil // collect switch blocks and their keys, but don't emit yet any switch-block. - for (caze @ CaseDef(pat, guard, body) <- cases) { + for (caze @ CaseDefBI(pat, guard, body) <- cases) { assert(guard == EmptyTree, guard) val switchBlockPoint = new asm.Label switchBlocks ::= (switchBlockPoint, body) pat match { - case Literal(value) => + case LiteralBI(value) => flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint - case Ident(`nme_WILDCARD`) => + case IdentBI(`nme_WILDCARD`) => assert(default == null, s"multiple default targets in a Match node, at ${treeHelper(tree).pos}") default = switchBlockPoint - case Alternative(alts) => + case AlternativeBI(alts) => alts foreach { - case Literal(value) => + case LiteralBI(value) => flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint case _ => @@ -882,7 +882,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genBlock(tree: Block, expectedType: BType) = tree match { - case Block(stats, expr) => + case BlockBI(stats, expr) => val savedScope = varsInScope varsInScope = Nil @@ -978,7 +978,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadQualifier(tree: Tree): Unit = { lineNumber(tree) tree match { - case Select(qualifier, _) => genLoad(qualifier) + case SelectBI(qualifier, _) => genLoad(qualifier) case t: Ident => // dotty specific desugarIdent(t) match { case Some(sel) => genLoadQualifier(sel) @@ -1055,7 +1055,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) liftStringConcat(tree) match { // Optimization for expressions of the form "" + x. We can avoid the StringBuilder. - case List(Literal(Constant("")), arg) => + case List(LiteralBI(ConstantBI("")), arg) => genLoad(arg, ObjectReference) genCallMethod(String_valueOf, InvokeStyle.Static) @@ -1063,7 +1063,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { bc.genStartConcat for (elem <- concatenations) { val loadedElem = elem match { - case Apply(boxOp, value :: Nil) if isBox(treeHelper(boxOp).symbol) => + case ApplyBI(boxOp, value :: Nil) if isBox(treeHelper(boxOp).symbol) => // Eliminate boxing of primitive values. Boxing is introduced by erasure because // there's only a single synthetic `+` method "added" to the string class. value @@ -1156,7 +1156,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * It turns a chained call like "a".+("b").+("c") into a list of arguments. */ def liftStringConcat(tree: Tree): List[Tree] = tree match { - case tree @ Apply(fun @ Select(larg, method), rarg) => + case tree @ ApplyBI(fun @ SelectBI(larg, method), rarg) => if (isPrimitive(fun) && primitives.getPrimitive(tree, treeHelper(larg).tpe) == ScalaPrimitivesOps.CONCAT) liftStringConcat(larg) ::: rarg @@ -1259,11 +1259,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case tree @ Apply(fun, args) if isPrimitive(fun) => + case tree @ ApplyBI(fun, args) if isPrimitive(fun) => import ScalaPrimitivesOps.{ ZNOT, ZAND, ZOR, EQ } // lhs and rhs of test - lazy val Select(lhs, _) = fun + lazy val SelectBI(lhs, _) = fun val rhs = if (args.isEmpty) EmptyTree else args.head // args.isEmpty only for ZNOT def genZandOrZor(and: Boolean): Unit = { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 59de6866d07c..3509e531d672 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -406,7 +406,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def getExceptions(excs: List[Annotation]): List[String] = { - for (ThrownException(exc) <- excs.distinct) + for (ThrownExceptionBI(exc) <- excs.distinct) yield internalName(exc) } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 03112bc835e0..32a74769da0a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -63,7 +63,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* ---------------- idiomatic way to ask questions to typer ---------------- */ def paramTKs(app: Apply, take: Int = -1): List[BType] = app match { - case Apply(fun, _) => + case ApplyBI(fun, _) => val funSym = treeHelper(fun).symbol (typeHelper(symHelper(funSym).info).paramTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) } @@ -79,7 +79,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* ---------------- helper utils for generating classes and fields ---------------- */ def genPlainClass(cd: ClassDef) = cd match { - case ClassDef(_, _, _, impl) => + case ClassDefBI(_, _, _, impl) => assert(cnode == null, "GenBCode detected nested methods.") innerClassBufferASM.clear() @@ -445,7 +445,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // on entering a method def resetMethodBookkeeping(dd: DefDef) = dd match { - case DefDef(_, _, _, _, _, rhs) => + case DefDefBI(_, _, _, _, _, rhs) => locals.reset(isStaticMethod = symHelper(methSymbol).isStaticMember) jumpDest = immutable.Map.empty[ /* LabelDef */ Symbol, asm.Label ] @@ -466,11 +466,11 @@ trait BCodeSkelBuilder extends BCodeHelpers { tree match { case EmptyTree => () - case ValDef(mods, name, tpt, rhs) => () // fields are added in `genPlainClass()`, via `addClassFields()` + case ValDefBI(mods, name, tpt, rhs) => () // fields are added in `genPlainClass()`, via `addClassFields()` - case dd @ DefDef(_, _, _, _, _, _) => genDefDef(dd.asInstanceOf[DefDef]) + case dd @ DefDefBI(_, _, _, _, _, _) => genDefDef(dd.asInstanceOf[DefDef]) - case Template(_, _, body) => body foreach gen + case TemplateBI(_, _, body) => body foreach gen case _ => abort(s"Illegal tree in gen: $tree") } @@ -507,7 +507,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def genDefDef(dd: DefDef): Unit = dd match { - case DefDef(_, _, _, vparamss, _, rhs) => + case DefDefBI(_, _, _, vparamss, _, rhs) => // the only method whose implementation is not emitted: getClass() if (symHelper(treeHelper(dd).symbol).isGetClass) { return } assert(mnode == null, "GenBCode detected nested method.") @@ -552,7 +552,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { genLoad(rhs, returnType) rhs match { - case Return(_) | Block(_, Return(_)) | Throw(_) | Block(_, Throw(_)) => () + case ReturnBI(_) | BlockBI(_, ReturnBI(_)) | ThrowBI(_) | BlockBI(_, ThrowBI(_)) => () case EmptyTree => error(NoPosition, "Concrete method has no definition: " + dd + ( if (settings_debug) "(found: " + typeHelper(symHelper(symHelper(methSymbol).owner).info).decls.toList.mkString(", ") + ")" diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index 7780e916f2ed..26b7e1c6e324 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -21,7 +21,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { abstract class SyncAndTryBuilder(cunit: CompilationUnit) extends PlainBodyBuilder(cunit) { def genSynchronized(tree: Apply, expectedType: BType): BType = tree match { - case Apply(TypeApply(fun, _), args) => + case ApplyBI(TypeApplyBI(fun, _), args) => val monitor = locals.makeLocal(ObjectReference, "monitor", Object_Type, treeHelper(tree).pos) val monCleanup = new asm.Label @@ -170,15 +170,15 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { * */ def genLoadTry(tree: Try): BType = tree match { - case Try(block, catches, finalizer) => + case TryBI(block, catches, finalizer) => val kind = tpeTK(tree) val caseHandlers: List[EHClause] = - for (CaseDef(pat, _, caseBody) <- catches) yield { + for (CaseDefBI(pat, _, caseBody) <- catches) yield { pat match { - case Typed(Ident(`nme_WILDCARD`), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) - case Ident(`nme_WILDCARD`) => NamelessEH(ThrowableReference, caseBody) - case Bind(_, _) => BoundEH (treeHelper(pat).symbol, caseBody) + case TypedBI(IdentBI(`nme_WILDCARD`), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) + case IdentBI(`nme_WILDCARD`) => NamelessEH(ThrowableReference, caseBody) + case BindBI(_, _) => BoundEH (treeHelper(pat).symbol, caseBody) } } @@ -404,7 +404,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { /* Does this tree have a try-catch block? */ def mayCleanStack(tree: Tree): Boolean = treeHelper(tree) exists { t => t match { - case Try(_, _, _) => true + case TryBI(_, _, _) => true case _ => false } } diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index 70f76f15f8d8..6780c67c4528 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -176,35 +176,35 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { def positionHelper(a: Position): PositionHelper - val Assign: AssignDeconstructor - val Select: SelectDeconstructor - val Apply: ApplyDeconstructor - val If: IfDeconstructor - val ValDef: ValDefDeconstructor - val Throw: ThrowDeconstructor - val New: NewDeconstructor - val This: ThisDeconstructor - val Ident: IdentDeconstructor - val Try: TryDeconstructor - val Labeled: LabeledDeconstructor - val Return: ReturnDeconstructor - val WhileDo: WhileDoDeconstructor - val Literal: LiteralDeconstructor - val Typed: TypedDeconstrutor - val Super: SuperDeconstructor - val ArrayValue: ArrayValueDeconstructor - val Match: MatchDeconstructor - val Block: BlockDeconstructor - val TypeApply: TypeApplyDeconstructor - val CaseDef: CaseDeconstructor - val Alternative: AlternativeDeconstructor - val Constant: ConstantDeconstructor - val ThrownException: ThrownException - val DefDef: DefDefDeconstructor - val Template: TemplateDeconstructor - val Bind: BindDeconstructor - val ClassDef: ClassDefDeconstructor - val Closure: ClosureDeconstructor + val AssignBI: AssignDeconstructor + val SelectBI: SelectDeconstructor + val ApplyBI: ApplyDeconstructor + val IfBI: IfDeconstructor + val ValDefBI: ValDefDeconstructor + val ThrowBI: ThrowDeconstructor + val NewBI: NewDeconstructor + val ThisBI: ThisDeconstructor + val IdentBI: IdentDeconstructor + val TryBI: TryDeconstructor + val LabeledBI: LabeledDeconstructor + val ReturnBI: ReturnDeconstructor + val WhileDoBI: WhileDoDeconstructor + val LiteralBI: LiteralDeconstructor + val TypedBI: TypedDeconstrutor + val SuperBI: SuperDeconstructor + val ArrayValueBI: ArrayValueDeconstructor + val MatchBI: MatchDeconstructor + val BlockBI: BlockDeconstructor + val TypeApplyBI: TypeApplyDeconstructor + val CaseDefBI: CaseDeconstructor + val AlternativeBI: AlternativeDeconstructor + val ConstantBI: ConstantDeconstructor + val ThrownExceptionBI: ThrownException + val DefDefBI: DefDefDeconstructor + val TemplateBI: TemplateDeconstructor + val BindBI: BindDeconstructor + val ClassDefBI: ClassDefDeconstructor + val ClosureBI: ClosureDeconstructor abstract class DeconstructorCommon[T >: Null <: AnyRef] { var field: T = null @@ -755,11 +755,11 @@ abstract class BackendInterfaceDefinitions { self: BackendInterface => val String_valueOf: Symbol def isNull(t: Tree): Boolean = t match { - case Literal(Constant(null)) => true + case LiteralBI(ConstantBI(null)) => true case _ => false } def isLiteral(t: Tree): Boolean = t match { - case Literal(_) => true + case LiteralBI(_) => true case _ => false } def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((treeHelper(t).symbol ne null) && symHelper(treeHelper(t).symbol).isModule) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 4a153e8c733b..156f59546ee9 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -127,7 +127,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val FloatClass: Symbol = defn.FloatClass val DoubleClass: Symbol = defn.DoubleClass def isArrayClone(tree: Tree): Boolean = tree match { - case Select(qual, StdNames.nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true + case SelectBI(qual, StdNames.nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true case _ => false } @@ -982,12 +982,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def parents: List[Type] = tp.parents } - object Assign extends AssignDeconstructor { + object AssignBI extends AssignDeconstructor { def _1: Tree = field.lhs def _2: Tree = field.rhs } - object Select extends SelectDeconstructor { + object SelectBI extends SelectDeconstructor { var desugared: tpd.Select = null @@ -1013,18 +1013,18 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object Apply extends ApplyDeconstructor { + object ApplyBI extends ApplyDeconstructor { def _1: Tree = field.fun def _2: List[Tree] = field.args } - object If extends IfDeconstructor { + object IfBI extends IfDeconstructor { def _1: Tree = field.cond def _2: Tree = field.thenp def _3: Tree = field.elsep } - object ValDef extends ValDefDeconstructor { + object ValDefBI extends ValDefDeconstructor { def _1: Null = null def _2: Name = field.name def _3: Tree = field.tpt @@ -1032,14 +1032,14 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } // todo: this product1s should also eventually become name-based pattn matching - object Literal extends LiteralDeconstructor { + object LiteralBI extends LiteralDeconstructor { def get: Constant = field.const } - object Throw extends ThrowDeconstructor { + object ThrowBI extends ThrowDeconstructor { def get: Tree = field.args.head - override def unapply(s: Throw): Throw.type = { + override def unapply(s: Throw): ThrowBI.type = { if (s.fun.symbol eq defn.throwMethod) { field = s } else { @@ -1049,60 +1049,60 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object New extends NewDeconstructor { + object NewBI extends NewDeconstructor { def get: Type = field.tpt.tpe } - object This extends ThisDeconstructor { + object ThisBI extends ThisDeconstructor { def get: Name = field.qual.name def apply(s: Symbol): This = tpd.This(s.asClass) } - object Labeled extends LabeledDeconstructor { + object LabeledBI extends LabeledDeconstructor { def _1: Bind = field.bind def _2: Tree = field.expr } - object Return extends ReturnDeconstructor { + object ReturnBI extends ReturnDeconstructor { def _1: Tree = field.expr def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol } - object WhileDo extends WhileDoDeconstructor { + object WhileDoBI extends WhileDoDeconstructor { def _1: Tree = field.cond def _2: Tree = field.body } - object Ident extends IdentDeconstructor { + object IdentBI extends IdentDeconstructor { def get: Name = field.name } - object Alternative extends AlternativeDeconstructor { + object AlternativeBI extends AlternativeDeconstructor { def get: List[Tree] = field.trees } - object Constant extends ConstantDeconstructor { + object ConstantBI extends ConstantDeconstructor { def get: Any = field.value } - object ThrownException extends ThrownException { + object ThrownExceptionBI extends ThrownException { def unapply(a: Annotation): Option[Symbol] = None // todo } - object Try extends TryDeconstructor { + object TryBI extends TryDeconstructor { def _1: Tree = field.expr def _2: List[Tree] = field.cases def _3: Tree = field.finalizer } - object Typed extends TypedDeconstrutor { + object TypedBI extends TypedDeconstrutor { def _1: Tree = field.expr def _2: Tree = field.tpt } - object Super extends SuperDeconstructor { + object SuperBI extends SuperDeconstructor { def _1: Tree = field.qual def _2: Name = field.mix.name } - object ArrayValue extends ArrayValueDeconstructor { + object ArrayValueBI extends ArrayValueDeconstructor { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => @@ -1111,25 +1111,25 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } def _2: List[Tree] = field.elems } - object Match extends MatchDeconstructor { + object MatchBI extends MatchDeconstructor { def _1: Tree = field.selector def _2: List[Tree] = field.cases } - object Block extends BlockDeconstructor { + object BlockBI extends BlockDeconstructor { def _1: List[Tree] = field.stats def _2: Tree = field.expr } - object TypeApply extends TypeApplyDeconstructor { + object TypeApplyBI extends TypeApplyDeconstructor { def _1: Tree = field.fun def _2: List[Tree] = field.args } - object CaseDef extends CaseDeconstructor { + object CaseDefBI extends CaseDeconstructor { def _1: Tree = field.pat def _2: Tree = field.guard def _3: Tree = field.body } - object DefDef extends DefDefDeconstructor { + object DefDefBI extends DefDefDeconstructor { def _1: Null = null def _2: Name = field.name def _3: List[TypeDef] = field.tparams @@ -1138,7 +1138,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _6: Tree = field.rhs } - object Template extends TemplateDeconstructor { + object TemplateBI extends TemplateDeconstructor { def _1: List[Tree] = field.parents def _2: ValDef = field.self def _3: List[Tree] = @@ -1146,19 +1146,19 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma else field.constr :: field.body } - object Bind extends BindDeconstructor { + object BindBI extends BindDeconstructor { def _1: Name = field.name def _2: Tree = field.body } - object ClassDef extends ClassDefDeconstructor { + object ClassDefBI extends ClassDefDeconstructor { def _1: Null = null def _2: Name = field.name def _4: Template = field.rhs.asInstanceOf[Template] def _3: List[TypeDef] = Nil } - object Closure extends ClosureDeconstructor { + object ClosureBI extends ClosureDeconstructor { def _1: List[Tree] = field.env def _2: Tree = field.meth def _3: Symbol = { From 401146ab5b80aefb478426b1505f44b205e4e690 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 08:00:58 +0200 Subject: [PATCH 07/98] Use DottyBackendInterface directly --- compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 3a9e00522532..00c9586d1dd7 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -6,7 +6,7 @@ package jvm * This trait contains code shared between GenBCode and GenASM that depends on types defined in * the compiler cake (Global). */ -final class BCodeAsmCommon[I <: BackendInterface](val interface: I) { +final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { import interface._ /** diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala b/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala index 81e3284e1fff..785644e24159 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala @@ -16,7 +16,7 @@ import scala.tools.asm.tree.MethodInsnNode * */ trait BCodeIdiomatic { - val int: BackendInterface + val int: DottyBackendInterface final lazy val bTypes = new BTypesFromSymbols[int.type](int) import int._ diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index dac96bb24431..b59f7406ccff 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -17,7 +17,7 @@ import scala.annotation.threadUnsafe * of the core btypes. They are declared in BTypes as abstract members. Note that BTypes does * not have access to the compiler instance. */ -class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { +class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { import int._ val bCodeAsmCommon: BCodeAsmCommon[int.type ] = new BCodeAsmCommon(int) diff --git a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala index b67baf8e96d4..28ff01e6542b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala +++ b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala @@ -15,7 +15,7 @@ class FileConflictException(msg: String, val file: AbstractFile) extends IOExcep * files, jars, and disassembled/javap output. */ trait BytecodeWriters { - val int: BackendInterface + val int: DottyBackendInterface import int._ /** From ce744702625606d8cf219a5eaa62c9980d704291 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 08:06:14 +0200 Subject: [PATCH 08/98] Remove BackendIntefaceDefinitions --- compiler/src/dotty/tools/backend/jvm/BackendInterface.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index 6780c67c4528..80f4ce100bd9 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -11,7 +11,7 @@ import scala.tools.asm /* Interface to abstract over frontend inside backend. * Intended to be implemented by both scalac and dotc */ -abstract class BackendInterface extends BackendInterfaceDefinitions { +abstract class BackendInterface { type Flags = Long type Constant >: Null <: AnyRef @@ -637,7 +637,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { def dropModule(str: String): String -/* Returns a ScalaSignature annotation if it must be added to this class, none otherwise. + /* Returns a ScalaSignature annotation if it must be added to this class, none otherwise. * This annotation must be added to the class' annotations list when generating them. * * Depending on whether the returned option is defined, it adds to `jclass` one of: @@ -659,9 +659,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions { * must-single-thread */ def getAnnotPickle(jclassName: String, sym: Symbol): Option[Annotation] -} -abstract class BackendInterfaceDefinitions { self: BackendInterface => val nme_valueOf: Name /* magic instances */ From 9ae52fd8107082ad3694a71d777f5f41b3fe6e6f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 08:15:41 +0200 Subject: [PATCH 09/98] Remove direct references to BackendInterface --- compiler/src/dotty/tools/backend/jvm/BTypes.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BackendInterface.scala | 2 +- compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala | 4 ++-- .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypes.scala b/compiler/src/dotty/tools/backend/jvm/BTypes.scala index 998981bfbec1..7d19b57a7bd6 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypes.scala @@ -14,7 +14,7 @@ import scala.tools.asm */ abstract class BTypes { - val int: BackendInterface + val int: DottyBackendInterface import int._ /** * A map from internal names to ClassBTypes. Every ClassBType is added to this map on its diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index 80f4ce100bd9..bec627eb654a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -11,7 +11,7 @@ import scala.tools.asm /* Interface to abstract over frontend inside backend. * Intended to be implemented by both scalac and dotc */ -abstract class BackendInterface { +abstract class BackendInterfaceOld { type Flags = Long type Constant >: Null <: AnyRef diff --git a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala index cd04f6f7d1c8..6d3ea81deeeb 100644 --- a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala @@ -27,7 +27,7 @@ import scala.annotation.switch * added when the ClassBTypes are created. The per run cache removes them, so they would be missing * in the second run. */ -class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: BackendInterface]](val bTypes: BTFS) { +class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTypes: BTFS) { import bTypes._ import int._ @@ -199,7 +199,7 @@ trait CoreBTypesProxyGlobalIndependent[BTS <: BTypes] { /** * See comment in class [[CoreBTypes]]. */ -final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: BackendInterface]](val bTypes: BTFS) extends CoreBTypesProxyGlobalIndependent[BTFS] { +final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTypes: BTFS) extends CoreBTypesProxyGlobalIndependent[BTFS] { import bTypes._ import bTypes.int._ diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 156f59546ee9..e4db04079703 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -31,7 +31,7 @@ import StdNames.{nme, str} import NameKinds.{DefaultGetterName, ExpandedName} import Names.TermName -class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit ctx: Context) extends BackendInterface{ +class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit ctx: Context) extends BackendInterfaceOld{ 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. From a0bec05c8e5f2ff32e8d5a8bd22bdd416aa5624f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 08:23:42 +0200 Subject: [PATCH 10/98] Remove BackendInterface --- .../tools/backend/jvm/BackendInterface.scala | 791 ------------------ .../backend/jvm/DottyBackendInterface.scala | 513 +++++++++++- 2 files changed, 505 insertions(+), 799 deletions(-) delete mode 100644 compiler/src/dotty/tools/backend/jvm/BackendInterface.scala diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala deleted file mode 100644 index bec627eb654a..000000000000 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ /dev/null @@ -1,791 +0,0 @@ -package dotty.tools -package backend -package jvm - -import scala.collection.generic.Clearable -import scala.reflect.ClassTag -import dotty.tools.io.AbstractFile -import scala.language.implicitConversions -import scala.tools.asm - -/* Interface to abstract over frontend inside backend. - * Intended to be implemented by both scalac and dotc - */ -abstract class BackendInterfaceOld { - type Flags = Long - - type Constant >: Null <: AnyRef - type Symbol >: Null <: AnyRef - type Type >: Null <: AnyRef - type Annotation >: Null <: AnyRef - type Tree >: Null <: AnyRef - type TypeDef >: Null <: Tree - type Apply >: Null <: Tree - type Select >: Null <: Tree - type TypeApply >: Null <: Tree - type ClassDef >: Null <: Tree - type Try >: Null <: Tree - type Assign >: Null <: Tree - type Ident >: Null <: Tree - type If >: Null <: Tree - type ValDef >: Null <: Tree - type Throw >: Null <: Tree - type Labeled >: Null <: Tree - type Return >: Null <: Tree - type WhileDo >: Null <: Tree - type Literal >: Null <: Tree - type Block >: Null <: Tree - type Typed >: Null <: Tree - type ArrayValue >: Null <: Tree - type Match >: Null <: Tree - type This >: Null <: Tree - type CaseDef >: Null <: Tree - type Alternative >: Null <: Tree - type DefDef >: Null <: Tree - type Template >: Null <: Tree - type Name >: Null <: AnyRef - type Position - type CompilationUnit <: AnyRef - type Bind >: Null <: Tree - type New >: Null <: Tree - type Super >: Null <: Tree - type Closure >: Null <: Tree - - - implicit val TypeDefTag: ClassTag[TypeDef] - implicit val ApplyTag: ClassTag[Apply] - implicit val SelectTag: ClassTag[Select] - - implicit val TypeApplyTag: ClassTag[TypeApply] - implicit val ClassDefTag: ClassTag[ClassDef] - implicit val TryTag: ClassTag[Try] - implicit val AssignTag: ClassTag[Assign] - implicit val IdentTag: ClassTag[Ident] - implicit val IfTag: ClassTag[If] - implicit val ValDefTag: ClassTag[ValDef] - implicit val ThrowTag: ClassTag[Throw] - implicit val LabeledTag: ClassTag[Labeled] - implicit val ReturnTag: ClassTag[Return] - implicit val WhileDoTag: ClassTag[WhileDo] - implicit val LiteralTag: ClassTag[Literal] - implicit val BlockTag: ClassTag[Block] - implicit val TypedTag: ClassTag[Typed] - implicit val ArrayValueTag: ClassTag[ArrayValue] - implicit val MatchTag: ClassTag[Match] - implicit val CaseDefTag: ClassTag[CaseDef] - implicit val ThisTag: ClassTag[This] - implicit val AlternativeTag: ClassTag[Alternative] - implicit val DefDefTag: ClassTag[DefDef] - implicit val NameTag: ClassTag[Name] - implicit val TemplateTag: ClassTag[Template] - implicit val BindTag: ClassTag[Bind] - implicit val NewTag: ClassTag[New] - implicit val SuperTag: ClassTag[Super] - implicit val ConstantClassTag: ClassTag[Constant] - implicit val ClosureTag: ClassTag[Closure] - - type ConstantTag = Int - - val UnitTag: ConstantTag - val IntTag: ConstantTag - val FloatTag: ConstantTag - val NullTag: ConstantTag - val BooleanTag: ConstantTag - val ByteTag: ConstantTag - val ShortTag: ConstantTag - val CharTag: ConstantTag - val DoubleTag: ConstantTag - val LongTag: ConstantTag - val StringTag: ConstantTag - val ClazzTag: ConstantTag - val EnumTag: ConstantTag - - val primitives: Primitives - - - val nme_This: Name - val nme_EMPTY_PACKAGE_NAME: Name - val nme_CONSTRUCTOR: Name - val nme_WILDCARD: Name - val nme_THIS: Name - val nme_PACKAGE: Name - val nme_EQEQ_LOCAL_VAR: Name - val nme_apply: Name - - /* methods used to box&unbox primitives ?and value classes? */ - def boxMethods: Map[Symbol, Symbol] // (class, method) - def unboxMethods: Map[Symbol, Symbol] - - /* dotty specific, see dotty.runtime.Arrays */ - def isSyntheticArrayConstructor(s: Symbol) = false - - /* - * Implementation of those methods is very specific to how annotations are represented - * representations for Dotc and Scalac are to different to abstract over them - */ - def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers)(innerClasesStore: bcodeStore.BCInnerClassGen): Unit - def emitAnnotations(mw: asm.MethodVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers)(innerClasesStore: bcodeStore.BCInnerClassGen): Unit - def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers)(innerClasesStore: bcodeStore.BCInnerClassGen): Unit - def emitParamAnnotations(jmethod: asm.MethodVisitor, pannotss: List[List[Annotation]], bcodeStore: BCodeHelpers)(innerClasesStore: bcodeStore.BCInnerClassGen): Unit - - /* means of getting class symbols from compiler */ - def requiredClass[T: ClassTag]: Symbol - def requiredModule[T: ClassTag]: Symbol - def getRequiredClass(fullname: String): Symbol - def getClassIfDefined(fullname: String): Symbol - - def isQualifierSafeToElide(qual: Tree): Boolean - def desugarIdent(i: Ident): Option[Select] - - /* various configuration options used by backend */ - def emitAsmp: Option[String] - def dumpClasses: Option[String] - def noForwarders: Boolean - def debuglevel: Int - def settings_debug: Boolean - def targetPlatform: String - def sourceFileFor(cu: CompilationUnit): String - def informProgress(msg: String): Unit - - /* backend actually uses free names to generate stuff. This should NOT mangled */ - def newTermName(prefix: String): Name - - def getGenericSignature(sym: Symbol, owner:Symbol): String - def getStaticForwarderGenericSignature(sym: Symbol, moduleClass: Symbol): String - - def isBox(sym: Symbol): Boolean - def isUnbox(sym: Symbol): Boolean - def isMaybeBoxed(sym: Symbol): Boolean - - /** Whether an annotation should be emitted as a Java annotation - * .initialize: if 'annot' is read from pickle, atp might be un-initialized - */ - def shouldEmitAnnotation(annot: Annotation): Boolean - - def isRuntimeVisible(annot: Annotation): Boolean - - def getSingleOutput: Option[AbstractFile] - - def symHelper(sym: Symbol): SymbolHelper - def typeHelper(tp: Type): TypeHelper - def nameHelper(n: Name): NameHelper - def annotHelper(a: Annotation): AnnotationHelper - def treeHelper(a: Tree): TreeHelper - - def constantHelper(a: Constant): ConstantHelper - def positionHelper(a: Position): PositionHelper - - - val AssignBI: AssignDeconstructor - val SelectBI: SelectDeconstructor - val ApplyBI: ApplyDeconstructor - val IfBI: IfDeconstructor - val ValDefBI: ValDefDeconstructor - val ThrowBI: ThrowDeconstructor - val NewBI: NewDeconstructor - val ThisBI: ThisDeconstructor - val IdentBI: IdentDeconstructor - val TryBI: TryDeconstructor - val LabeledBI: LabeledDeconstructor - val ReturnBI: ReturnDeconstructor - val WhileDoBI: WhileDoDeconstructor - val LiteralBI: LiteralDeconstructor - val TypedBI: TypedDeconstrutor - val SuperBI: SuperDeconstructor - val ArrayValueBI: ArrayValueDeconstructor - val MatchBI: MatchDeconstructor - val BlockBI: BlockDeconstructor - val TypeApplyBI: TypeApplyDeconstructor - val CaseDefBI: CaseDeconstructor - val AlternativeBI: AlternativeDeconstructor - val ConstantBI: ConstantDeconstructor - val ThrownExceptionBI: ThrownException - val DefDefBI: DefDefDeconstructor - val TemplateBI: TemplateDeconstructor - val BindBI: BindDeconstructor - val ClassDefBI: ClassDefDeconstructor - val ClosureBI: ClosureDeconstructor - - abstract class DeconstructorCommon[T >: Null <: AnyRef] { - var field: T = null - def get: this.type = this - def isEmpty: Boolean = field eq null - def isDefined = !isEmpty - def unapply(s: T): this.type ={ - field = s - this - } - } - - abstract class Deconstructor1Common[T >: Null <: AnyRef, R]{ - var field: T = _ - def get: R - def isEmpty: Boolean = field eq null - def isDefined = !isEmpty - def unapply(s: T): this.type ={ - field = s - this - } - } - - abstract class ClassDefDeconstructor extends DeconstructorCommon[ClassDef] { - def _1: Null - def _2: Name - def _3: List[TypeDef] - def _4: Template - } - - abstract class BindDeconstructor extends DeconstructorCommon[Bind]{ - def _1: Name - def _2: Tree - } - - abstract class TemplateDeconstructor extends DeconstructorCommon[Template]{ - def _1: List[Tree] - def _2: ValDef - def _3: List[Tree] - } - - abstract class DefDefDeconstructor extends DeconstructorCommon[DefDef]{ - def _1: Null - def _2: Name - def _3: List[TypeDef] - def _4: List[List[ValDef]] - def _5: Tree - def _6: Tree - } - - abstract class ClosureDeconstructor extends DeconstructorCommon[Closure]{ - def _1: List[Tree] // environment - def _2: Tree // meth - def _3: Symbol // functionalInterface - } - - abstract class ThisDeconstructor extends Deconstructor1Common[This, Name]{ - def apply(s: Symbol): Tree - } - - abstract class IdentDeconstructor extends Deconstructor1Common[Ident, Name]{ - } - - abstract class LabeledDeconstructor extends DeconstructorCommon[Labeled]{ - def _1: Bind // bind - def _2: Tree // expr - } - - abstract class ReturnDeconstructor extends DeconstructorCommon[Return]{ - def _1: Tree // expr - def _2: Symbol // target label, NoSymbol if return to method - } - - abstract class WhileDoDeconstructor extends DeconstructorCommon[WhileDo]{ - def _1: Tree // cond - def _2: Tree // body - } - - abstract class ThrownException { - def unapply(a: Annotation): Option[Symbol] - } - - abstract class ThrowDeconstructor extends Deconstructor1Common[Throw, Tree]{ - } - - abstract class ConstantDeconstructor extends Deconstructor1Common[Constant, Any]{ - } - - abstract class NewDeconstructor extends Deconstructor1Common[New, Type]{ - } - - abstract class AlternativeDeconstructor extends Deconstructor1Common[Alternative, List[Tree]]{ - } - - abstract class BlockDeconstructor extends DeconstructorCommon[Block]{ - def _1: List[Tree] - def _2: Tree - } - - abstract class CaseDeconstructor extends DeconstructorCommon[CaseDef]{ - def _1: Tree - def _2: Tree - def _3: Tree - } - - abstract class MatchDeconstructor extends DeconstructorCommon[Match]{ - def _1: Tree - def _2: List[Tree] - } - - abstract class LiteralDeconstructor extends Deconstructor1Common[Literal, Constant]{ - } - - abstract class AssignDeconstructor extends DeconstructorCommon[Assign]{ - def _1: Tree - def _2: Tree - } - - abstract class SelectDeconstructor extends DeconstructorCommon[Select]{ - def _1: Tree - def _2: Name - } - - abstract class ApplyDeconstructor extends DeconstructorCommon[Apply] { - def _1: Tree - def _2: List[Tree] - } - - abstract class IfDeconstructor extends DeconstructorCommon[If]{ - def _1: Tree - def _2: Tree - def _3: Tree - } - - abstract class ValDefDeconstructor extends DeconstructorCommon[ValDef]{ - def _1: Null - def _2: Name - def _3: Tree - def _4: Tree - } - - - abstract class TryDeconstructor extends DeconstructorCommon[Try]{ - def _1: Tree - def _2: List[Tree] - def _3: Tree - } - - abstract class TypedDeconstrutor extends DeconstructorCommon[Typed]{ - def _1: Tree - def _2: Tree - } - - abstract class SuperDeconstructor extends DeconstructorCommon[Super]{ - def _1: Tree - def _2: Name - } - - abstract class ArrayValueDeconstructor extends DeconstructorCommon[ArrayValue]{ - def _1: Type - def _2: List[Tree] - } - - abstract class TypeApplyDeconstructor extends DeconstructorCommon[TypeApply]{ - def _1: Tree - def _2: List[Tree] - } - - abstract class PositionHelper { - def isDefined: Boolean - def finalPosition: Position - def line: Int - } - - abstract class ConstantHelper { - def tag: ConstantTag - def longValue: Long - def doubleValue: Double - def charValue: Char - def stringValue: String - def byteValue: Byte - def booleanValue: Boolean - def shortValue: Short - def intValue: Int - def value: Any - def floatValue: Float - def typeValue: Type - def symbolValue: Symbol - } - - abstract class TreeHelper{ - def symbol: Symbol - def tpe: Type - def isEmpty: Boolean - def pos: Position - def exists(pred: Tree => Boolean): Boolean - } - - abstract class SymbolHelper { - def exists: Boolean - - // names - def showFullName: String - def javaSimpleName: String - def javaBinaryName: String - def javaClassName: String - def name: Name - def rawname: String - - // types - def info: Type - def tpe: Type // todo whats the differentce between tpe and info? - def thisType: Type - - /** Does this symbol actually correspond to an interface that will be emitted? - * In the backend, this should be preferred over `isInterface` because it - * also returns true for the symbols of the fake companion objects we - * create for Java-defined classes as well as for Java annotations - * which we represent as classes. - */ - final def isEmittedInterface: Boolean = isInterface || - isJavaDefined && (isAnnotation || isModuleClass && symHelper(companionClass).isInterface) - - // tests - def isClass: Boolean - def isType: Boolean - def isAnonymousClass: Boolean - def isConstructor: Boolean - def isExpanded: Boolean - def isAnonymousFunction: Boolean - def isMethod: Boolean - def isPublic: Boolean - def isSynthetic: Boolean - def isPackageClass: Boolean - def isModuleClass: Boolean - def isModule: Boolean - def isStrictFP: Boolean - def isLabel: Boolean - def hasPackageFlag: Boolean - def isInterface: Boolean - def isGetter: Boolean - def isSetter: Boolean - def isGetClass: Boolean - def isJavaDefined: Boolean - def isDeferred: Boolean - def isPrivate: Boolean - def getsJavaPrivateFlag: Boolean - def isFinal: Boolean - def getsJavaFinalFlag: Boolean - def isScalaStatic: Boolean - def isStaticMember: Boolean - def isBottomClass: Boolean - def isBridge: Boolean - def isArtifact: Boolean - def hasEnumFlag: Boolean - def hasAccessBoundary: Boolean - def isVarargsMethod: Boolean - def isDeprecated: Boolean - def isMutable: Boolean - def hasAbstractFlag: Boolean - def hasModuleFlag: Boolean - def isSynchronized: Boolean - def isNonBottomSubClass(sym: Symbol): Boolean - def hasAnnotation(sym: Symbol): Boolean - def shouldEmitForwarders: Boolean - def isJavaDefaultMethod: Boolean - def isClassConstructor: Boolean - def isAnnotation: Boolean - def isSerializable: Boolean - def isEnum: Boolean - - /** - * True for module classes of modules that are top-level or owned only by objects. Module classes - * for such objects will get a MODULE$ flag and a corresponding static initializer. - */ - def isStaticModuleClass: Boolean - - def isStaticConstructor: Boolean - - - // navigation - def owner: Symbol - def rawowner: Symbol // todo ??? - def originalOwner: Symbol - def parentSymbols: List[Symbol] - def superClass: Symbol - def enclClass: Symbol - def linkedClassOfClass: Symbol - def linkedClass: Symbol - def companionClass: Symbol - def companionModule: Symbol - def companionSymbol: Symbol - def moduleClass: Symbol - def enclosingClassSym: Symbol - def originalLexicallyEnclosingClass: Symbol - def nextOverriddenSymbol: Symbol - def allOverriddenSymbols: List[Symbol] - - - // members - def primaryConstructor: Symbol - def nestedClasses: List[Symbol] - def memberClasses: List[Symbol] - def annotations: List[Annotation] - def companionModuleMembers: List[Symbol] - def fieldSymbols: List[Symbol] - def methodSymbols: List[Symbol] - def serialVUID: Option[Long] - - - def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol - - def getter(clz: Symbol): Symbol - def setter(clz: Symbol): Symbol - - def moduleSuffix: String - def outputDirectory: AbstractFile - def pos: Position - - def throwsAnnotations: List[Symbol] - - /** - * All interfaces implemented by a class, except for those inherited through the superclass. - * - */ - def superInterfaces: List[Symbol] - - /** - * True for module classes of package level objects. The backend will generate a mirror class for - * such objects. - */ - def isTopLevelModuleClass: Boolean - - /** - * This is basically a re-implementation of sym.isStaticOwner, but using the originalOwner chain. - * - * The problem is that we are interested in a source-level property. Various phases changed the - * symbol's properties in the meantime, mostly lambdalift modified (destructively) the owner. - * Therefore, `sym.isStatic` is not what we want. For example, in - * object T { def f { object U } } - * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. - */ - def isOriginallyStaticOwner: Boolean = - isPackageClass || isModuleClass && symHelper(symHelper(originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner - - def samMethod(): Symbol - - /** Is this the symbol of one of the `scala.Function*` class ? - * Note that this will return false for subclasses of these classes. - */ - def isFunctionClass: Boolean - } - - abstract class TypeHelper { - def <:<(other: Type): Boolean - def =:=(other: Type): Boolean - def paramTypes: List[Type] - def params: List[Symbol] - def resultType: Type - def memberInfo(s: Symbol): Type - - /** The members of this type that have all of `required` flags but none of `excluded` flags set. - * The members are sorted by name and signature to guarantee a stable ordering. - */ - def sortedMembersBasedOnFlags(required: Flags, excluded: Flags): List[Symbol] - def members: List[Symbol] - def decl(name: Name): Symbol - def decls: List[Symbol] - def underlying: Type - def parents: List[Type] - def summaryString: String - def typeSymbol: Symbol - def member(string: Name): Symbol - /** - * This method returns the BType for a type reference, for example a parameter type. - * - * If the result is a ClassBType for a nested class, it is added to the innerClassBufferASM. - * - * If `t` references a class, toTypeKind ensures that the class is not an implementation class. - * See also comment on getClassBTypeAndRegisterInnerClass, which is invoked for implementation - * classes. - */ - def toTypeKind(ctx: BCodeHelpers)(storage: ctx.BCInnerClassGen): ctx.bTypes.BType - - def isFinalType: Boolean - } - - abstract class Primitives { - def getPrimitive(app: Apply, receiver: Type): Int - def isPrimitive(fun: Tree): Boolean - def getPrimitive(sym: Symbol): Int - } - - abstract class NameHelper { - def isTypeName: Boolean - def isTermName: Boolean - def startsWith(s: String): Boolean - def mangledString: String - } - - abstract class AnnotationHelper{ - def atp: Type - def symbol: Symbol - def args: List[Tree] - def assocs: List[(Name, /* ClassfileAnnotArg*/ Object)] - } - - def debuglog(msg: => String): Unit - def log(msg: => String): Unit - def error(pos: Position, msg: String): Unit // reporter.error - def warning(pos: Position, msg: String): Unit // reporter.warning - def abort(msg: String): Nothing - - val ExcludedForwarderFlags: Flags - val Flag_METHOD: Flags - val Flag_SYNTHETIC: Flags - - abstract class Caches { - def recordCache[T <: Clearable](cache: T): T - def newWeakMap[K, V](): collection.mutable.WeakHashMap[K, V] - def newMap[K, V](): collection.mutable.HashMap[K, V] - def newSet[K](): collection.mutable.Set[K] - def newWeakSet[K >: Null <: AnyRef](): dotty.tools.dotc.util.WeakHashSet[K] - def newAnyRefMap[K <: AnyRef, V](): collection.mutable.AnyRefMap[K, V] - } - - def perRunCaches: Caches - - def MODULE_INSTANCE_FIELD: String - - def dropModule(str: String): String - - /* Returns a ScalaSignature annotation if it must be added to this class, none otherwise. - * This annotation must be added to the class' annotations list when generating them. - * - * Depending on whether the returned option is defined, it adds to `jclass` one of: - * (a) the ScalaSig marker attribute - * (indicating that a scala-signature-annotation aka pickle is present in this class); or - * (b) the Scala marker attribute - * (indicating that a scala-signature-annotation aka pickle is to be found in another file). - * - * - * @param jclassName The class file that is being readied. - * @param sym The symbol for which the signature has been entered in the symData map. - * This is different than the symbol - * that is being generated in the case of a mirror class. - * @return An option that is: - * - defined and contains an AnnotationInfo of the ScalaSignature type, - * instantiated with the pickle signature for sym. - * - empty if the jclass/sym pair must not contain a pickle. - * - * must-single-thread - */ - def getAnnotPickle(jclassName: String, sym: Symbol): Option[Annotation] - - val nme_valueOf: Name - - /* magic instances */ - val NoPosition: Position - val NoSymbol: Symbol - val EmptyTree: Tree - val NothingClass: Symbol - val NullClass: Symbol - val ObjectClass: Symbol - val Object_isInstanceOf: Symbol - val Object_asInstanceOf: Symbol - val Object_synchronized: Symbol - val Object_equals: Symbol - val ArrayClass: Symbol - - val UnitClass: Symbol - val BooleanClass: Symbol - val CharClass: Symbol - val ShortClass: Symbol - val ClassClass: Symbol - val ByteClass: Symbol - val IntClass: Symbol - val LongClass: Symbol - val FloatClass: Symbol - val DoubleClass: Symbol - - // Class symbols used in backend. - // Vals because they are to frequent in scala programs so that they are already loaded by backend - - lazy val NativeAttr: Symbol = requiredClass[scala.native] - lazy val TransientAttr = requiredClass[scala.transient] - lazy val VolatileAttr = requiredClass[scala.volatile] - lazy val LambdaMetaFactory = getClassIfDefined("java.lang.invoke.LambdaMetafactory") - lazy val MethodHandle = getClassIfDefined("java.lang.invoke.MethodHandle") - - val ScalaATTRName: String = "Scala" - val ScalaSignatureATTRName: String = "ScalaSig" - - def doLabmdasFollowJVMMetafactoryOrder: Boolean = true - - val BoxedBooleanClass: Symbol = requiredClass[java.lang.Boolean] - val BoxedByteClass: Symbol = requiredClass[java.lang.Byte] - val BoxedShortClass: Symbol = requiredClass[java.lang.Short] - val BoxedCharacterClass: Symbol = requiredClass[java.lang.Character] - val BoxedIntClass: Symbol = requiredClass[java.lang.Integer] - val BoxedLongClass: Symbol = requiredClass[java.lang.Long] - val BoxedFloatClass: Symbol = requiredClass[java.lang.Float] - val BoxedDoubleClass: Symbol = requiredClass[java.lang.Double] - val StringClass: Symbol = requiredClass[java.lang.String] - val JavaStringBuilderClass: Symbol = requiredClass[java.lang.StringBuilder] - val JavaStringBufferClass: Symbol = requiredClass[java.lang.StringBuffer] - val JavaCharSequenceClass: Symbol = requiredClass[java.lang.CharSequence] - val ThrowableClass: Symbol = requiredClass[java.lang.Throwable] - val JavaCloneableClass: Symbol = requiredClass[java.lang.Cloneable] - val NullPointerExceptionClass: Symbol = requiredClass[java.lang.NullPointerException] - val JavaSerializableClass: Symbol = requiredClass[java.io.Serializable] - val SerializableClass: Symbol = requiredClass[scala.Serializable] - val ClassCastExceptionClass: Symbol = requiredClass[java.lang.ClassCastException] - val IllegalArgExceptionClass: Symbol = requiredClass[java.lang.IllegalArgumentException] - val SerializedLambdaClass: Symbol = requiredClass[java.lang.invoke.SerializedLambda] - - val ClassfileAnnotationClass: Symbol = requiredClass[scala.annotation.ClassfileAnnotation] - val BoxedNumberClass: Symbol = requiredClass[java.lang.Number] - val ThrowsClass: Symbol = requiredClass[scala.throws[_]] - - // Module symbols used in backend - val StringModule: Symbol = symHelper(StringClass).linkedClassOfClass - val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type] - - - // types used in backend - - val Object_Type: Type - val Throwable_Type: Type - // methods used in backend - - def isArrayClone(fun: Tree): Boolean - val hashMethodSym: Symbol - val externalEqualsNumNum: Symbol - val externalEqualsNumChar: Symbol - val externalEqualsNumObject: Symbol - val externalEquals: Symbol - - val MaxFunctionArity: Int - val FunctionClass: Array[Symbol] - val AbstractFunctionClass: Array[Symbol] - val PartialFunctionClass: Symbol - val AbstractPartialFunctionClass: Symbol - - /* The Object => String overload. */ - val String_valueOf: Symbol - - def isNull(t: Tree): Boolean = t match { - case LiteralBI(ConstantBI(null)) => true - case _ => false - } - def isLiteral(t: Tree): Boolean = t match { - case LiteralBI(_) => true - case _ => false - } - def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((treeHelper(t).symbol ne null) && symHelper(treeHelper(t).symbol).isModule) - def ifOneIsNull(l: Tree, r: Tree): Tree = if (isNull(l)) r else if (isNull(r)) l else null - - private val primitiveCompilationUnits = Set( - "Unit.scala", - "Boolean.scala", - "Char.scala", - "Byte.scala", - "Short.scala", - "Int.scala", - "Float.scala", - "Long.scala", - "Double.scala" - ) - - def currentUnit: CompilationUnit - - /** - * True if the current compilation unit is of a primitive class (scala.Boolean et al). - * Used only in assertions. - */ - def isCompilingPrimitive = { - primitiveCompilationUnits(sourceFileFor(currentUnit)) - } - - def isCompilingArray = { - sourceFileFor(currentUnit) == "Array.scala" - } -} diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index e4db04079703..88cb57660de0 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -31,11 +31,14 @@ import StdNames.{nme, str} import NameKinds.{DefaultGetterName, ExpandedName} import Names.TermName -class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit ctx: Context) extends BackendInterfaceOld{ +class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit ctx: Context) { 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. + type Flags = Long + type ConstantTag = Int + type Symbol = Symbols.Symbol type Type = Types.Type type Tree = tpd.Tree @@ -101,8 +104,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val nme_EQEQ_LOCAL_VAR: Name = StdNames.nme.EQEQ_LOCAL_VAR // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. - @threadUnsafe override lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") - @threadUnsafe override lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") + @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") + @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") val nme_valueOf: Name = StdNames.nme.valueOf val nme_apply: TermName = StdNames.nme.apply @@ -156,7 +159,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def unboxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap - override def isSyntheticArrayConstructor(s: Symbol): Boolean = { + def isSyntheticArrayConstructor(s: Symbol): Boolean = { s eq defn.newArrayMethod } @@ -306,7 +309,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - override def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) + def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { for(annot <- annotations; if shouldEmitAnnotation(annot)) { val typ = annot.atp @@ -323,7 +326,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma av.visitEnd() } - override def emitAnnotations(mw: asm.MethodVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) + def emitAnnotations(mw: asm.MethodVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { for(annot <- annotations; if shouldEmitAnnotation(annot)) { val typ = annot.atp @@ -333,7 +336,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - override def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) + def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { for(annot <- annotations; if shouldEmitAnnotation(annot)) { val typ = annot.atp @@ -343,7 +346,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - override def emitParamAnnotations(jmethod: asm.MethodVisitor, pannotss: List[List[Annotation]], bcodeStore: BCodeHelpers) + def emitParamAnnotations(jmethod: asm.MethodVisitor, pannotss: List[List[Annotation]], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { val annotationss = pannotss map (_ filter shouldEmitAnnotation) if (annotationss forall (_.isEmpty)) return @@ -1175,6 +1178,500 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } def currentUnit: CompilationUnit = ctx.compilationUnit + + + + abstract class DeconstructorCommon[T >: Null <: AnyRef] { + var field: T = null + def get: this.type = this + def isEmpty: Boolean = field eq null + def isDefined = !isEmpty + def unapply(s: T): this.type ={ + field = s + this + } + } + + abstract class Deconstructor1Common[T >: Null <: AnyRef, R]{ + var field: T = _ + def get: R + def isEmpty: Boolean = field eq null + def isDefined = !isEmpty + def unapply(s: T): this.type ={ + field = s + this + } + } + + abstract class ClassDefDeconstructor extends DeconstructorCommon[ClassDef] { + def _1: Null + def _2: Name + def _3: List[TypeDef] + def _4: Template + } + + abstract class BindDeconstructor extends DeconstructorCommon[Bind]{ + def _1: Name + def _2: Tree + } + + abstract class TemplateDeconstructor extends DeconstructorCommon[Template]{ + def _1: List[Tree] + def _2: ValDef + def _3: List[Tree] + } + + abstract class DefDefDeconstructor extends DeconstructorCommon[DefDef]{ + def _1: Null + def _2: Name + def _3: List[TypeDef] + def _4: List[List[ValDef]] + def _5: Tree + def _6: Tree + } + + abstract class ClosureDeconstructor extends DeconstructorCommon[Closure]{ + def _1: List[Tree] // environment + def _2: Tree // meth + def _3: Symbol // functionalInterface + } + + abstract class ThisDeconstructor extends Deconstructor1Common[This, Name]{ + def apply(s: Symbol): Tree + } + + abstract class IdentDeconstructor extends Deconstructor1Common[Ident, Name]{ + } + + abstract class LabeledDeconstructor extends DeconstructorCommon[Labeled]{ + def _1: Bind // bind + def _2: Tree // expr + } + + abstract class ReturnDeconstructor extends DeconstructorCommon[Return]{ + def _1: Tree // expr + def _2: Symbol // target label, NoSymbol if return to method + } + + abstract class WhileDoDeconstructor extends DeconstructorCommon[WhileDo]{ + def _1: Tree // cond + def _2: Tree // body + } + + abstract class ThrownException { + def unapply(a: Annotation): Option[Symbol] + } + + abstract class ThrowDeconstructor extends Deconstructor1Common[Throw, Tree]{ + } + + abstract class ConstantDeconstructor extends Deconstructor1Common[Constant, Any]{ + } + + abstract class NewDeconstructor extends Deconstructor1Common[New, Type]{ + } + + abstract class AlternativeDeconstructor extends Deconstructor1Common[Alternative, List[Tree]]{ + } + + abstract class BlockDeconstructor extends DeconstructorCommon[Block]{ + def _1: List[Tree] + def _2: Tree + } + + abstract class CaseDeconstructor extends DeconstructorCommon[CaseDef]{ + def _1: Tree + def _2: Tree + def _3: Tree + } + + abstract class MatchDeconstructor extends DeconstructorCommon[Match]{ + def _1: Tree + def _2: List[Tree] + } + + abstract class LiteralDeconstructor extends Deconstructor1Common[Literal, Constant]{ + } + + abstract class AssignDeconstructor extends DeconstructorCommon[Assign]{ + def _1: Tree + def _2: Tree + } + + abstract class SelectDeconstructor extends DeconstructorCommon[Select]{ + def _1: Tree + def _2: Name + } + + abstract class ApplyDeconstructor extends DeconstructorCommon[Apply] { + def _1: Tree + def _2: List[Tree] + } + + abstract class IfDeconstructor extends DeconstructorCommon[If]{ + def _1: Tree + def _2: Tree + def _3: Tree + } + + abstract class ValDefDeconstructor extends DeconstructorCommon[ValDef]{ + def _1: Null + def _2: Name + def _3: Tree + def _4: Tree + } + + + abstract class TryDeconstructor extends DeconstructorCommon[Try]{ + def _1: Tree + def _2: List[Tree] + def _3: Tree + } + + abstract class TypedDeconstrutor extends DeconstructorCommon[Typed]{ + def _1: Tree + def _2: Tree + } + + abstract class SuperDeconstructor extends DeconstructorCommon[Super]{ + def _1: Tree + def _2: Name + } + + abstract class ArrayValueDeconstructor extends DeconstructorCommon[ArrayValue]{ + def _1: Type + def _2: List[Tree] + } + + abstract class TypeApplyDeconstructor extends DeconstructorCommon[TypeApply]{ + def _1: Tree + def _2: List[Tree] + } + + abstract class PositionHelper { + def isDefined: Boolean + def finalPosition: Position + def line: Int + } + + abstract class ConstantHelper { + def tag: ConstantTag + def longValue: Long + def doubleValue: Double + def charValue: Char + def stringValue: String + def byteValue: Byte + def booleanValue: Boolean + def shortValue: Short + def intValue: Int + def value: Any + def floatValue: Float + def typeValue: Type + def symbolValue: Symbol + } + + abstract class TreeHelper{ + def symbol: Symbol + def tpe: Type + def isEmpty: Boolean + def pos: Position + def exists(pred: Tree => Boolean): Boolean + } + + abstract class SymbolHelper { + def exists: Boolean + + // names + def showFullName: String + def javaSimpleName: String + def javaBinaryName: String + def javaClassName: String + def name: Name + def rawname: String + + // types + def info: Type + def tpe: Type // todo whats the differentce between tpe and info? + def thisType: Type + + /** Does this symbol actually correspond to an interface that will be emitted? + * In the backend, this should be preferred over `isInterface` because it + * also returns true for the symbols of the fake companion objects we + * create for Java-defined classes as well as for Java annotations + * which we represent as classes. + */ + final def isEmittedInterface: Boolean = isInterface || + isJavaDefined && (isAnnotation || isModuleClass && symHelper(companionClass).isInterface) + + // tests + def isClass: Boolean + def isType: Boolean + def isAnonymousClass: Boolean + def isConstructor: Boolean + def isExpanded: Boolean + def isAnonymousFunction: Boolean + def isMethod: Boolean + def isPublic: Boolean + def isSynthetic: Boolean + def isPackageClass: Boolean + def isModuleClass: Boolean + def isModule: Boolean + def isStrictFP: Boolean + def isLabel: Boolean + def hasPackageFlag: Boolean + def isInterface: Boolean + def isGetter: Boolean + def isSetter: Boolean + def isGetClass: Boolean + def isJavaDefined: Boolean + def isDeferred: Boolean + def isPrivate: Boolean + def getsJavaPrivateFlag: Boolean + def isFinal: Boolean + def getsJavaFinalFlag: Boolean + def isScalaStatic: Boolean + def isStaticMember: Boolean + def isBottomClass: Boolean + def isBridge: Boolean + def isArtifact: Boolean + def hasEnumFlag: Boolean + def hasAccessBoundary: Boolean + def isVarargsMethod: Boolean + def isDeprecated: Boolean + def isMutable: Boolean + def hasAbstractFlag: Boolean + def hasModuleFlag: Boolean + def isSynchronized: Boolean + def isNonBottomSubClass(sym: Symbol): Boolean + def hasAnnotation(sym: Symbol): Boolean + def shouldEmitForwarders: Boolean + def isJavaDefaultMethod: Boolean + def isClassConstructor: Boolean + def isAnnotation: Boolean + def isSerializable: Boolean + def isEnum: Boolean + + /** + * True for module classes of modules that are top-level or owned only by objects. Module classes + * for such objects will get a MODULE$ flag and a corresponding static initializer. + */ + def isStaticModuleClass: Boolean + + def isStaticConstructor: Boolean + + + // navigation + def owner: Symbol + def rawowner: Symbol // todo ??? + def originalOwner: Symbol + def parentSymbols: List[Symbol] + def superClass: Symbol + def enclClass: Symbol + def linkedClassOfClass: Symbol + def linkedClass: Symbol + def companionClass: Symbol + def companionModule: Symbol + def companionSymbol: Symbol + def moduleClass: Symbol + def enclosingClassSym: Symbol + def originalLexicallyEnclosingClass: Symbol + def nextOverriddenSymbol: Symbol + def allOverriddenSymbols: List[Symbol] + + + // members + def primaryConstructor: Symbol + def nestedClasses: List[Symbol] + def memberClasses: List[Symbol] + def annotations: List[Annotation] + def companionModuleMembers: List[Symbol] + def fieldSymbols: List[Symbol] + def methodSymbols: List[Symbol] + def serialVUID: Option[Long] + + + def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol + + def getter(clz: Symbol): Symbol + def setter(clz: Symbol): Symbol + + def moduleSuffix: String + def outputDirectory: AbstractFile + def pos: Position + + def throwsAnnotations: List[Symbol] + + /** + * All interfaces implemented by a class, except for those inherited through the superclass. + * + */ + def superInterfaces: List[Symbol] + + /** + * True for module classes of package level objects. The backend will generate a mirror class for + * such objects. + */ + def isTopLevelModuleClass: Boolean + + /** + * This is basically a re-implementation of sym.isStaticOwner, but using the originalOwner chain. + * + * The problem is that we are interested in a source-level property. Various phases changed the + * symbol's properties in the meantime, mostly lambdalift modified (destructively) the owner. + * Therefore, `sym.isStatic` is not what we want. For example, in + * object T { def f { object U } } + * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. + */ + def isOriginallyStaticOwner: Boolean = + isPackageClass || isModuleClass && symHelper(symHelper(originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner + + def samMethod(): Symbol + + /** Is this the symbol of one of the `scala.Function*` class ? + * Note that this will return false for subclasses of these classes. + */ + def isFunctionClass: Boolean + } + + abstract class TypeHelper { + def <:<(other: Type): Boolean + def =:=(other: Type): Boolean + def paramTypes: List[Type] + def params: List[Symbol] + def resultType: Type + def memberInfo(s: Symbol): Type + + /** The members of this type that have all of `required` flags but none of `excluded` flags set. + * The members are sorted by name and signature to guarantee a stable ordering. + */ + def sortedMembersBasedOnFlags(required: Flags, excluded: Flags): List[Symbol] + def members: List[Symbol] + def decl(name: Name): Symbol + def decls: List[Symbol] + def underlying: Type + def parents: List[Type] + def summaryString: String + def typeSymbol: Symbol + def member(string: Name): Symbol + /** + * This method returns the BType for a type reference, for example a parameter type. + * + * If the result is a ClassBType for a nested class, it is added to the innerClassBufferASM. + * + * If `t` references a class, toTypeKind ensures that the class is not an implementation class. + * See also comment on getClassBTypeAndRegisterInnerClass, which is invoked for implementation + * classes. + */ + def toTypeKind(ctx: BCodeHelpers)(storage: ctx.BCInnerClassGen): ctx.bTypes.BType + + def isFinalType: Boolean + } + + abstract class Primitives { + def getPrimitive(app: Apply, receiver: Type): Int + def isPrimitive(fun: Tree): Boolean + def getPrimitive(sym: Symbol): Int + } + + abstract class NameHelper { + def isTypeName: Boolean + def isTermName: Boolean + def startsWith(s: String): Boolean + def mangledString: String + } + + abstract class AnnotationHelper{ + def atp: Type + def symbol: Symbol + def args: List[Tree] + def assocs: List[(Name, /* ClassfileAnnotArg*/ Object)] + } + + abstract class Caches { + def recordCache[T <: Clearable](cache: T): T + def newWeakMap[K, V](): collection.mutable.WeakHashMap[K, V] + def newMap[K, V](): collection.mutable.HashMap[K, V] + def newSet[K](): collection.mutable.Set[K] + def newWeakSet[K >: Null <: AnyRef](): dotty.tools.dotc.util.WeakHashSet[K] + def newAnyRefMap[K <: AnyRef, V](): collection.mutable.AnyRefMap[K, V] + } + + // Class symbols used in backend. + // Vals because they are to frequent in scala programs so that they are already loaded by backend + + lazy val NativeAttr: Symbol = requiredClass[scala.native] + lazy val TransientAttr = requiredClass[scala.transient] + lazy val VolatileAttr = requiredClass[scala.volatile] + + val ScalaATTRName: String = "Scala" + val ScalaSignatureATTRName: String = "ScalaSig" + + def doLabmdasFollowJVMMetafactoryOrder: Boolean = true + + val BoxedBooleanClass: Symbol = requiredClass[java.lang.Boolean] + val BoxedByteClass: Symbol = requiredClass[java.lang.Byte] + val BoxedShortClass: Symbol = requiredClass[java.lang.Short] + val BoxedCharacterClass: Symbol = requiredClass[java.lang.Character] + val BoxedIntClass: Symbol = requiredClass[java.lang.Integer] + val BoxedLongClass: Symbol = requiredClass[java.lang.Long] + val BoxedFloatClass: Symbol = requiredClass[java.lang.Float] + val BoxedDoubleClass: Symbol = requiredClass[java.lang.Double] + val StringClass: Symbol = requiredClass[java.lang.String] + val JavaStringBuilderClass: Symbol = requiredClass[java.lang.StringBuilder] + val JavaStringBufferClass: Symbol = requiredClass[java.lang.StringBuffer] + val JavaCharSequenceClass: Symbol = requiredClass[java.lang.CharSequence] + val ThrowableClass: Symbol = requiredClass[java.lang.Throwable] + val JavaCloneableClass: Symbol = requiredClass[java.lang.Cloneable] + val NullPointerExceptionClass: Symbol = requiredClass[java.lang.NullPointerException] + val JavaSerializableClass: Symbol = requiredClass[java.io.Serializable] + val SerializableClass: Symbol = requiredClass[scala.Serializable] + val ClassCastExceptionClass: Symbol = requiredClass[java.lang.ClassCastException] + val IllegalArgExceptionClass: Symbol = requiredClass[java.lang.IllegalArgumentException] + val SerializedLambdaClass: Symbol = requiredClass[java.lang.invoke.SerializedLambda] + + val ClassfileAnnotationClass: Symbol = requiredClass[scala.annotation.ClassfileAnnotation] + val BoxedNumberClass: Symbol = requiredClass[java.lang.Number] + val ThrowsClass: Symbol = requiredClass[scala.throws[_]] + + // Module symbols used in backend + val StringModule: Symbol = symHelper(StringClass).linkedClassOfClass + val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type] + + + def isNull(t: Tree): Boolean = t match { + case LiteralBI(ConstantBI(null)) => true + case _ => false + } + def isLiteral(t: Tree): Boolean = t match { + case LiteralBI(_) => true + case _ => false + } + def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((treeHelper(t).symbol ne null) && symHelper(treeHelper(t).symbol).isModule) + def ifOneIsNull(l: Tree, r: Tree): Tree = if (isNull(l)) r else if (isNull(r)) l else null + + private val primitiveCompilationUnits = Set( + "Unit.scala", + "Boolean.scala", + "Char.scala", + "Byte.scala", + "Short.scala", + "Int.scala", + "Float.scala", + "Long.scala", + "Double.scala" + ) + + /** + * True if the current compilation unit is of a primitive class (scala.Boolean et al). + * Used only in assertions. + */ + def isCompilingPrimitive = { + primitiveCompilationUnits(sourceFileFor(currentUnit)) + } + + def isCompilingArray = { + sourceFileFor(currentUnit) == "Array.scala" + } } object DottyBackendInterface { From d4636445b918ed1e30c8143ff3ea32a3d16ef71a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 08:25:09 +0200 Subject: [PATCH 11/98] Remove classTags --- .../backend/jvm/DottyBackendInterface.scala | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 88cb57660de0..b8b1279f7eaf 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -176,36 +176,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isPrimitive(fun: Tree): Boolean = primitives.isPrimitive(fun) } - implicit val TypeDefTag: ClassTag[TypeDef] = ClassTag[TypeDef](classOf[TypeDef]) - implicit val ApplyTag: ClassTag[Apply] = ClassTag[Apply](classOf[Apply]) - implicit val SelectTag: ClassTag[Select] = ClassTag[Select](classOf[Select]) - implicit val TypeApplyTag: ClassTag[TypeApply] = ClassTag[TypeApply](classOf[TypeApply]) - implicit val ClassDefTag: ClassTag[ClassDef] = ClassTag[TypeDef](classOf[TypeDef]) - implicit val TryTag: ClassTag[Try] = ClassTag[Try](classOf[Try]) - implicit val AssignTag: ClassTag[Assign] = ClassTag[Assign](classOf[Assign]) - implicit val IdentTag: ClassTag[Ident] = ClassTag[Ident](classOf[Ident]) - implicit val IfTag: ClassTag[If] = ClassTag[If](classOf[If]) - implicit val ValDefTag: ClassTag[ValDef] = ClassTag[ValDef](classOf[ValDef]) - implicit val ThrowTag: ClassTag[Throw] = ClassTag[Throw](classOf[Throw]) - implicit val LabeledTag: ClassTag[Labeled] = ClassTag[Labeled](classOf[Labeled]) - implicit val ReturnTag: ClassTag[Return] = ClassTag[Return](classOf[Return]) - implicit val WhileDoTag: ClassTag[WhileDo] = ClassTag[WhileDo](classOf[WhileDo]) - implicit val LiteralTag: ClassTag[Literal] = ClassTag[Literal](classOf[Literal]) - implicit val BlockTag: ClassTag[Block] = ClassTag[Block](classOf[Block]) - implicit val TypedTag: ClassTag[Typed] = ClassTag[Typed](classOf[Typed]) - implicit val ArrayValueTag: ClassTag[ArrayValue] = ClassTag[ArrayValue](classOf[ArrayValue]) - implicit val MatchTag: ClassTag[Match] = ClassTag[Match](classOf[Match]) - implicit val CaseDefTag: ClassTag[CaseDef] = ClassTag[CaseDef](classOf[CaseDef]) - implicit val ThisTag: ClassTag[This] = ClassTag[This](classOf[This]) - implicit val AlternativeTag: ClassTag[Alternative] = ClassTag[Alternative](classOf[Alternative]) - implicit val DefDefTag: ClassTag[DefDef] = ClassTag[DefDef](classOf[DefDef]) - implicit val NameTag: ClassTag[Name] = ClassTag[Name](classOf[Name]) - implicit val TemplateTag: ClassTag[Template] = ClassTag[Template](classOf[Template]) - implicit val BindTag: ClassTag[Bind] = ClassTag[Bind](classOf[Bind]) - implicit val NewTag: ClassTag[New] = ClassTag[New](classOf[New]) - implicit val SuperTag: ClassTag[Super] = ClassTag[Super](classOf[Super]) - implicit val ConstantClassTag: ClassTag[Constant] = ClassTag[Constant](classOf[Constant]) - implicit val ClosureTag: ClassTag[Closure] = ClassTag[Closure](classOf[Closure]) def isRuntimeVisible(annot: Annotation): Boolean = if (toDenot(annotHelper(annot).atp.typeSymbol).hasAnnotation(AnnotationRetentionAttr)) From e8edee97414b099a23ede60cce8077efce6dcfb7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 08:31:09 +0200 Subject: [PATCH 12/98] Remove custom extractors --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 68 +++++++++---------- .../tools/backend/jvm/BCodeSkelBuilder.scala | 4 +- .../tools/backend/jvm/BCodeSyncAndTry.scala | 2 +- .../backend/jvm/DottyBackendInterface.scala | 44 +----------- 4 files changed, 40 insertions(+), 78 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 7c389daec115..5770f37c8e74 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -57,7 +57,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case AssignBI(lhs @ SelectBI(qual, _), rhs) => + case Assign(lhs @ SelectBI(qual, _), rhs) => val isStatic = symHelper(treeHelper(lhs).symbol).isStaticMember if (!isStatic) { genLoadQualifier(lhs) } genLoad(rhs, symInfoTK(treeHelper(lhs).symbol)) @@ -66,7 +66,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val receiverClass = typeHelper(treeHelper(qual).tpe).typeSymbol fieldStore(treeHelper(lhs).symbol, receiverClass) - case AssignBI(lhs, rhs) => + case Assign(lhs, rhs) => val s = treeHelper(lhs).symbol val Local(tk, _, idx, _) = locals.getOrMakeLocal(s) genLoad(rhs, tk) @@ -92,7 +92,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* Generate code for primitive arithmetic operations. */ def genArithmeticOp(tree: Tree, code: Int): BType = tree match{ - case ApplyBI(fun @ SelectBI(larg, _), args) => + case Apply(fun @ SelectBI(larg, _), args) => var resKind = tpeTK(larg) assert(resKind.isNumericType || (resKind == BOOL), @@ -148,7 +148,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* Generate primitive array operations. */ def genArrayOp(tree: Tree, code: Int, expectedType: BType): BType = tree match{ - case ApplyBI(SelectBI(arrayObj, _), args) => + case Apply(SelectBI(arrayObj, _), args) => import ScalaPrimitivesOps._ val k = tpeTK(arrayObj) genLoad(arrayObj, k) @@ -179,13 +179,13 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genLoadIf(tree: If, expectedType: BType): BType = tree match{ - case IfBI(condp, thenp, elsep) => + case If(condp, thenp, elsep) => val success = new asm.Label val failure = new asm.Label val hasElse = !treeHelper(elsep).isEmpty && (elsep match { - case LiteralBI(value) if constantHelper(value).tag == UnitTag => false + case Literal(value) if constantHelper(value).tag == UnitTag => false case _ => true }) val postIf = if (hasElse) new asm.Label else failure @@ -210,7 +210,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genPrimitiveOp(tree: Apply, expectedType: BType): BType = tree match { - case ApplyBI(fun @ SelectBI(receiver, _), _) => + case Apply(fun @ SelectBI(receiver, _), _) => val sym = treeHelper(tree).symbol val code = primitives.getPrimitive(tree, treeHelper(receiver).tpe) @@ -276,17 +276,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } generatedType = UNIT - case t @ IfBI(_, _, _) => + case t @ If(_, _, _) => generatedType = genLoadIf(t, expectedType) - case t @ LabeledBI(_, _) => + case t @ Labeled(_, _) => generatedType = genLabeled(t) case r @ ReturnBI(_) => genReturn(r) generatedType = expectedType - case t @ WhileDoBI(_, _) => + case t @ WhileDo(_, _) => generatedType = genWhileDo(t) case t @ TryBI(_, _, _) => @@ -301,7 +301,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case app @ ClosureBI(env, call, functionalInterface) => val (fun, args) = call match { - case ApplyBI(fun, args) => (fun, args) + case Apply(fun, args) => (fun, args) case t @ SelectBI(_, _) => (t, Nil) case t @ IdentBI(_) => (t, Nil) } @@ -320,7 +320,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoadArguments(env, typeHelper(symHelper(treeHelper(fun).symbol).info).paramTypes map toTypeKind) generatedType = genInvokeDynamicLambda(NoSymbol, treeHelper(fun).symbol, env.size, functionalInterface) - case app @ ApplyBI(_, _) => + case app @ Apply(_, _) => generatedType = genApply(app, expectedType) case ThisBI(qual) => @@ -377,7 +377,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(t, generatedType) } - case LiteralBI(value) => + case Literal(value) => if (constantHelper(value).tag != UnitTag) (constantHelper(value).tag, expectedType) match { case (IntTag, LONG ) => bc.lconst(constantHelper(value).longValue); generatedType = LONG case (FloatTag, DOUBLE) => bc.dconst(constantHelper(value).doubleValue); generatedType = DOUBLE @@ -385,7 +385,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case _ => genConstant(value); generatedType = tpeTK(tree) } - case blck @ BlockBI(stats, expr) => + case blck @ Block(stats, expr) => if(stats.isEmpty) genLoad(expr, expectedType) else genBlock(blck, expectedType) @@ -394,7 +394,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case TypedBI(expr, _) => genLoad(expr, expectedType) - case AssignBI(_, _) => + case Assign(_, _) => generatedType = UNIT genStat(tree) @@ -501,7 +501,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } private def genLabeled(tree: Labeled): BType = tree match { - case LabeledBI(bind, expr) => + case Labeled(bind, expr) => val resKind = tpeTK(tree) genLoad(expr, resKind) @@ -552,7 +552,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } // end of genReturn() def genWhileDo(tree: WhileDo): BType = tree match{ - case WhileDoBI(cond, body) => + case WhileDo(cond, body) => val isInfinite = cond == EmptyTree @@ -565,7 +565,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { RT_NOTHING } else { val hasBody = cond match { - case LiteralBI(value) if constantHelper(value).tag == UnitTag => false + case Literal(value) if constantHelper(value).tag == UnitTag => false case _ => true } @@ -589,7 +589,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genTypeApply(t: TypeApply): BType = t match { - case TypeApplyBI(fun@SelectBI(obj, _), targs) => + case TypeApply(fun@SelectBI(obj, _), targs) => val sym = treeHelper(fun).symbol val cast = sym match { @@ -658,17 +658,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var generatedType = expectedType lineNumber(app) app match { - case ApplyBI(_, args) if isSyntheticArrayConstructor(treeHelper(app).symbol) => - val List(elemClaz, LiteralBI(c: Constant), ArrayValueBI(_, dims)) = args + case Apply(_, args) if isSyntheticArrayConstructor(treeHelper(app).symbol) => + val List(elemClaz, Literal(c: Constant), ArrayValueBI(_, dims)) = args generatedType = toTypeKind(constantHelper(c).typeValue) mkArrayConstructorCall(generatedType.asArrayBType, app, dims) - case ApplyBI(t :TypeApply, _) => + case Apply(t :TypeApply, _) => generatedType = if (treeHelper(t).symbol ne Object_synchronized) genTypeApply(t) else genSynchronized(app, expectedType) - case ApplyBI(fun @ SelectBI(SuperBI(_, _), _), args) => + case Apply(fun @ SelectBI(SuperBI(_, _), _), args) => def initModule(): Unit = { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && @@ -700,7 +700,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // thought to return an instance of what they construct, // we have to 'simulate' it by DUPlicating the freshly created // instance (on JVM, methods return VOID). - case ApplyBI(fun @ SelectBI(NewBI(tpt), `nme_CONSTRUCTOR`), args) => + case Apply(fun @ SelectBI(NewBI(tpt), `nme_CONSTRUCTOR`), args) => val ctor = treeHelper(fun).symbol assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${symHelper(ctor).name}") @@ -722,21 +722,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { abort(s"Cannot instantiate $tpt of kind: $generatedType") } - case ApplyBI(fun, List(expr)) if isBox(treeHelper(fun).symbol) => + case Apply(fun, List(expr)) if isBox(treeHelper(fun).symbol) => val nativeKind = tpeTK(expr) genLoad(expr, nativeKind) val MethodNameAndType(mname, methodType) = asmBoxTo(nativeKind) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) generatedType = boxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.tpe.resultType) - case ApplyBI(fun, List(expr)) if isUnbox(treeHelper(fun).symbol) => + case Apply(fun, List(expr)) if isUnbox(treeHelper(fun).symbol) => genLoad(expr) val boxType = unboxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) generatedType = boxType val MethodNameAndType(mname, methodType) = asmUnboxTo(boxType) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) - case app @ ApplyBI(fun, args) => + case app @ Apply(fun, args) => val sym = treeHelper(fun).symbol if (isPrimitive(fun)) { // primitive method call @@ -847,7 +847,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val switchBlockPoint = new asm.Label switchBlocks ::= (switchBlockPoint, body) pat match { - case LiteralBI(value) => + case Literal(value) => flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint case IdentBI(`nme_WILDCARD`) => @@ -855,7 +855,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { default = switchBlockPoint case AlternativeBI(alts) => alts foreach { - case LiteralBI(value) => + case Literal(value) => flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint case _ => @@ -882,7 +882,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genBlock(tree: Block, expectedType: BType) = tree match { - case BlockBI(stats, expr) => + case Block(stats, expr) => val savedScope = varsInScope varsInScope = Nil @@ -1055,7 +1055,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) liftStringConcat(tree) match { // Optimization for expressions of the form "" + x. We can avoid the StringBuilder. - case List(LiteralBI(ConstantBI("")), arg) => + case List(Literal(ConstantBI("")), arg) => genLoad(arg, ObjectReference) genCallMethod(String_valueOf, InvokeStyle.Static) @@ -1063,7 +1063,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { bc.genStartConcat for (elem <- concatenations) { val loadedElem = elem match { - case ApplyBI(boxOp, value :: Nil) if isBox(treeHelper(boxOp).symbol) => + case Apply(boxOp, value :: Nil) if isBox(treeHelper(boxOp).symbol) => // Eliminate boxing of primitive values. Boxing is introduced by erasure because // there's only a single synthetic `+` method "added" to the string class. value @@ -1156,7 +1156,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * It turns a chained call like "a".+("b").+("c") into a list of arguments. */ def liftStringConcat(tree: Tree): List[Tree] = tree match { - case tree @ ApplyBI(fun @ SelectBI(larg, method), rarg) => + case tree @ Apply(fun @ SelectBI(larg, method), rarg) => if (isPrimitive(fun) && primitives.getPrimitive(tree, treeHelper(larg).tpe) == ScalaPrimitivesOps.CONCAT) liftStringConcat(larg) ::: rarg @@ -1259,7 +1259,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case tree @ ApplyBI(fun, args) if isPrimitive(fun) => + case tree @ Apply(fun, args) if isPrimitive(fun) => import ScalaPrimitivesOps.{ ZNOT, ZAND, ZOR, EQ } // lhs and rhs of test diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 32a74769da0a..1421c07cd428 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -63,7 +63,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* ---------------- idiomatic way to ask questions to typer ---------------- */ def paramTKs(app: Apply, take: Int = -1): List[BType] = app match { - case ApplyBI(fun, _) => + case Apply(fun, _) => val funSym = treeHelper(fun).symbol (typeHelper(symHelper(funSym).info).paramTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) } @@ -552,7 +552,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { genLoad(rhs, returnType) rhs match { - case ReturnBI(_) | BlockBI(_, ReturnBI(_)) | ThrowBI(_) | BlockBI(_, ThrowBI(_)) => () + case ReturnBI(_) | Block(_, ReturnBI(_)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () case EmptyTree => error(NoPosition, "Concrete method has no definition: " + dd + ( if (settings_debug) "(found: " + typeHelper(symHelper(symHelper(methSymbol).owner).info).decls.toList.mkString(", ") + ")" diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index 26b7e1c6e324..eae7b4480d7b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -21,7 +21,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { abstract class SyncAndTryBuilder(cunit: CompilationUnit) extends PlainBodyBuilder(cunit) { def genSynchronized(tree: Apply, expectedType: BType): BType = tree match { - case ApplyBI(TypeApplyBI(fun, _), args) => + case Apply(TypeApply(fun, _), args) => val monitor = locals.makeLocal(ObjectReference, "monitor", Object_Type, treeHelper(tree).pos) val monCleanup = new asm.Label diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index b8b1279f7eaf..f5433bfd784a 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -955,11 +955,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def parents: List[Type] = tp.parents } - object AssignBI extends AssignDeconstructor { - def _1: Tree = field.lhs - def _2: Tree = field.rhs - } - object SelectBI extends SelectDeconstructor { var desugared: tpd.Select = null @@ -986,17 +981,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object ApplyBI extends ApplyDeconstructor { - def _1: Tree = field.fun - def _2: List[Tree] = field.args - } - - object IfBI extends IfDeconstructor { - def _1: Tree = field.cond - def _2: Tree = field.thenp - def _3: Tree = field.elsep - } - object ValDefBI extends ValDefDeconstructor { def _1: Null = null def _2: Name = field.name @@ -1004,11 +988,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _4: Tree = field.rhs } - // todo: this product1s should also eventually become name-based pattn matching - object LiteralBI extends LiteralDeconstructor { - def get: Constant = field.const - } - object ThrowBI extends ThrowDeconstructor { def get: Tree = field.args.head @@ -1031,21 +1010,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def apply(s: Symbol): This = tpd.This(s.asClass) } - object LabeledBI extends LabeledDeconstructor { - def _1: Bind = field.bind - def _2: Tree = field.expr - } - object ReturnBI extends ReturnDeconstructor { def _1: Tree = field.expr def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol } - object WhileDoBI extends WhileDoDeconstructor { - def _1: Tree = field.cond - def _2: Tree = field.body - } - object IdentBI extends IdentDeconstructor { def get: Name = field.name } @@ -1088,14 +1057,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _1: Tree = field.selector def _2: List[Tree] = field.cases } - object BlockBI extends BlockDeconstructor { - def _1: List[Tree] = field.stats - def _2: Tree = field.expr - } - object TypeApplyBI extends TypeApplyDeconstructor { - def _1: Tree = field.fun - def _2: List[Tree] = field.args - } + object CaseDefBI extends CaseDeconstructor { def _1: Tree = field.pat def _2: Tree = field.guard @@ -1609,11 +1571,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isNull(t: Tree): Boolean = t match { - case LiteralBI(ConstantBI(null)) => true + case Literal(Constant(null)) => true case _ => false } def isLiteral(t: Tree): Boolean = t match { - case LiteralBI(_) => true + case Literal(_) => true case _ => false } def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((treeHelper(t).symbol ne null) && symHelper(treeHelper(t).symbol).isModule) From 3226aca137e711fe3e00ed03c293160fd93b7322 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 08:36:05 +0200 Subject: [PATCH 13/98] Remove more custom extractors --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 28 +++++++++---------- .../tools/backend/jvm/BCodeSyncAndTry.scala | 8 +++--- .../backend/jvm/DottyBackendInterface.scala | 27 ------------------ 3 files changed, 18 insertions(+), 45 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 5770f37c8e74..b6448fa771e6 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -295,15 +295,15 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case ThrowBI(expr) => generatedType = genThrow(expr) - case NewBI(tpt) => - abort(s"Unexpected New(${typeHelper(tpt).summaryString}/$tpt) reached GenBCode.\n" + + case New(tpt) => + abort(s"Unexpected New(${typeHelper(tpt.tpe).summaryString}/$tpt) reached GenBCode.\n" + " Call was genLoad" + ((tree, expectedType))) case app @ ClosureBI(env, call, functionalInterface) => val (fun, args) = call match { case Apply(fun, args) => (fun, args) case t @ SelectBI(_, _) => (t, Nil) - case t @ IdentBI(_) => (t, Nil) + case t @ Ident(_) => (t, Nil) } if (!symHelper(treeHelper(fun).symbol).isStaticMember) { @@ -337,7 +337,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { else classBTypeFromSymbol(claszSymbol) } - case SelectBI(IdentBI(`nme_EMPTY_PACKAGE_NAME`), module) => + case SelectBI(Ident(`nme_EMPTY_PACKAGE_NAME`), module) => assert(symHelper(treeHelper(tree).symbol).isModule, s"Selection of non-module from empty package: $tree sym: ${treeHelper(tree).symbol} at: ${treeHelper(tree).pos}") genLoadModule(tree) @@ -361,7 +361,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { fieldLoad(sym, receiverClass) } - case t @ IdentBI(name) => + case t @ Ident(name) => val sym = treeHelper(tree).symbol val tk = symInfoTK(sym) generatedType = tk @@ -390,9 +390,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(expr, expectedType) else genBlock(blck, expectedType) - case TypedBI(SuperBI(_, _), _) => genLoad(ThisBI(claszSymbol), expectedType) + case Typed(SuperBI(_, _), _) => genLoad(ThisBI(claszSymbol), expectedType) - case TypedBI(expr, _) => genLoad(expr, expectedType) + case Typed(expr, _) => genLoad(expr, expectedType) case Assign(_, _) => generatedType = UNIT @@ -401,7 +401,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case av @ ArrayValueBI(_, _) => generatedType = genArrayValue(av) - case mtch @ MatchBI(_, _) => + case mtch @ Match(_, _) => generatedType = genMatch(mtch) case EmptyTree => if (expectedType != UNIT) { emitZeroOf(expectedType) } @@ -700,11 +700,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // thought to return an instance of what they construct, // we have to 'simulate' it by DUPlicating the freshly created // instance (on JVM, methods return VOID). - case Apply(fun @ SelectBI(NewBI(tpt), `nme_CONSTRUCTOR`), args) => + case Apply(fun @ SelectBI(New(tpt), `nme_CONSTRUCTOR`), args) => val ctor = treeHelper(fun).symbol assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${symHelper(ctor).name}") - generatedType = toTypeKind(tpt) + generatedType = toTypeKind(tpt.tpe) assert(generatedType.isRef, s"Non reference type cannot be instantiated: $generatedType") generatedType match { @@ -831,7 +831,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * On a second pass, we emit the switch blocks, one for each different target. */ private def genMatch(tree: Match): BType = tree match { - case MatchBI(selector, cases) => + case Match(selector, cases) => lineNumber(tree) genLoad(selector, INT) val generatedType = tpeTK(tree) @@ -842,7 +842,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var switchBlocks: List[(asm.Label, Tree)] = Nil // collect switch blocks and their keys, but don't emit yet any switch-block. - for (caze @ CaseDefBI(pat, guard, body) <- cases) { + for (caze @ CaseDef(pat, guard, body) <- cases) { assert(guard == EmptyTree, guard) val switchBlockPoint = new asm.Label switchBlocks ::= (switchBlockPoint, body) @@ -850,10 +850,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case Literal(value) => flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint - case IdentBI(`nme_WILDCARD`) => + case Ident(`nme_WILDCARD`) => assert(default == null, s"multiple default targets in a Match node, at ${treeHelper(tree).pos}") default = switchBlockPoint - case AlternativeBI(alts) => + case Alternative(alts) => alts foreach { case Literal(value) => flatKeys ::= constantHelper(value).intValue diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index eae7b4480d7b..cde1cd7bea60 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -174,11 +174,11 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { val kind = tpeTK(tree) val caseHandlers: List[EHClause] = - for (CaseDefBI(pat, _, caseBody) <- catches) yield { + for (CaseDef(pat, _, caseBody) <- catches) yield { pat match { - case TypedBI(IdentBI(`nme_WILDCARD`), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) - case IdentBI(`nme_WILDCARD`) => NamelessEH(ThrowableReference, caseBody) - case BindBI(_, _) => BoundEH (treeHelper(pat).symbol, caseBody) + case Typed(Ident(`nme_WILDCARD`), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) + case Ident(`nme_WILDCARD`) => NamelessEH(ThrowableReference, caseBody) + case Bind(_, _) => BoundEH (treeHelper(pat).symbol, caseBody) } } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index f5433bfd784a..f961bbbb8983 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -1015,14 +1015,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol } - object IdentBI extends IdentDeconstructor { - def get: Name = field.name - } - - object AlternativeBI extends AlternativeDeconstructor { - def get: List[Tree] = field.trees - } - object ConstantBI extends ConstantDeconstructor { def get: Any = field.value } @@ -1036,10 +1028,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _3: Tree = field.finalizer } - object TypedBI extends TypedDeconstrutor { - def _1: Tree = field.expr - def _2: Tree = field.tpt - } object SuperBI extends SuperDeconstructor { def _1: Tree = field.qual def _2: Name = field.mix.name @@ -1053,16 +1041,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } def _2: List[Tree] = field.elems } - object MatchBI extends MatchDeconstructor { - def _1: Tree = field.selector - def _2: List[Tree] = field.cases - } - - object CaseDefBI extends CaseDeconstructor { - def _1: Tree = field.pat - def _2: Tree = field.guard - def _3: Tree = field.body - } object DefDefBI extends DefDefDeconstructor { def _1: Null = null @@ -1081,11 +1059,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma else field.constr :: field.body } - object BindBI extends BindDeconstructor { - def _1: Name = field.name - def _2: Tree = field.body - } - object ClassDefBI extends ClassDefDeconstructor { def _1: Null = null def _2: Name = field.name From 93303172b03df064ee6a296ded3800fac12f97c9 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 09:09:16 +0200 Subject: [PATCH 14/98] Remove aliases --- .../tools/backend/jvm/BCodeAsmCommon.scala | 2 + .../tools/backend/jvm/BCodeBodyBuilder.scala | 60 ++++++++-------- .../tools/backend/jvm/BCodeHelpers.scala | 10 +-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 10 ++- .../tools/backend/jvm/BCodeSyncAndTry.scala | 16 +++-- .../tools/backend/jvm/BTypesFromSymbols.scala | 8 ++- .../dotty/tools/backend/jvm/CoreBTypes.scala | 30 ++++---- .../backend/jvm/DottyBackendInterface.scala | 70 +++---------------- 8 files changed, 89 insertions(+), 117 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 00c9586d1dd7..efed1c950876 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -2,6 +2,8 @@ package dotty.tools package backend package jvm +import dotty.tools.dotc.core.Symbols._ + /** * This trait contains code shared between GenBCode and GenASM that depends on types defined in * the compiler cake (Global). diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index b6448fa771e6..6e281ba08aa7 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -8,6 +8,12 @@ import scala.tools.asm import scala.tools.asm.{Handle, Label, Opcodes} import BCodeHelpers.InvokeStyle +import dotty.tools.dotc.core.Constants._ +import dotty.tools.dotc.core.StdNames.nme +import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.util.Spans.NoSpan +import dotty.tools.dotc.ast.tpd + /* * * @author Miguel Garcia, http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/ @@ -258,7 +264,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case ValDefBI(_, `nme_THIS`, _, _) => + case ValDefBI(_, nme.THIS, _, _) => debuglog("skipping trivial assign to _$this: " + tree) case ValDefBI(_, _, _, rhs) => @@ -267,7 +273,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { while duplicating a finalizer that contains this ValDef. */ val loc = locals.getOrMakeLocal(sym) val Local(tk, _, idx, isSynth) = loc - if (rhs == EmptyTree) { emitZeroOf(tk) } + if (rhs == tpd.EmptyTree) { emitZeroOf(tk) } else { genLoad(rhs, tk) } bc.store(idx, tk) val localVarStart = currProgramPoint() @@ -333,11 +339,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { else { mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) generatedType = - if (treeHelper(tree).symbol == ArrayClass) ObjectReference + if (treeHelper(tree).symbol == defn.ArrayClass) ObjectReference else classBTypeFromSymbol(claszSymbol) } - case SelectBI(Ident(`nme_EMPTY_PACKAGE_NAME`), module) => + case SelectBI(Ident(nme.EMPTY_PACKAGE), module) => assert(symHelper(treeHelper(tree).symbol).isModule, s"Selection of non-module from empty package: $tree sym: ${treeHelper(tree).symbol} at: ${treeHelper(tree).pos}") genLoadModule(tree) @@ -404,7 +410,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case mtch @ Match(_, _) => generatedType = genMatch(mtch) - case EmptyTree => if (expectedType != UNIT) { emitZeroOf(expectedType) } + case tpd.EmptyTree => if (expectedType != UNIT) { emitZeroOf(expectedType) } case t: TypeApply => // dotty specific @@ -554,7 +560,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genWhileDo(tree: WhileDo): BType = tree match{ case WhileDo(cond, body) => - val isInfinite = cond == EmptyTree + val isInfinite = cond == tpd.EmptyTree val loop = new asm.Label markProgramPoint(loop) @@ -592,12 +598,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case TypeApply(fun@SelectBI(obj, _), targs) => val sym = treeHelper(fun).symbol - val cast = sym match { - case Object_isInstanceOf => false - case Object_asInstanceOf => true - case _ => abort(s"Unexpected type application $fun[sym: ${symHelper(sym).showFullName}] in: $t") - } - + val cast = + if (sym == defn.Any_isInstanceOf) false + else if (sym == defn.Any_asInstanceOf) true + else abort(s"Unexpected type application $fun[sym: ${symHelper(sym).showFullName}] in: $t") val l = tpeTK(obj) val r = tpeTK(targs.head) genLoadQualifier(fun) @@ -665,7 +669,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { mkArrayConstructorCall(generatedType.asArrayBType, app, dims) case Apply(t :TypeApply, _) => generatedType = - if (treeHelper(t).symbol ne Object_synchronized) genTypeApply(t) + if (treeHelper(t).symbol ne defn.Object_synchronized) genTypeApply(t) else genSynchronized(app, expectedType) case Apply(fun @ SelectBI(SuperBI(_, _), _), args) => @@ -700,7 +704,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // thought to return an instance of what they construct, // we have to 'simulate' it by DUPlicating the freshly created // instance (on JVM, methods return VOID). - case Apply(fun @ SelectBI(New(tpt), `nme_CONSTRUCTOR`), args) => + case Apply(fun @ SelectBI(New(tpt), nme.CONSTRUCTOR), args) => val ctor = treeHelper(fun).symbol assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${symHelper(ctor).name}") @@ -774,13 +778,13 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // receiverClass is used in the bytecode to as the method receiver. using sym.owner // may lead to IllegalAccessErrors, see 9954eaf / aladdin bug 455. val qualSym = typeHelper(treeHelper(qual).tpe).typeSymbol - if (qualSym == ArrayClass) { + if (qualSym == defn.ArrayClass) { // For invocations like `Array(1).hashCode` or `.wait()`, use Object as receiver // in the bytecode. Using the array descriptor (like we do for clone above) seems // to work as well, but it seems safer not to change this. Javac also uses Object. // Note that array apply/update/length are handled by isPrimitive (above). - assert(symHelper(sym).owner == ObjectClass, s"unexpected array call: $app") - ObjectClass + assert(symHelper(sym).owner == defn.ObjectClass, s"unexpected array call: $app") + defn.ObjectClass } else qualSym } generatedType = genCallMethod(sym, invokeStyle, treeHelper(app).pos, receiverClass) @@ -843,14 +847,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // collect switch blocks and their keys, but don't emit yet any switch-block. for (caze @ CaseDef(pat, guard, body) <- cases) { - assert(guard == EmptyTree, guard) + assert(guard == tpd.EmptyTree, guard) val switchBlockPoint = new asm.Label switchBlocks ::= (switchBlockPoint, body) pat match { case Literal(value) => flatKeys ::= constantHelper(value).intValue targets ::= switchBlockPoint - case Ident(`nme_WILDCARD`) => + case Ident(nme.WILDCARD) => assert(default == null, s"multiple default targets in a Match node, at ${treeHelper(tree).pos}") default = switchBlockPoint case Alternative(alts) => @@ -996,7 +1000,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(tree: Tree): BType = { val module = ( if (!symHelper(treeHelper(tree).symbol).isPackageClass) treeHelper(tree).symbol - else typeHelper(symHelper(treeHelper(tree).symbol).info).member(nme_PACKAGE) match { + else typeHelper(symHelper(treeHelper(tree).symbol).info).member(nme.PACKAGE) match { case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree") case s => abort(s"SI-5604: found package class where package object expected: $tree") } @@ -1084,7 +1088,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * invocation instruction, otherwise `method.owner`. A specific receiver class is needed to * prevent an IllegalAccessError, (aladdin bug 455). */ - def genCallMethod(method: Symbol, style: InvokeStyle, pos: Position = NoPosition, specificReceiver: Symbol = null): BType = { + def genCallMethod(method: Symbol, style: InvokeStyle, pos: Position = NoSpan, specificReceiver: Symbol = null): BType = { val methodOwner = symHelper(method).owner // the class used in the invocation's method descriptor in the classfile @@ -1112,9 +1116,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { receiver != methodOwner && // fast path - the boolean is used to pick either of these two, if they are the same it does not matter style.isVirtual && symHelper(receiver).isEmittedInterface && - symHelper(typeHelper(Object_Type).decl(symHelper(method).name)).exists && { // fast path - compute overrideChain on the next line only if necessary + symHelper(typeHelper(defn.ObjectType).decl(symHelper(method).name)).exists && { // fast path - compute overrideChain on the next line only if necessary val syms = symHelper(method).allOverriddenSymbols - !syms.isEmpty && symHelper(syms.last).owner == ObjectClass + !syms.isEmpty && symHelper(syms.last).owner == defn.ObjectClass } } if (isTraitMethodOverridingObjectMember) methodOwner else receiver @@ -1264,7 +1268,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // lhs and rhs of test lazy val SelectBI(lhs, _) = fun - val rhs = if (args.isEmpty) EmptyTree else args.head // args.isEmpty only for ZNOT + val rhs = if (args.isEmpty) tpd.EmptyTree else args.head // args.isEmpty only for ZNOT def genZandOrZor(and: Boolean): Unit = { // reaching "keepGoing" indicates the rhs should be evaluated too (ie not short-circuited). @@ -1345,11 +1349,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // SI-7852 Avoid null check if L is statically non-null. genLoad(l, ObjectReference) genLoad(r, ObjectReference) - genCallMethod(Object_equals, InvokeStyle.Virtual) + genCallMethod(defn.Any_equals, InvokeStyle.Virtual) genCZJUMP(success, failure, Primitives.NE, BOOL, targetIfNoJump) } else { // l == r -> if (l eq null) r eq null else l.equals(r) - val eqEqTempLocal = locals.makeLocal(ObjectReference, nameHelper(nme_EQEQ_LOCAL_VAR).mangledString, Object_Type, treeHelper(r).pos) + val eqEqTempLocal = locals.makeLocal(ObjectReference, nameHelper(nme.EQEQ_LOCAL_VAR).mangledString, defn.ObjectType, treeHelper(r).pos) val lNull = new asm.Label val lNonNull = new asm.Label @@ -1366,7 +1370,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { markProgramPoint(lNonNull) locals.load(eqEqTempLocal) - genCallMethod(Object_equals, InvokeStyle.Virtual) + genCallMethod(defn.Any_equals, InvokeStyle.Virtual) genCZJUMP(success, failure, Primitives.NE, BOOL, targetIfNoJump) } } @@ -1404,7 +1408,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = symHelper(symHelper(lambdaTarget).owner).info :: capturedParamsTypes // Requires https://github.com/scala/scala-java8-compat on the runtime classpath - val returnUnit = typeHelper(typeHelper(symHelper(lambdaTarget).info).resultType).typeSymbol == UnitClass + val returnUnit = typeHelper(typeHelper(symHelper(lambdaTarget).info).resultType).typeSymbol == defn.UnitClass val functionalInterfaceDesc: String = generatedType.descriptor val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc // TODO specialization diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 3509e531d672..bba653d04ce4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -7,6 +7,8 @@ import scala.tools.asm.ClassWriter import scala.collection.mutable import dotty.tools.io.AbstractFile +import dotty.tools.dotc.core.Symbols._ + /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. * @@ -198,7 +200,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { private def assertClassNotArray(sym: Symbol): Unit = { assert(symHelper(sym).isClass, sym) - assert(sym != ArrayClass || isCompilingArray, sym) + assert(sym != defn.ArrayClass || isCompilingArray, sym) } private def assertClassNotArrayNotPrimitive(sym: Symbol): Unit = { @@ -223,8 +225,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { final def getClassBTypeAndRegisterInnerClass(sym: Symbol): ClassBType = { assertClassNotArrayNotPrimitive(sym) - if (sym == NothingClass) RT_NOTHING - else if (sym == NullClass) RT_NULL + if (sym == defn.NothingClass) RT_NOTHING + else if (sym == defn.NullClass) RT_NULL else { val r = classBTypeFromSymbol(sym) if (r.isNestedClass) innerClassBufferASM += r @@ -382,7 +384,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val m = if (symHelper(m0).isBridge) symHelper(m0).nextOverriddenSymbol else m0 if (m == NoSymbol) log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") - else if (symHelper(m).isType || symHelper(m).isDeferred || (symHelper(m).owner eq ObjectClass) || symHelper(m).isConstructor || symHelper(m).isExpanded) + else if (symHelper(m).isType || symHelper(m).isDeferred || (symHelper(m).owner eq defn.ObjectClass) || symHelper(m).isConstructor || symHelper(m).isExpanded) debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(symHelper(m).name)) log(s"No forwarder for $m due to conflict with ${typeHelper(symHelper(linkedClass).info).member(symHelper(m).name)}") diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 1421c07cd428..0ebf4801401c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -9,6 +9,10 @@ import scala.tools.asm import scala.tools.asm.util.{TraceMethodVisitor, ASMifier} import java.io.PrintWriter +import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.util.Spans.NoSpan +import dotty.tools.dotc.ast.tpd + /* * * @author Miguel Garcia, http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/ @@ -464,7 +468,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def gen(tree: Tree): Unit = { tree match { - case EmptyTree => () + case tpd.EmptyTree => () case ValDefBI(mods, name, tpt, rhs) => () // fields are added in `genPlainClass()`, via `addClassFields()` @@ -553,8 +557,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { rhs match { case ReturnBI(_) | Block(_, ReturnBI(_)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () - case EmptyTree => - error(NoPosition, "Concrete method has no definition: " + dd + ( + case tpd.EmptyTree => + error(NoSpan, "Concrete method has no definition: " + dd + ( if (settings_debug) "(found: " + typeHelper(symHelper(symHelper(methSymbol).owner).info).decls.toList.mkString(", ") + ")" else "") ) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index cde1cd7bea60..706f66c28e0b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -5,6 +5,10 @@ package jvm import scala.collection.immutable import scala.tools.asm +import dotty.tools.dotc.core.StdNames.nme +import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.ast.tpd + /* * * @author Miguel Garcia, http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/ @@ -22,13 +26,13 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { def genSynchronized(tree: Apply, expectedType: BType): BType = tree match { case Apply(TypeApply(fun, _), args) => - val monitor = locals.makeLocal(ObjectReference, "monitor", Object_Type, treeHelper(tree).pos) + val monitor = locals.makeLocal(ObjectReference, "monitor", defn.ObjectType, treeHelper(tree).pos) val monCleanup = new asm.Label // if the synchronized block returns a result, store it in a local variable. // Just leaving it on the stack is not valid in MSIL (stack is cleaned when leaving try-blocks). val hasResult = (expectedType != UNIT) - val monitorResult: Symbol = if (hasResult) locals.makeLocal(tpeTK(args.head), "monitorResult", Object_Type, treeHelper(tree).pos) else null + val monitorResult: Symbol = if (hasResult) locals.makeLocal(tpeTK(args.head), "monitorResult", defn.ObjectType, treeHelper(tree).pos) else null /* ------ (1) pushing and entering the monitor, also keeping a reference to it in a local var. ------ */ genLoadQualifier(fun) @@ -176,8 +180,8 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { val caseHandlers: List[EHClause] = for (CaseDef(pat, _, caseBody) <- catches) yield { pat match { - case Typed(Ident(`nme_WILDCARD`), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) - case Ident(`nme_WILDCARD`) => NamelessEH(ThrowableReference, caseBody) + case Typed(Ident(nme.WILDCARD), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) + case Ident(nme.WILDCARD) => NamelessEH(ThrowableReference, caseBody) case Bind(_, _) => BoundEH (treeHelper(pat).symbol, caseBody) } } @@ -195,7 +199,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { */ val postHandlers = new asm.Label - val hasFinally = (finalizer != EmptyTree) + val hasFinally = (finalizer != tpd.EmptyTree) /* * used in the finally-clause reached via fall-through from try-catch, if any. @@ -316,7 +320,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { nopIfNeeded(startTryBody) val finalHandler = currProgramPoint() // version of the finally-clause reached via unhandled exception. protect(startTryBody, finalHandler, finalHandler, null) - val Local(eTK, _, eIdx, _) = locals(locals.makeLocal(ThrowableReference, "exc", Throwable_Type, treeHelper(finalizer).pos)) + val Local(eTK, _, eIdx, _) = locals(locals.makeLocal(ThrowableReference, "exc", defn.ThrowableType, treeHelper(finalizer).pos)) bc.store(eIdx, eTK) emitFinalizer(finalizer, null, isDuplicate = true) bc.load(eIdx, eTK) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index b59f7406ccff..8535c23648a1 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -5,6 +5,8 @@ package jvm import scala.tools.asm import scala.annotation.threadUnsafe +import dotty.tools.dotc.core.Symbols._ + /** * This class mainly contains the method classBTypeFromSymbol, which extracts the necessary * information from a symbol and its type to create the corresponding ClassBType. It requires @@ -48,7 +50,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { assert(symHelper(classSym).isClass, s"Cannot create ClassBType from non-class symbol $classSym") assert( (!primitiveTypeMap.contains(classSym) || isCompilingPrimitive) && - (classSym != NothingClass && classSym != NullClass), + (classSym != defn.NothingClass && classSym != defn.NullClass), s"Cannot create ClassBType for special class symbol ${symHelper(classSym).showFullName}") convertedClasses.getOrElse(classSym, { @@ -64,10 +66,10 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { private def setClassInfo(classSym: Symbol, classBType: ClassBType): ClassBType = { val superClassSym = symHelper(classSym).superClass assert( - if (classSym == ObjectClass) + if (classSym == defn.ObjectClass) superClassSym == NoSymbol else if (symHelper(classSym).isInterface) - superClassSym == ObjectClass + superClassSym == defn.ObjectClass else // A ClassBType for a primitive class (scala.Boolean et al) is only created when compiling these classes. ((superClassSym != NoSymbol) && !symHelper(superClassSym).isInterface) || (isCompilingPrimitive && primitiveTypeMap.contains(classSym)), diff --git a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala index 6d3ea81deeeb..7b8d1b6f293a 100644 --- a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala @@ -4,6 +4,8 @@ package jvm import scala.annotation.switch +import dotty.tools.dotc.core.Symbols._ + /** * Core BTypes and some other definitions. The initialization of these definitions requies access * to symbols / types (global). @@ -40,15 +42,15 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp * the first use of `classBTypeFromSymbol` because that method looks at the map. */ lazy val primitiveTypeMap: Map[Symbol, PrimitiveBType] = Map( - UnitClass -> UNIT, - BooleanClass -> BOOL, - CharClass -> CHAR, - ByteClass -> BYTE, - ShortClass -> SHORT, - IntClass -> INT, - LongClass -> LONG, - FloatClass -> FLOAT, - DoubleClass -> DOUBLE + defn.UnitClass -> UNIT, + defn.BooleanClass -> BOOL, + defn.CharClass -> CHAR, + defn.ByteClass -> BYTE, + defn.ShortClass -> SHORT, + defn.IntClass -> INT, + defn.LongClass -> LONG, + defn.FloatClass -> FLOAT, + defn.DoubleClass -> DOUBLE ) lazy val BOXED_UNIT : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Void]) @@ -107,16 +109,16 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp lazy val RT_NOTHING : ClassBType = classBTypeFromSymbol(getRequiredClass("scala.runtime.Nothing$")) // (requiredClass[scala.runtime.Nothing$]) lazy val RT_NULL : ClassBType = classBTypeFromSymbol(getRequiredClass("scala.runtime.Null$")) // (requiredClass[scala.runtime.Null$]) - lazy val ObjectReference : ClassBType = classBTypeFromSymbol(ObjectClass) + lazy val ObjectReference : ClassBType = classBTypeFromSymbol(defn.ObjectClass) lazy val objArrayReference : ArrayBType = ArrayBType(ObjectReference) - lazy val StringRef : ClassBType = classBTypeFromSymbol(StringClass) + lazy val StringRef : ClassBType = classBTypeFromSymbol(defn.StringClass) lazy val jlStringBuilderRef : ClassBType = classBTypeFromSymbol(JavaStringBuilderClass) lazy val jlStringBufferRef : ClassBType = classBTypeFromSymbol(JavaStringBufferClass) lazy val jlCharSequenceRef : ClassBType = classBTypeFromSymbol(JavaCharSequenceClass) - lazy val ThrowableReference : ClassBType = classBTypeFromSymbol(ThrowableClass) - lazy val jlCloneableReference : ClassBType = classBTypeFromSymbol(JavaCloneableClass) // java/lang/Cloneable - lazy val jlNPEReference : ClassBType = classBTypeFromSymbol(NullPointerExceptionClass) // java/lang/NullPointerException + lazy val ThrowableReference : ClassBType = classBTypeFromSymbol(defn.ThrowableClass) + lazy val jlCloneableReference : ClassBType = classBTypeFromSymbol(defn.JavaCloneableClass) // java/lang/Cloneable + lazy val jlNPEReference : ClassBType = classBTypeFromSymbol(defn.NullPointerExceptionClass) // java/lang/NullPointerException lazy val jioSerializableReference : ClassBType = classBTypeFromSymbol(JavaSerializableClass) // java/io/Serializable lazy val scalaSerializableReference : ClassBType = classBTypeFromSymbol(SerializableClass) // scala/Serializable lazy val classCastExceptionReference : ClassBType = classBTypeFromSymbol(ClassCastExceptionClass) // java/lang/ClassCastException diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index f961bbbb8983..012ee9c94108 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -24,6 +24,7 @@ import Phases._ import dotty.tools.dotc.util import dotty.tools.dotc.util.Spans import Decorators._ +import Constants._ import tpd._ import scala.tools.asm @@ -31,7 +32,7 @@ import StdNames.{nme, str} import NameKinds.{DefaultGetterName, ExpandedName} import Names.TermName -class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit ctx: Context) { +class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit val ctx: Context) { 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. @@ -76,59 +77,10 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma type ArrayValue = tpd.JavaSeqLiteral type Closure = tpd.Closure - val NoSymbol: Symbol = Symbols.NoSymbol - val NoPosition: Position = Spans.NoSpan - val EmptyTree: Tree = tpd.EmptyTree - - - val UnitTag: ConstantTag = Constants.UnitTag - val IntTag: ConstantTag = Constants.IntTag - val FloatTag: ConstantTag = Constants.FloatTag - val NullTag: ConstantTag = Constants.NullTag - val BooleanTag: ConstantTag = Constants.BooleanTag - val ByteTag: ConstantTag = Constants.ByteTag - val ShortTag: ConstantTag = Constants.ShortTag - val CharTag: ConstantTag = Constants.CharTag - val DoubleTag: ConstantTag = Constants.DoubleTag - val LongTag: ConstantTag = Constants.LongTag - val StringTag: ConstantTag = Constants.StringTag - val ClazzTag: ConstantTag = Constants.ClazzTag - val EnumTag: ConstantTag = Constants.EnumTag - - val nme_This: Name = StdNames.nme.This - val nme_EMPTY_PACKAGE_NAME: Name = StdNames.nme.EMPTY_PACKAGE - val nme_CONSTRUCTOR: Name = StdNames.nme.CONSTRUCTOR - val nme_WILDCARD: Name = StdNames.nme.WILDCARD - val nme_THIS: Name = StdNames.nme.THIS - val nme_PACKAGE: Name = StdNames.nme.PACKAGE - val nme_EQEQ_LOCAL_VAR: Name = StdNames.nme.EQEQ_LOCAL_VAR - // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") - val nme_valueOf: Name = StdNames.nme.valueOf - val nme_apply: TermName = StdNames.nme.apply - val NothingClass: Symbol = defn.NothingClass - val NullClass: Symbol = defn.NullClass - val ObjectClass: Symbol = defn.ObjectClass - val Object_Type: Type = defn.ObjectType - val Throwable_Type: Type = defn.ThrowableType - val Object_isInstanceOf: Symbol = defn.Any_isInstanceOf - val Object_asInstanceOf: Symbol = defn.Any_asInstanceOf - val Object_synchronized: Symbol = defn.Object_synchronized - val Object_equals: Symbol = defn.Any_equals - val ArrayClass: Symbol = defn.ArrayClass - val UnitClass: Symbol = defn.UnitClass - val BooleanClass: Symbol = defn.BooleanClass - val CharClass: Symbol = defn.CharClass - val ShortClass: Symbol = defn.ShortClass - val ClassClass: Symbol = defn.ClassClass - val ByteClass: Symbol = defn.ByteClass - val IntClass: Symbol = defn.IntClass - val LongClass: Symbol = defn.LongClass - val FloatClass: Symbol = defn.FloatClass - val DoubleClass: Symbol = defn.DoubleClass def isArrayClone(tree: Tree): Boolean = tree match { case SelectBI(qual, StdNames.nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true case _ => false @@ -237,7 +189,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma arrAnnotV.visitEnd() case Apply(fun, args) if fun.symbol == defn.ArrayClass.primaryConstructor || - toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply => + toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme.apply => val arrAnnotV: AnnotationVisitor = av.visitArray(name) var actualArgs = if (fun.tpe.isImplicitMethod) { @@ -412,12 +364,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma // todo: remove def isMaybeBoxed(sym: Symbol): Boolean = { - (sym == ObjectClass) || - (sym == JavaSerializableClass) || + (sym == defn.ObjectClass) || + (sym == defn.JavaSerializableClass) || (sym == defn.ComparableClass) || - (sym derivesFrom BoxedNumberClass) || + (sym derivesFrom defn.BoxedNumberClass) || (sym derivesFrom BoxedCharacterClass) || - (sym derivesFrom BoxedBooleanClass) + (sym derivesFrom defn.BoxedBooleanClass) } def getSingleOutput: Option[AbstractFile] = None // todo: implement @@ -699,7 +651,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma // workaround #371 println(s"Warning: mocking up superclass for $sym") - ObjectClass + defn.ObjectClass } else t } @@ -881,7 +833,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma */ def primitiveOrClassToBType(sym: Symbol): BType = { assert(sym.isClass, sym) - assert(sym != ArrayClass || isCompilingArray, sym) + assert(sym != defn.ArrayClass || isCompilingArray, sym) primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] } @@ -934,7 +886,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") tp match { - case tp: ThisType if tp.cls == ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test + case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) case t: SingletonType => t.underlying.toTypeKind(ct)(storage) @@ -1074,7 +1026,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma if (t.exists) t else { val arity = field.meth.tpe.widenDealias.paramTypes.size - _1.size - val returnsUnit = field.meth.tpe.widenDealias.resultType.classSymbol == UnitClass + val returnsUnit = field.meth.tpe.widenDealias.resultType.classSymbol == defn.UnitClass if (returnsUnit) ctx.requiredClass(("dotty.runtime.function.JProcedure" + arity)) else if (arity <= 2) ctx.requiredClass(("dotty.runtime.function.JFunction" + arity)) else ctx.requiredClass(("scala.Function" + arity)) From cec354cde9fee18665390e90eeb67109aa20e2fb Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 09:23:09 +0200 Subject: [PATCH 15/98] Remove more aliases --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 8 ++--- .../tools/backend/jvm/BCodeHelpers.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../dotty/tools/backend/jvm/CoreBTypes.scala | 32 +++++++++---------- .../backend/jvm/DottyBackendInterface.scala | 31 ++---------------- 5 files changed, 24 insertions(+), 51 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 6e281ba08aa7..710346f0d2ee 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1324,9 +1324,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (mustUseAnyComparator) { val equalsMethod: Symbol = { - if (typeHelper(treeHelper(l).tpe) <:< symHelper(BoxedNumberClass).tpe) { - if (typeHelper(treeHelper(r).tpe) <:< symHelper(BoxedNumberClass).tpe) externalEqualsNumNum - else if (typeHelper(treeHelper(r).tpe) <:< symHelper(BoxedCharacterClass).tpe) externalEqualsNumChar + if (typeHelper(treeHelper(l).tpe) <:< symHelper(defn.BoxedNumberClass).tpe) { + if (typeHelper(treeHelper(r).tpe) <:< symHelper(defn.BoxedNumberClass).tpe) externalEqualsNumNum + else if (typeHelper(treeHelper(r).tpe) <:< symHelper(defn.BoxedCharClass).tpe) externalEqualsNumChar else externalEqualsNumObject } else externalEquals } @@ -1403,7 +1403,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* itf = */ isInterface) val (a,b) = typeHelper(symHelper(lambdaTarget).info).paramTypes.splitAt(environmentSize) - var (capturedParamsTypes, lambdaParamTypes) = if(int.doLabmdasFollowJVMMetafactoryOrder) (a,b) else (b,a) + var (capturedParamsTypes, lambdaParamTypes) = (a,b) if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = symHelper(symHelper(lambdaTarget).owner).info :: capturedParamsTypes diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index bba653d04ce4..4e9a5fea75c1 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -327,7 +327,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // TODO needed? for(ann <- m.annotations) { ann.symbol.initialize } val jgensig = getStaticForwarderGenericSignature(m, module) - val (throws, others) = symHelper(m).annotations partition (annotHelper(_).symbol == ThrowsClass) + val (throws, others) = symHelper(m).annotations partition (annotHelper(_).symbol == defn.ThrowsAnnot) val thrownExceptions: List[String] = getExceptions(throws) val jReturnType = toTypeKind(typeHelper(methodInfo).resultType) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 0ebf4801401c..59fcd46a499f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -486,7 +486,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def initJMethod(flags: Int, paramAnnotations: List[List[Annotation]]): Unit = { val jgensig = getGenericSignature(methSymbol, claszSymbol) - val (excs, others) = symHelper(methSymbol).annotations partition (annotHelper(_).symbol == ThrowsClass) + val (excs, others) = symHelper(methSymbol).annotations partition (annotHelper(_).symbol == defn.ThrowsAnnot) val thrownExceptions: List[String] = getExceptions(excs) val bytecodeName = diff --git a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala index 7b8d1b6f293a..aa53a4935157 100644 --- a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala @@ -54,14 +54,14 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp ) lazy val BOXED_UNIT : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Void]) - lazy val BOXED_BOOLEAN : ClassBType = classBTypeFromSymbol(BoxedBooleanClass) - lazy val BOXED_BYTE : ClassBType = classBTypeFromSymbol(BoxedByteClass) - lazy val BOXED_SHORT : ClassBType = classBTypeFromSymbol(BoxedShortClass) - lazy val BOXED_CHAR : ClassBType = classBTypeFromSymbol(BoxedCharacterClass) - lazy val BOXED_INT : ClassBType = classBTypeFromSymbol(BoxedIntClass) - lazy val BOXED_LONG : ClassBType = classBTypeFromSymbol(BoxedLongClass) - lazy val BOXED_FLOAT : ClassBType = classBTypeFromSymbol(BoxedFloatClass) - lazy val BOXED_DOUBLE : ClassBType = classBTypeFromSymbol(BoxedDoubleClass) + lazy val BOXED_BOOLEAN : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Boolean]) + lazy val BOXED_BYTE : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Byte]) + lazy val BOXED_SHORT : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Short]) + lazy val BOXED_CHAR : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Character]) + lazy val BOXED_INT : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Integer]) + lazy val BOXED_LONG : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Long]) + lazy val BOXED_FLOAT : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Float]) + lazy val BOXED_DOUBLE : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Double]) /** * Map from primitive types to their boxed class type. Useful when pushing class literals onto the @@ -113,17 +113,17 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp lazy val objArrayReference : ArrayBType = ArrayBType(ObjectReference) lazy val StringRef : ClassBType = classBTypeFromSymbol(defn.StringClass) - lazy val jlStringBuilderRef : ClassBType = classBTypeFromSymbol(JavaStringBuilderClass) - lazy val jlStringBufferRef : ClassBType = classBTypeFromSymbol(JavaStringBufferClass) - lazy val jlCharSequenceRef : ClassBType = classBTypeFromSymbol(JavaCharSequenceClass) + lazy val jlStringBuilderRef : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.StringBuilder]) + lazy val jlStringBufferRef : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.StringBuffer]) + lazy val jlCharSequenceRef : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.CharSequence]) lazy val ThrowableReference : ClassBType = classBTypeFromSymbol(defn.ThrowableClass) lazy val jlCloneableReference : ClassBType = classBTypeFromSymbol(defn.JavaCloneableClass) // java/lang/Cloneable lazy val jlNPEReference : ClassBType = classBTypeFromSymbol(defn.NullPointerExceptionClass) // java/lang/NullPointerException - lazy val jioSerializableReference : ClassBType = classBTypeFromSymbol(JavaSerializableClass) // java/io/Serializable - lazy val scalaSerializableReference : ClassBType = classBTypeFromSymbol(SerializableClass) // scala/Serializable - lazy val classCastExceptionReference : ClassBType = classBTypeFromSymbol(ClassCastExceptionClass) // java/lang/ClassCastException - lazy val jlIllegalArgExceptionRef: ClassBType = classBTypeFromSymbol(IllegalArgExceptionClass) - lazy val jliSerializedLambdaRef: ClassBType = classBTypeFromSymbol(SerializedLambdaClass) + lazy val jioSerializableReference : ClassBType = classBTypeFromSymbol(requiredClass[java.io.Serializable]) // java/io/Serializable + lazy val scalaSerializableReference : ClassBType = classBTypeFromSymbol(requiredClass[scala.Serializable]) // scala/Serializable + lazy val classCastExceptionReference : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.ClassCastException]) // java/lang/ClassCastException + lazy val jlIllegalArgExceptionRef: ClassBType = classBTypeFromSymbol(requiredClass[java.lang.IllegalArgumentException]) + lazy val jliSerializedLambdaRef: ClassBType = classBTypeFromSymbol(requiredClass[java.lang.invoke.SerializedLambda]) lazy val srBooleanRef : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.BooleanRef]) lazy val srByteRef : ClassBType = classBTypeFromSymbol(requiredClass[scala.runtime.ByteRef]) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 012ee9c94108..7f8b2ba7066c 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -368,7 +368,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma (sym == defn.JavaSerializableClass) || (sym == defn.ComparableClass) || (sym derivesFrom defn.BoxedNumberClass) || - (sym derivesFrom BoxedCharacterClass) || + (sym derivesFrom defn.BoxedCharClass) || (sym derivesFrom defn.BoxedBooleanClass) } @@ -1463,35 +1463,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val ScalaATTRName: String = "Scala" val ScalaSignatureATTRName: String = "ScalaSig" - def doLabmdasFollowJVMMetafactoryOrder: Boolean = true - - val BoxedBooleanClass: Symbol = requiredClass[java.lang.Boolean] - val BoxedByteClass: Symbol = requiredClass[java.lang.Byte] - val BoxedShortClass: Symbol = requiredClass[java.lang.Short] - val BoxedCharacterClass: Symbol = requiredClass[java.lang.Character] - val BoxedIntClass: Symbol = requiredClass[java.lang.Integer] - val BoxedLongClass: Symbol = requiredClass[java.lang.Long] - val BoxedFloatClass: Symbol = requiredClass[java.lang.Float] - val BoxedDoubleClass: Symbol = requiredClass[java.lang.Double] - val StringClass: Symbol = requiredClass[java.lang.String] - val JavaStringBuilderClass: Symbol = requiredClass[java.lang.StringBuilder] - val JavaStringBufferClass: Symbol = requiredClass[java.lang.StringBuffer] - val JavaCharSequenceClass: Symbol = requiredClass[java.lang.CharSequence] - val ThrowableClass: Symbol = requiredClass[java.lang.Throwable] - val JavaCloneableClass: Symbol = requiredClass[java.lang.Cloneable] - val NullPointerExceptionClass: Symbol = requiredClass[java.lang.NullPointerException] - val JavaSerializableClass: Symbol = requiredClass[java.io.Serializable] - val SerializableClass: Symbol = requiredClass[scala.Serializable] - val ClassCastExceptionClass: Symbol = requiredClass[java.lang.ClassCastException] - val IllegalArgExceptionClass: Symbol = requiredClass[java.lang.IllegalArgumentException] - val SerializedLambdaClass: Symbol = requiredClass[java.lang.invoke.SerializedLambda] - - val ClassfileAnnotationClass: Symbol = requiredClass[scala.annotation.ClassfileAnnotation] - val BoxedNumberClass: Symbol = requiredClass[java.lang.Number] - val ThrowsClass: Symbol = requiredClass[scala.throws[_]] - // Module symbols used in backend - val StringModule: Symbol = symHelper(StringClass).linkedClassOfClass + val StringModule: Symbol = symHelper(requiredClass[java.lang.String]).linkedClassOfClass val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type] From b0a2713c038d4be3262c9fa5274661db3e229545 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 09:28:19 +0200 Subject: [PATCH 16/98] Remove custom Val/Def extractors --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 8 ++++---- .../tools/backend/jvm/BCodeSkelBuilder.scala | 13 +++++++------ .../backend/jvm/DottyBackendInterface.scala | 16 ---------------- 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 710346f0d2ee..9db6868dc23c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -264,17 +264,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case ValDefBI(_, nme.THIS, _, _) => + case ValDef(nme.THIS, _, _) => debuglog("skipping trivial assign to _$this: " + tree) - case ValDefBI(_, _, _, rhs) => + case tree@ValDef(_, _, _) => val sym = treeHelper(tree).symbol /* most of the time, !locals.contains(sym), unless the current activation of genLoad() is being called while duplicating a finalizer that contains this ValDef. */ val loc = locals.getOrMakeLocal(sym) val Local(tk, _, idx, isSynth) = loc - if (rhs == tpd.EmptyTree) { emitZeroOf(tk) } - else { genLoad(rhs, tk) } + if (tree.rhs == tpd.EmptyTree) { emitZeroOf(tk) } + else { genLoad(tree.rhs, tk) } bc.store(idx, tk) val localVarStart = currProgramPoint() if (!isSynth) { // there are case ValDef's emitted by patmat diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 59fcd46a499f..b405dbbe6631 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -448,8 +448,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { } // on entering a method - def resetMethodBookkeeping(dd: DefDef) = dd match { - case DefDefBI(_, _, _, _, _, rhs) => + def resetMethodBookkeeping(dd: DefDef) = { + val rhs = dd.rhs locals.reset(isStaticMethod = symHelper(methSymbol).isStaticMember) jumpDest = immutable.Map.empty[ /* LabelDef */ Symbol, asm.Label ] @@ -470,9 +470,9 @@ trait BCodeSkelBuilder extends BCodeHelpers { tree match { case tpd.EmptyTree => () - case ValDefBI(mods, name, tpt, rhs) => () // fields are added in `genPlainClass()`, via `addClassFields()` + case ValDef(name, tpt, rhs) => () // fields are added in `genPlainClass()`, via `addClassFields()` - case dd @ DefDefBI(_, _, _, _, _, _) => genDefDef(dd.asInstanceOf[DefDef]) + case dd: DefDef => genDefDef(dd) case TemplateBI(_, _, body) => body foreach gen @@ -510,8 +510,9 @@ trait BCodeSkelBuilder extends BCodeHelpers { } // end of method initJMethod - def genDefDef(dd: DefDef): Unit = dd match { - case DefDefBI(_, _, _, vparamss, _, rhs) => + def genDefDef(dd: DefDef): Unit = { + val rhs = dd.rhs + val vparamss = dd.vparamss // the only method whose implementation is not emitted: getClass() if (symHelper(treeHelper(dd).symbol).isGetClass) { return } assert(mnode == null, "GenBCode detected nested method.") diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 7f8b2ba7066c..93793f7c8a30 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -933,13 +933,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object ValDefBI extends ValDefDeconstructor { - def _1: Null = null - def _2: Name = field.name - def _3: Tree = field.tpt - def _4: Tree = field.rhs - } - object ThrowBI extends ThrowDeconstructor { def get: Tree = field.args.head @@ -994,15 +987,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _2: List[Tree] = field.elems } - object DefDefBI extends DefDefDeconstructor { - def _1: Null = null - def _2: Name = field.name - def _3: List[TypeDef] = field.tparams - def _4: List[List[ValDef]] = field.vparamss - def _5: Tree = field.tpt - def _6: Tree = field.rhs - } - object TemplateBI extends TemplateDeconstructor { def _1: List[Tree] = field.parents def _2: ValDef = field.self From c8cbf3606eed9794e618e526f17d1b91ec205883 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 09:34:00 +0200 Subject: [PATCH 17/98] Remove more custom extractors --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 8 +++---- .../tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../tools/backend/jvm/BCodeSyncAndTry.scala | 4 ++-- .../backend/jvm/DottyBackendInterface.scala | 24 ------------------- 4 files changed, 7 insertions(+), 31 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 9db6868dc23c..f6278ede2646 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -295,7 +295,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t @ WhileDo(_, _) => generatedType = genWhileDo(t) - case t @ TryBI(_, _, _) => + case t @ Try(_, _, _) => generatedType = genLoadTry(t) case ThrowBI(expr) => @@ -396,7 +396,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(expr, expectedType) else genBlock(blck, expectedType) - case Typed(SuperBI(_, _), _) => genLoad(ThisBI(claszSymbol), expectedType) + case Typed(Super(_, _), _) => genLoad(ThisBI(claszSymbol), expectedType) case Typed(expr, _) => genLoad(expr, expectedType) @@ -672,7 +672,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (treeHelper(t).symbol ne defn.Object_synchronized) genTypeApply(t) else genSynchronized(app, expectedType) - case Apply(fun @ SelectBI(SuperBI(_, _), _), args) => + case Apply(fun @ SelectBI(Super(_, _), _), args) => def initModule(): Unit = { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && @@ -1059,7 +1059,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) liftStringConcat(tree) match { // Optimization for expressions of the form "" + x. We can avoid the StringBuilder. - case List(Literal(ConstantBI("")), arg) => + case List(Literal(Constant("")), arg) => genLoad(arg, ObjectReference) genCallMethod(String_valueOf, InvokeStyle.Static) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index b405dbbe6631..f9cab97f001b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -83,7 +83,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* ---------------- helper utils for generating classes and fields ---------------- */ def genPlainClass(cd: ClassDef) = cd match { - case ClassDefBI(_, _, _, impl) => + case ClassDef(_, impl) => assert(cnode == null, "GenBCode detected nested methods.") innerClassBufferASM.clear() diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index 706f66c28e0b..f1bf6667548a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -174,7 +174,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { * */ def genLoadTry(tree: Try): BType = tree match { - case TryBI(block, catches, finalizer) => + case Try(block, catches, finalizer) => val kind = tpeTK(tree) val caseHandlers: List[EHClause] = @@ -408,7 +408,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { /* Does this tree have a try-catch block? */ def mayCleanStack(tree: Tree): Boolean = treeHelper(tree) exists { t => t match { - case TryBI(_, _, _) => true + case Try(_, _, _) => true case _ => false } } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 93793f7c8a30..e6faa252ce2b 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -946,10 +946,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object NewBI extends NewDeconstructor { - def get: Type = field.tpt.tpe - } - object ThisBI extends ThisDeconstructor { def get: Name = field.qual.name def apply(s: Symbol): This = tpd.This(s.asClass) @@ -960,23 +956,10 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol } - object ConstantBI extends ConstantDeconstructor { - def get: Any = field.value - } object ThrownExceptionBI extends ThrownException { def unapply(a: Annotation): Option[Symbol] = None // todo } - object TryBI extends TryDeconstructor { - def _1: Tree = field.expr - def _2: List[Tree] = field.cases - def _3: Tree = field.finalizer - } - - object SuperBI extends SuperDeconstructor { - def _1: Tree = field.qual - def _2: Name = field.mix.name - } object ArrayValueBI extends ArrayValueDeconstructor { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem @@ -995,13 +978,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma else field.constr :: field.body } - object ClassDefBI extends ClassDefDeconstructor { - def _1: Null = null - def _2: Name = field.name - def _4: Template = field.rhs.asInstanceOf[Template] - def _3: List[TypeDef] = Nil - } - object ClosureBI extends ClosureDeconstructor { def _1: List[Tree] = field.env def _2: Tree = field.meth From bc6af8400c72b8ba9737a90231cf4ce091e56c2f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 09:51:02 +0200 Subject: [PATCH 18/98] Remove some aliases --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 28 +++++++++---------- .../tools/backend/jvm/BCodeHelpers.scala | 14 +++++----- .../tools/backend/jvm/BTypesFromSymbols.scala | 4 +-- .../backend/jvm/DottyBackendInterface.scala | 16 ----------- 4 files changed, 23 insertions(+), 39 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index f6278ede2646..7aedd558aadb 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -114,7 +114,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case POS => () // nothing case NEG => bc.neg(resKind) case NOT => bc.genPrimitiveArithmetic(Primitives.NOT, resKind) - case _ => abort(s"Unknown unary operation: ${symHelper(treeHelper(fun).symbol).showFullName} code: $code") + case _ => abort(s"Unknown unary operation: ${treeHelper(fun).symbol.showFullName} code: $code") } // binary operation @@ -249,7 +249,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { coercionTo(code) } else abort( - s"Primitive operation not handled yet: ${symHelper(sym).showFullName}(${symHelper(treeHelper(fun).symbol).name}) at: ${treeHelper(tree).pos}" + s"Primitive operation not handled yet: ${sym.showFullName}(${treeHelper(fun).symbol.name}) at: ${treeHelper(tree).pos}" ) } @@ -601,7 +601,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val cast = if (sym == defn.Any_isInstanceOf) false else if (sym == defn.Any_asInstanceOf) true - else abort(s"Unexpected type application $fun[sym: ${symHelper(sym).showFullName}] in: $t") + else abort(s"Unexpected type application $fun[sym: ${sym.showFullName}] in: $t") val l = tpeTK(obj) val r = tpeTK(targs.head) genLoadQualifier(fun) @@ -706,7 +706,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // instance (on JVM, methods return VOID). case Apply(fun @ SelectBI(New(tpt), nme.CONSTRUCTOR), args) => val ctor = treeHelper(fun).symbol - assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${symHelper(ctor).name}") + assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${ctor.name}") generatedType = toTypeKind(tpt.tpe) assert(generatedType.isRef, s"Non reference type cannot be instantiated: $generatedType") @@ -716,7 +716,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { mkArrayConstructorCall(arr, app, args) case rt: ClassBType => - assert(classBTypeFromSymbol(symHelper(ctor).owner) == rt, s"Symbol ${symHelper(symHelper(ctor).owner).showFullName} is different from $rt") + assert(classBTypeFromSymbol(symHelper(ctor).owner) == rt, s"Symbol ${symHelper(ctor).owner.showFullName} is different from $rt") mnode.visitTypeInsn(asm.Opcodes.NEW, rt.internalName) bc dup generatedType genLoadArguments(args, paramTKs(app)) @@ -1116,7 +1116,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { receiver != methodOwner && // fast path - the boolean is used to pick either of these two, if they are the same it does not matter style.isVirtual && symHelper(receiver).isEmittedInterface && - symHelper(typeHelper(defn.ObjectType).decl(symHelper(method).name)).exists && { // fast path - compute overrideChain on the next line only if necessary + symHelper(typeHelper(defn.ObjectType).decl(method.name)).exists && { // fast path - compute overrideChain on the next line only if necessary val syms = symHelper(method).allOverriddenSymbols !syms.isEmpty && symHelper(syms.last).owner == defn.ObjectClass } @@ -1317,16 +1317,16 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * not using the rich equality is possible (their own equals method will do ok.) */ val mustUseAnyComparator: Boolean = { - val areSameFinals = typeHelper(treeHelper(l).tpe).isFinalType && typeHelper(treeHelper(r).tpe).isFinalType && (typeHelper(treeHelper(l).tpe) =:= treeHelper(r).tpe) + val areSameFinals = typeHelper(treeHelper(l).tpe).isFinalType && typeHelper(treeHelper(r).tpe).isFinalType && (treeHelper(l).tpe =:= treeHelper(r).tpe) !areSameFinals && isMaybeBoxed(typeHelper(treeHelper(l).tpe).typeSymbol) && isMaybeBoxed(typeHelper(treeHelper(r).tpe).typeSymbol) } if (mustUseAnyComparator) { val equalsMethod: Symbol = { - if (typeHelper(treeHelper(l).tpe) <:< symHelper(defn.BoxedNumberClass).tpe) { - if (typeHelper(treeHelper(r).tpe) <:< symHelper(defn.BoxedNumberClass).tpe) externalEqualsNumNum - else if (typeHelper(treeHelper(r).tpe) <:< symHelper(defn.BoxedCharClass).tpe) externalEqualsNumChar + if (treeHelper(l).tpe <:< symHelper(defn.BoxedNumberClass).tpe) { + if (treeHelper(r).tpe <:< symHelper(defn.BoxedNumberClass).tpe) externalEqualsNumNum + else if (treeHelper(r).tpe <:< symHelper(defn.BoxedCharClass).tpe) externalEqualsNumChar else externalEqualsNumObject } else externalEquals } @@ -1398,7 +1398,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val targetHandle = new asm.Handle(invokeStyle, classBTypeFromSymbol(symHelper(lambdaTarget).owner).internalName, - nameHelper(symHelper(lambdaTarget).name).mangledString, + nameHelper(lambdaTarget.name).mangledString, asmMethodType(lambdaTarget).descriptor, /* itf = */ isInterface) @@ -1408,13 +1408,13 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = symHelper(symHelper(lambdaTarget).owner).info :: capturedParamsTypes // Requires https://github.com/scala/scala-java8-compat on the runtime classpath - val returnUnit = typeHelper(typeHelper(symHelper(lambdaTarget).info).resultType).typeSymbol == defn.UnitClass + val returnUnit = typeHelper(symHelper(lambdaTarget).info.resultType).typeSymbol == defn.UnitClass val functionalInterfaceDesc: String = generatedType.descriptor val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc // TODO specialization - val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(typeHelper(symHelper(lambdaTarget).tpe).resultType)).toASMType + val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(symHelper(lambdaTarget).tpe.resultType)).toASMType val abstractMethod = symHelper(functionalInterface).samMethod() - val methodName = nameHelper(symHelper(abstractMethod).name).mangledString + val methodName = nameHelper(abstractMethod.name).mangledString val applyN = { val mt = asmMethodType(abstractMethod) mt.toASMType diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 4e9a5fea75c1..98e9fa5476c7 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -241,7 +241,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { assert(symHelper(msym).isMethod, s"not a method-symbol: $msym") val resT: BType = if (symHelper(msym).isClassConstructor || symHelper(msym).isConstructor) UNIT - else toTypeKind(typeHelper(symHelper(msym).tpe).resultType) + else toTypeKind(symHelper(msym).tpe.resultType) MethodBType(typeHelper(symHelper(msym).tpe).paramTypes map toTypeKind, resT) } @@ -311,7 +311,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ private def addForwarder(jclass: asm.ClassVisitor, module: Symbol, m: Symbol): Unit = { val moduleName = internalName(module) - val methodInfo = typeHelper(symHelper(module).thisType).memberInfo(m) + val methodInfo = symHelper(module).thisType.memberInfo(m) val paramJavaTypes: List[BType] = typeHelper(methodInfo).paramTypes map toTypeKind // val paramNames = 0 until paramJavaTypes.length map ("x_" + _) @@ -330,7 +330,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val (throws, others) = symHelper(m).annotations partition (annotHelper(_).symbol == defn.ThrowsAnnot) val thrownExceptions: List[String] = getExceptions(throws) - val jReturnType = toTypeKind(typeHelper(methodInfo).resultType) + val jReturnType = toTypeKind(methodInfo.resultType) val mdesc = MethodBType(paramJavaTypes, jReturnType).descriptor val mirrorMethodName = symHelper(m).javaSimpleName.toString val mirrorMethod: asm.MethodVisitor = jclass.visitMethod( @@ -376,7 +376,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val linkedClass = symHelper(moduleClass).companionClass lazy val conflictingNames: Set[Name] = { - (typeHelper(symHelper(linkedClass).info).members collect { case sym if nameHelper(symHelper(sym).name).isTermName => symHelper(sym).name }).toSet + (typeHelper(symHelper(linkedClass).info).members collect { case sym if nameHelper(sym.name).isTermName => sym.name }).toSet } debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") @@ -386,8 +386,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") else if (symHelper(m).isType || symHelper(m).isDeferred || (symHelper(m).owner eq defn.ObjectClass) || symHelper(m).isConstructor || symHelper(m).isExpanded) debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") - else if (conflictingNames(symHelper(m).name)) - log(s"No forwarder for $m due to conflict with ${typeHelper(symHelper(linkedClass).info).member(symHelper(m).name)}") + else if (conflictingNames(m.name)) + log(s"No forwarder for $m due to conflict with ${typeHelper(symHelper(linkedClass).info).member(m.name)}") else if (symHelper(m).hasAccessBoundary) log(s"No forwarder for non-public member $m") else { @@ -494,7 +494,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { mirrorClass.visitEnd() - symHelper(moduleClass).name // this side-effect is necessary, really. + moduleClass.name // this side-effect is necessary, really. mirrorClass } diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 8535c23648a1..30abcf4ee59d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -51,7 +51,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { assert( (!primitiveTypeMap.contains(classSym) || isCompilingPrimitive) && (classSym != defn.NothingClass && classSym != defn.NullClass), - s"Cannot create ClassBType for special class symbol ${symHelper(classSym).showFullName}") + s"Cannot create ClassBType for special class symbol ${classSym.showFullName}") convertedClasses.getOrElse(classSym, { val internalName = symHelper(classSym).javaBinaryName @@ -127,7 +127,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (symHelper(s).isJavaDefined && symHelper(s).isModuleClass) { // We could also search in nestedClassSymbols for s.linkedClassOfClass, but sometimes that // returns NoSymbol, so it doesn't work. - val nb = nestedClassSymbols.count(mc => symHelper(mc).name == symHelper(s).name && symHelper(mc).owner == symHelper(s).owner) + val nb = nestedClassSymbols.count(mc => mc.name == s.name && symHelper(mc).owner == symHelper(s).owner) // this assertion is specific to how ScalaC works. It doesn't apply to dotty, as n dotty there will be B & B$ // assert(nb == 2, s"Java member module without member class: $s - $nestedClassSymbols") false diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index e6faa252ce2b..c02a536e7f26 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -544,11 +544,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def exists: Boolean = sym.exists // names - def showFullName: String = sym.showFullName def javaSimpleName: String = toDenot(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 def rawname: String = { val original = toDenot(sym).initial sym.name(ctx.withPhase(original.validFor.phaseId)).mangledString @@ -793,10 +791,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def paramTypes: List[Type] = tp.firstParamTypes - def <:<(other: Type): Boolean = tp <:< other - - def memberInfo(s: Symbol): Type = tp.memberInfo(s) - def decl(name: Name): Symbol = tp.decl(name).symbol def decls: List[Symbol] = tp.decls.toList @@ -805,8 +799,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def typeSymbol: Symbol = tp.widenDealias.typeSymbol - def =:=(other: Type): Boolean = tp =:= other - def sortedMembersBasedOnFlags(required: Flags, excluded: Flags): List[Symbol] = { val requiredFlagSet = termFlagSet(required) val excludedFlagSet = termFlagSet(excluded) @@ -820,8 +812,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma buffer.toList } - def resultType: Type = tp.resultType - def toTypeKind(ct: BCodeHelpers)(storage: ct.BCInnerClassGen): ct.bTypes.BType = { import ct.bTypes._ val defn = ctx.definitions @@ -1199,11 +1189,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def exists: Boolean // names - def showFullName: String def javaSimpleName: String def javaBinaryName: String def javaClassName: String - def name: Name def rawname: String // types @@ -1351,12 +1339,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } abstract class TypeHelper { - def <:<(other: Type): Boolean - def =:=(other: Type): Boolean def paramTypes: List[Type] def params: List[Symbol] - def resultType: Type - def memberInfo(s: Symbol): Type /** The members of this type that have all of `required` flags but none of `excluded` flags set. * The members are sorted by name and signature to guarantee a stable ordering. From cbad7665d0c93fba9f2bf7c046291aafa14cb810 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 09:53:44 +0200 Subject: [PATCH 19/98] Remove constantHelper --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 42 +++++++++---------- .../backend/jvm/DottyBackendInterface.scala | 16 ------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 7aedd558aadb..2f957657c16f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -191,7 +191,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val failure = new asm.Label val hasElse = !treeHelper(elsep).isEmpty && (elsep match { - case Literal(value) if constantHelper(value).tag == UnitTag => false + case Literal(value) if value.tag == UnitTag => false case _ => true }) val postIf = if (hasElse) new asm.Label else failure @@ -384,9 +384,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } case Literal(value) => - if (constantHelper(value).tag != UnitTag) (constantHelper(value).tag, expectedType) match { - case (IntTag, LONG ) => bc.lconst(constantHelper(value).longValue); generatedType = LONG - case (FloatTag, DOUBLE) => bc.dconst(constantHelper(value).doubleValue); generatedType = DOUBLE + if (value.tag != UnitTag) (value.tag, expectedType) match { + case (IntTag, LONG ) => bc.lconst(value.longValue); generatedType = LONG + case (FloatTag, DOUBLE) => bc.dconst(value.doubleValue); generatedType = DOUBLE case (NullTag, _ ) => bc.emit(asm.Opcodes.ACONST_NULL); generatedType = RT_NULL case _ => genConstant(value); generatedType = tpeTK(tree) } @@ -463,35 +463,35 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * Otherwise it's safe to call from multiple threads. */ def genConstant(const: Constant): Unit = { - (constantHelper(const).tag/*: @switch*/) match { + (const.tag/*: @switch*/) match { - case BooleanTag => bc.boolconst(constantHelper(const).booleanValue) + case BooleanTag => bc.boolconst(const.booleanValue) - case ByteTag => bc.iconst(constantHelper(const).byteValue) - case ShortTag => bc.iconst(constantHelper(const).shortValue) - case CharTag => bc.iconst(constantHelper(const).charValue) - case IntTag => bc.iconst(constantHelper(const).intValue) + case ByteTag => bc.iconst(const.byteValue) + case ShortTag => bc.iconst(const.shortValue) + case CharTag => bc.iconst(const.charValue) + case IntTag => bc.iconst(const.intValue) - case LongTag => bc.lconst(constantHelper(const).longValue) - case FloatTag => bc.fconst(constantHelper(const).floatValue) - case DoubleTag => bc.dconst(constantHelper(const).doubleValue) + case LongTag => bc.lconst(const.longValue) + case FloatTag => bc.fconst(const.floatValue) + case DoubleTag => bc.dconst(const.doubleValue) case UnitTag => () case StringTag => - assert(constantHelper(const).value != null, const) // TODO this invariant isn't documented in `case class Constant` - mnode.visitLdcInsn(constantHelper(const).stringValue) // `stringValue` special-cases null, but not for a const with StringTag + assert(const.value != null, const) // TODO this invariant isn't documented in `case class Constant` + mnode.visitLdcInsn(const.stringValue) // `stringValue` special-cases null, but not for a const with StringTag case NullTag => emit(asm.Opcodes.ACONST_NULL) case ClazzTag => - val tp = toTypeKind(constantHelper(const).typeValue) + val tp = toTypeKind(const.typeValue) // classOf[Int] is transformed to Integer.TYPE by ClassOf assert(!tp.isPrimitive, s"expected class type in classOf[T], found primitive type $tp") mnode.visitLdcInsn(tp.toASMType) case EnumTag => - val sym = constantHelper(const).symbolValue + val sym = const.symbolValue val ownerName = internalName(symHelper(sym).owner) val fieldName = symHelper(sym).javaSimpleName.toString val fieldDesc = toTypeKind(typeHelper(symHelper(sym).tpe).underlying).descriptor @@ -571,7 +571,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { RT_NOTHING } else { val hasBody = cond match { - case Literal(value) if constantHelper(value).tag == UnitTag => false + case Literal(value) if value.tag == UnitTag => false case _ => true } @@ -665,7 +665,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case Apply(_, args) if isSyntheticArrayConstructor(treeHelper(app).symbol) => val List(elemClaz, Literal(c: Constant), ArrayValueBI(_, dims)) = args - generatedType = toTypeKind(constantHelper(c).typeValue) + generatedType = toTypeKind(c.typeValue) mkArrayConstructorCall(generatedType.asArrayBType, app, dims) case Apply(t :TypeApply, _) => generatedType = @@ -852,7 +852,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { switchBlocks ::= (switchBlockPoint, body) pat match { case Literal(value) => - flatKeys ::= constantHelper(value).intValue + flatKeys ::= value.intValue targets ::= switchBlockPoint case Ident(nme.WILDCARD) => assert(default == null, s"multiple default targets in a Match node, at ${treeHelper(tree).pos}") @@ -860,7 +860,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case Alternative(alts) => alts foreach { case Literal(value) => - flatKeys ::= constantHelper(value).intValue + flatKeys ::= value.intValue targets ::= switchBlockPoint case _ => abort(s"Invalid alternative in alternative pattern in Match node: $tree at: ${treeHelper(tree).pos}") diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index c02a536e7f26..7614d70c98db 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -479,22 +479,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def finalPosition: Position = a } - implicit def constantHelper(a: Constant): ConstantHelper = new ConstantHelper { - def booleanValue: Boolean = a.booleanValue - def longValue: Long = a.longValue - def byteValue: Byte = a.byteValue - def stringValue: String = a.stringValue - def symbolValue: Symbol = a.symbolValue - def floatValue: Float = a.floatValue - def value: Any = a.value - def tag: ConstantTag = a.tag - def typeValue: Type = a.typeValue - def shortValue: Short = a.shortValue - def intValue: Int = a.intValue - def doubleValue: Double = a.doubleValue - def charValue: Char = a.charValue - } - implicit def treeHelper(a: Tree): TreeHelper = new TreeHelper { def symbol: Symbol = a.symbol From 2fe7de6e0b967174c04b787934c5d880e4188bbe Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 10:02:59 +0200 Subject: [PATCH 20/98] Remove treeHelper --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 116 +++++++++--------- .../tools/backend/jvm/BCodeSkelBuilder.scala | 26 ++-- .../tools/backend/jvm/BCodeSyncAndTry.scala | 15 +-- .../backend/jvm/DottyBackendInterface.scala | 22 +--- 4 files changed, 80 insertions(+), 99 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 2f957657c16f..133a29d1dfe9 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -64,16 +64,16 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { tree match { case Assign(lhs @ SelectBI(qual, _), rhs) => - val isStatic = symHelper(treeHelper(lhs).symbol).isStaticMember + val isStatic = symHelper(lhs.symbol).isStaticMember if (!isStatic) { genLoadQualifier(lhs) } - genLoad(rhs, symInfoTK(treeHelper(lhs).symbol)) + genLoad(rhs, symInfoTK(lhs.symbol)) lineNumber(tree) // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError - val receiverClass = typeHelper(treeHelper(qual).tpe).typeSymbol - fieldStore(treeHelper(lhs).symbol, receiverClass) + val receiverClass = typeHelper(qual.tpe).typeSymbol + fieldStore(lhs.symbol, receiverClass) case Assign(lhs, rhs) => - val s = treeHelper(lhs).symbol + val s = lhs.symbol val Local(tk, _, idx, _) = locals.getOrMakeLocal(s) genLoad(rhs, tk) lineNumber(tree) @@ -102,7 +102,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var resKind = tpeTK(larg) assert(resKind.isNumericType || (resKind == BOOL), - s"$resKind is not a numeric or boolean type [operation: ${treeHelper(fun).symbol}]") + s"$resKind is not a numeric or boolean type [operation: ${fun.symbol}]") import ScalaPrimitivesOps._ @@ -114,7 +114,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case POS => () // nothing case NEG => bc.neg(resKind) case NOT => bc.genPrimitiveArithmetic(Primitives.NOT, resKind) - case _ => abort(s"Unknown unary operation: ${treeHelper(fun).symbol.showFullName} code: $code") + case _ => abort(s"Unknown unary operation: ${fun.symbol.showFullName} code: $code") } // binary operation @@ -141,7 +141,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case LSL | LSR | ASR => bc.genPrimitiveShift(code, resKind) - case _ => abort(s"Unknown primitive: ${treeHelper(fun).symbol}[$code]") + case _ => abort(s"Unknown primitive: ${fun.symbol}[$code]") } case _ => @@ -190,7 +190,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val success = new asm.Label val failure = new asm.Label - val hasElse = !treeHelper(elsep).isEmpty && (elsep match { + val hasElse = !elsep.isEmpty && (elsep match { case Literal(value) if value.tag == UnitTag => false case _ => true }) @@ -217,9 +217,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genPrimitiveOp(tree: Apply, expectedType: BType): BType = tree match { case Apply(fun @ SelectBI(receiver, _), _) => - val sym = treeHelper(tree).symbol + val sym = tree.symbol - val code = primitives.getPrimitive(tree, treeHelper(receiver).tpe) + val code = primitives.getPrimitive(tree, receiver.tpe) import ScalaPrimitivesOps._ @@ -249,7 +249,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { coercionTo(code) } else abort( - s"Primitive operation not handled yet: ${sym.showFullName}(${treeHelper(fun).symbol.name}) at: ${treeHelper(tree).pos}" + s"Primitive operation not handled yet: ${sym.showFullName}(${fun.symbol.name}) at: ${tree.span}" ) } @@ -268,7 +268,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { debuglog("skipping trivial assign to _$this: " + tree) case tree@ValDef(_, _, _) => - val sym = treeHelper(tree).symbol + val sym = tree.symbol /* most of the time, !locals.contains(sym), unless the current activation of genLoad() is being called while duplicating a finalizer that contains this ValDef. */ val loc = locals.getOrMakeLocal(sym) @@ -312,7 +312,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t @ Ident(_) => (t, Nil) } - if (!symHelper(treeHelper(fun).symbol).isStaticMember) { + if (!symHelper(fun.symbol).isStaticMember) { // load receiver of non-static implementation of lambda // darkdimius: I haven't found in spec `this` reference should go @@ -323,39 +323,39 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(prefix) } - genLoadArguments(env, typeHelper(symHelper(treeHelper(fun).symbol).info).paramTypes map toTypeKind) - generatedType = genInvokeDynamicLambda(NoSymbol, treeHelper(fun).symbol, env.size, functionalInterface) + genLoadArguments(env, typeHelper(symHelper(fun.symbol).info).paramTypes map toTypeKind) + generatedType = genInvokeDynamicLambda(NoSymbol, fun.symbol, env.size, functionalInterface) case app @ Apply(_, _) => generatedType = genApply(app, expectedType) case ThisBI(qual) => - val symIsModuleClass = symHelper(treeHelper(tree).symbol).isModuleClass - assert(treeHelper(tree).symbol == claszSymbol || symIsModuleClass, - s"Trying to access the this of another class: tree.symbol = ${treeHelper(tree).symbol}, class symbol = $claszSymbol compilation unit: $cunit") - if (symIsModuleClass && treeHelper(tree).symbol != claszSymbol) { + val symIsModuleClass = symHelper(tree.symbol).isModuleClass + assert(tree.symbol == claszSymbol || symIsModuleClass, + s"Trying to access the this of another class: tree.symbol = ${tree.symbol}, class symbol = $claszSymbol compilation unit: $cunit") + if (symIsModuleClass && tree.symbol != claszSymbol) { generatedType = genLoadModule(tree) } else { mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) generatedType = - if (treeHelper(tree).symbol == defn.ArrayClass) ObjectReference + if (tree.symbol == defn.ArrayClass) ObjectReference else classBTypeFromSymbol(claszSymbol) } case SelectBI(Ident(nme.EMPTY_PACKAGE), module) => - assert(symHelper(treeHelper(tree).symbol).isModule, s"Selection of non-module from empty package: $tree sym: ${treeHelper(tree).symbol} at: ${treeHelper(tree).pos}") + assert(symHelper(tree.symbol).isModule, s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.span}") genLoadModule(tree) case SelectBI(qualifier, _) => - val sym = treeHelper(tree).symbol + val sym = tree.symbol generatedType = symInfoTK(sym) val qualSafeToElide = isQualifierSafeToElide(qualifier) def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } } // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError - def receiverClass = typeHelper(treeHelper(qualifier).tpe).typeSymbol + def receiverClass = typeHelper(qualifier.tpe).typeSymbol if (symHelper(sym).isModule) { genLoadQualUnlessElidable() genLoadModule(tree) @@ -368,7 +368,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } case t @ Ident(name) => - val sym = treeHelper(tree).symbol + val sym = tree.symbol val tk = symInfoTK(sym) generatedType = tk @@ -416,7 +416,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t: TypeApply => // dotty specific generatedType = genTypeApply(t) - case _ => abort(s"Unexpected tree in genLoad: $tree/${tree.getClass} at: ${treeHelper(tree).pos}") + case _ => abort(s"Unexpected tree in genLoad: $tree/${tree.getClass} at: ${tree.span}") } // emit conversion @@ -511,7 +511,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val resKind = tpeTK(tree) genLoad(expr, resKind) - markProgramPoint(programPoint(treeHelper(bind).symbol)) + markProgramPoint(programPoint(bind.symbol)) resKind } @@ -534,7 +534,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (saveReturnValue) { // regarding return value, the protocol is: in place of a `return-stmt`, a sequence of `adapt, store, jump` are inserted. if (earlyReturnVar == null) { - earlyReturnVar = locals.makeLocal(returnType, "earlyReturnVar", treeHelper(expr).tpe, treeHelper(expr).pos) + earlyReturnVar = locals.makeLocal(returnType, "earlyReturnVar", expr.tpe, expr.span) } locals.store(earlyReturnVar) } @@ -597,7 +597,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genTypeApply(t: TypeApply): BType = t match { case TypeApply(fun@SelectBI(obj, _), targs) => - val sym = treeHelper(fun).symbol + val sym = fun.symbol val cast = if (sym == defn.Any_isInstanceOf) false else if (sym == defn.Any_asInstanceOf) true @@ -639,7 +639,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var elemKind = arr.elementType val argsSize = args.length if (argsSize > dims) { - error(treeHelper(app).pos, s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)") + error(app.span, s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)") } if (argsSize < dims) { /* In one step: @@ -662,14 +662,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var generatedType = expectedType lineNumber(app) app match { - case Apply(_, args) if isSyntheticArrayConstructor(treeHelper(app).symbol) => + case Apply(_, args) if isSyntheticArrayConstructor(app.symbol) => val List(elemClaz, Literal(c: Constant), ArrayValueBI(_, dims)) = args generatedType = toTypeKind(c.typeValue) mkArrayConstructorCall(generatedType.asArrayBType, app, dims) case Apply(t :TypeApply, _) => generatedType = - if (treeHelper(t).symbol ne defn.Object_synchronized) genTypeApply(t) + if (t.symbol ne defn.Object_synchronized) genTypeApply(t) else genSynchronized(app, expectedType) case Apply(fun @ SelectBI(Super(_, _), _), args) => @@ -677,7 +677,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && jMethodName == INSTANCE_CONSTRUCTOR_NAME && - symHelper(treeHelper(fun).symbol).javaSimpleName.toString == INSTANCE_CONSTRUCTOR_NAME && + symHelper(fun.symbol).javaSimpleName.toString == INSTANCE_CONSTRUCTOR_NAME && symHelper(claszSymbol).isStaticModuleClass) { isModuleInitialized = true mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) @@ -697,7 +697,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // on the stack (contrary to what the type in the AST says). mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) genLoadArguments(args, paramTKs(app)) - generatedType = genCallMethod(treeHelper(fun).symbol, InvokeStyle.Super, treeHelper(app).pos) + generatedType = genCallMethod(fun.symbol, InvokeStyle.Super, app.span) initModule() // 'new' constructor call: Note: since constructors are @@ -705,7 +705,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // we have to 'simulate' it by DUPlicating the freshly created // instance (on JVM, methods return VOID). case Apply(fun @ SelectBI(New(tpt), nme.CONSTRUCTOR), args) => - val ctor = treeHelper(fun).symbol + val ctor = fun.symbol assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${ctor.name}") generatedType = toTypeKind(tpt.tpe) @@ -720,28 +720,28 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { mnode.visitTypeInsn(asm.Opcodes.NEW, rt.internalName) bc dup generatedType genLoadArguments(args, paramTKs(app)) - genCallMethod(ctor, InvokeStyle.Special, treeHelper(app).pos) + genCallMethod(ctor, InvokeStyle.Special, app.span) case _ => abort(s"Cannot instantiate $tpt of kind: $generatedType") } - case Apply(fun, List(expr)) if isBox(treeHelper(fun).symbol) => + case Apply(fun, List(expr)) if isBox(fun.symbol) => val nativeKind = tpeTK(expr) genLoad(expr, nativeKind) val MethodNameAndType(mname, methodType) = asmBoxTo(nativeKind) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) - generatedType = boxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.tpe.resultType) + generatedType = boxResultType(fun.symbol) // was toTypeKind(fun.symbol.tpe.resultType) - case Apply(fun, List(expr)) if isUnbox(treeHelper(fun).symbol) => + case Apply(fun, List(expr)) if isUnbox(fun.symbol) => genLoad(expr) - val boxType = unboxResultType(treeHelper(fun).symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) + val boxType = unboxResultType(fun.symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) generatedType = boxType val MethodNameAndType(mname, methodType) = asmUnboxTo(boxType) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) case app @ Apply(fun, args) => - val sym = treeHelper(fun).symbol + val sym = fun.symbol if (isPrimitive(fun)) { // primitive method call generatedType = genPrimitiveOp(app, expectedType) @@ -777,7 +777,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val receiverClass = if (!invokeStyle.isVirtual) null else { // receiverClass is used in the bytecode to as the method receiver. using sym.owner // may lead to IllegalAccessErrors, see 9954eaf / aladdin bug 455. - val qualSym = typeHelper(treeHelper(qual).tpe).typeSymbol + val qualSym = typeHelper(qual.tpe).typeSymbol if (qualSym == defn.ArrayClass) { // For invocations like `Array(1).hashCode` or `.wait()`, use Object as receiver // in the bytecode. Using the array descriptor (like we do for clone above) seems @@ -787,7 +787,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { defn.ObjectClass } else qualSym } - generatedType = genCallMethod(sym, invokeStyle, treeHelper(app).pos, receiverClass) + generatedType = genCallMethod(sym, invokeStyle, app.span, receiverClass) } } } @@ -855,7 +855,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { flatKeys ::= value.intValue targets ::= switchBlockPoint case Ident(nme.WILDCARD) => - assert(default == null, s"multiple default targets in a Match node, at ${treeHelper(tree).pos}") + assert(default == null, s"multiple default targets in a Match node, at ${tree.span}") default = switchBlockPoint case Alternative(alts) => alts foreach { @@ -863,10 +863,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { flatKeys ::= value.intValue targets ::= switchBlockPoint case _ => - abort(s"Invalid alternative in alternative pattern in Match node: $tree at: ${treeHelper(tree).pos}") + abort(s"Invalid alternative in alternative pattern in Match node: $tree at: ${tree.span}") } case _ => - abort(s"Invalid pattern in Match node: $tree at: ${treeHelper(tree).pos}") + abort(s"Invalid pattern in Match node: $tree at: ${tree.span}") } } @@ -987,7 +987,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { desugarIdent(t) match { case Some(sel) => genLoadQualifier(sel) case None => - assert(symHelper(treeHelper(t).symbol).owner == this.claszSymbol) + assert(symHelper(t.symbol).owner == this.claszSymbol) } case _ => abort(s"Unknown qualifier $tree") } @@ -999,8 +999,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(tree: Tree): BType = { val module = ( - if (!symHelper(treeHelper(tree).symbol).isPackageClass) treeHelper(tree).symbol - else typeHelper(symHelper(treeHelper(tree).symbol).info).member(nme.PACKAGE) match { + if (!symHelper(tree.symbol).isPackageClass) tree.symbol + else typeHelper(symHelper(tree.symbol).info).member(nme.PACKAGE) match { case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree") case s => abort(s"SI-5604: found package class where package object expected: $tree") } @@ -1067,7 +1067,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { bc.genStartConcat for (elem <- concatenations) { val loadedElem = elem match { - case Apply(boxOp, value :: Nil) if isBox(treeHelper(boxOp).symbol) => + case Apply(boxOp, value :: Nil) if isBox(boxOp.symbol) => // Eliminate boxing of primitive values. Boxing is introduced by erasure because // there's only a single synthetic `+` method "added" to the string class. value @@ -1162,7 +1162,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def liftStringConcat(tree: Tree): List[Tree] = tree match { case tree @ Apply(fun @ SelectBI(larg, method), rarg) => if (isPrimitive(fun) && - primitives.getPrimitive(tree, treeHelper(larg).tpe) == ScalaPrimitivesOps.CONCAT) + primitives.getPrimitive(tree, larg.tpe) == ScalaPrimitivesOps.CONCAT) liftStringConcat(larg) ::: rarg else tree :: Nil @@ -1281,7 +1281,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genCond(rhs, success, failure, targetIfNoJump) } - primitives.getPrimitive(tree, treeHelper(lhs).tpe) match { + primitives.getPrimitive(tree, lhs.tpe) match { case ZNOT => genCond(lhs, failure, success, targetIfNoJump) case ZAND => genZandOrZor(and = true) case ZOR => genZandOrZor(and = false) @@ -1317,16 +1317,16 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * not using the rich equality is possible (their own equals method will do ok.) */ val mustUseAnyComparator: Boolean = { - val areSameFinals = typeHelper(treeHelper(l).tpe).isFinalType && typeHelper(treeHelper(r).tpe).isFinalType && (treeHelper(l).tpe =:= treeHelper(r).tpe) + val areSameFinals = typeHelper(l.tpe).isFinalType && typeHelper(r.tpe).isFinalType && (l.tpe =:= r.tpe) - !areSameFinals && isMaybeBoxed(typeHelper(treeHelper(l).tpe).typeSymbol) && isMaybeBoxed(typeHelper(treeHelper(r).tpe).typeSymbol) + !areSameFinals && isMaybeBoxed(typeHelper(l.tpe).typeSymbol) && isMaybeBoxed(typeHelper(r.tpe).typeSymbol) } if (mustUseAnyComparator) { val equalsMethod: Symbol = { - if (treeHelper(l).tpe <:< symHelper(defn.BoxedNumberClass).tpe) { - if (treeHelper(r).tpe <:< symHelper(defn.BoxedNumberClass).tpe) externalEqualsNumNum - else if (treeHelper(r).tpe <:< symHelper(defn.BoxedCharClass).tpe) externalEqualsNumChar + if (l.tpe <:< symHelper(defn.BoxedNumberClass).tpe) { + if (r.tpe <:< symHelper(defn.BoxedNumberClass).tpe) externalEqualsNumNum + else if (r.tpe <:< symHelper(defn.BoxedCharClass).tpe) externalEqualsNumChar else externalEqualsNumObject } else externalEquals } @@ -1353,7 +1353,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genCZJUMP(success, failure, Primitives.NE, BOOL, targetIfNoJump) } else { // l == r -> if (l eq null) r eq null else l.equals(r) - val eqEqTempLocal = locals.makeLocal(ObjectReference, nameHelper(nme.EQEQ_LOCAL_VAR).mangledString, defn.ObjectType, treeHelper(r).pos) + val eqEqTempLocal = locals.makeLocal(ObjectReference, nameHelper(nme.EQEQ_LOCAL_VAR).mangledString, defn.ObjectType, r.span) val lNull = new asm.Label val lNonNull = new asm.Label diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index f9cab97f001b..afb1956c1856 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -68,7 +68,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def paramTKs(app: Apply, take: Int = -1): List[BType] = app match { case Apply(fun, _) => - val funSym = treeHelper(fun).symbol + val funSym = fun.symbol (typeHelper(symHelper(funSym).info).paramTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) } @@ -76,7 +76,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { toTypeKind(symHelper(sym).info) // this tracks mentioned inner classes (in innerClassBufferASM) } - def tpeTK(tree: Tree): BType = { toTypeKind(treeHelper(tree).tpe) } + def tpeTK(tree: Tree): BType = { toTypeKind(tree.tpe) } override def getCurrentCUnit(): CompilationUnit = { cunit } @@ -87,7 +87,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { assert(cnode == null, "GenBCode detected nested methods.") innerClassBufferASM.clear() - claszSymbol = treeHelper(cd).symbol + claszSymbol = cd.symbol isCZParcelable = isAndroidParcelableClass(claszSymbol) isCZStaticModule = symHelper(claszSymbol).isStaticModuleClass thisName = internalName(claszSymbol) @@ -96,7 +96,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { initJClass(cnode) - val hasStaticCtor = symHelper(treeHelper(cd).symbol).methodSymbols exists (symHelper(_).isStaticConstructor) + val hasStaticCtor = symHelper(cd.symbol).methodSymbols exists (symHelper(_).isStaticConstructor) if (!hasStaticCtor) { // but needs one ... if (isCZStaticModule || isCZParcelable) { @@ -117,7 +117,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { AsmUtils.traceClass(cnode) cnode.innerClasses - assert(treeHelper(cd).symbol == claszSymbol, "Someone messed up BCodePhase.claszSymbol during genPlainClass().") + assert(cd.symbol == claszSymbol, "Someone messed up BCodePhase.claszSymbol during genPlainClass().") } // end of method genPlainClass() @@ -433,8 +433,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { case _ => false } ) } def lineNumber(tree: Tree): Unit = { - if (!emitLines || !positionHelper(treeHelper(tree).pos).isDefined) return; - val nr = positionHelper(positionHelper(treeHelper(tree).pos).finalPosition).line + if (!emitLines || !positionHelper(tree.span).isDefined) return; + val nr = positionHelper(positionHelper(tree.span).finalPosition).line if (nr != lastEmittedLineNr) { lastEmittedLineNr = nr lastInsn match { @@ -514,12 +514,12 @@ trait BCodeSkelBuilder extends BCodeHelpers { val rhs = dd.rhs val vparamss = dd.vparamss // the only method whose implementation is not emitted: getClass() - if (symHelper(treeHelper(dd).symbol).isGetClass) { return } + if (symHelper(dd.symbol).isGetClass) { return } assert(mnode == null, "GenBCode detected nested method.") - methSymbol = treeHelper(dd).symbol + methSymbol = dd.symbol jMethodName = symHelper(methSymbol).javaSimpleName.toString - returnType = asmMethodType(treeHelper(dd).symbol).returnType + returnType = asmMethodType(dd.symbol).returnType isMethSymStaticCtor = symHelper(methSymbol).isStaticConstructor resetMethodBookkeeping(dd) @@ -528,7 +528,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { assert(vparamss.isEmpty || vparamss.tail.isEmpty, s"Malformed parameter list: $vparamss") val params = if (vparamss.isEmpty) Nil else vparamss.head - for (p <- params) { locals.makeLocal(treeHelper(p).symbol) } + for (p <- params) { locals.makeLocal(p.symbol) } // debug assert((params.map(p => locals(p.symbol).tk)) == asmMethodType(methSymbol).getArgumentTypes.toList, "debug") if (params.size > MaximumJvmParameters) { @@ -547,7 +547,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { ) // TODO needed? for(ann <- m.symbol.annotations) { ann.symbol.initialize } - initJMethod(flags, params.map(p => symHelper(treeHelper(p).symbol).annotations)) + initJMethod(flags, params.map(p => symHelper(p.symbol).annotations)) if (!isAbstractMethod && !isNative) { @@ -580,7 +580,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { 0 ) } - for (p <- params) { emitLocalVarScope(treeHelper(p).symbol, veryFirstProgramPoint, onePastLastProgramPoint, force = true) } + for (p <- params) { emitLocalVarScope(p.symbol, veryFirstProgramPoint, onePastLastProgramPoint, force = true) } } if (isMethSymStaticCtor) { appendToStaticCtor(dd) } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index f1bf6667548a..a35bc15826b4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -8,6 +8,7 @@ import scala.tools.asm import dotty.tools.dotc.core.StdNames.nme import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.ast.tpd.TreeOps /* * @@ -26,13 +27,13 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { def genSynchronized(tree: Apply, expectedType: BType): BType = tree match { case Apply(TypeApply(fun, _), args) => - val monitor = locals.makeLocal(ObjectReference, "monitor", defn.ObjectType, treeHelper(tree).pos) + val monitor = locals.makeLocal(ObjectReference, "monitor", defn.ObjectType, tree.span) val monCleanup = new asm.Label // if the synchronized block returns a result, store it in a local variable. // Just leaving it on the stack is not valid in MSIL (stack is cleaned when leaving try-blocks). val hasResult = (expectedType != UNIT) - val monitorResult: Symbol = if (hasResult) locals.makeLocal(tpeTK(args.head), "monitorResult", defn.ObjectType, treeHelper(tree).pos) else null + val monitorResult: Symbol = if (hasResult) locals.makeLocal(tpeTK(args.head), "monitorResult", defn.ObjectType, tree.span) else null /* ------ (1) pushing and entering the monitor, also keeping a reference to it in a local var. ------ */ genLoadQualifier(fun) @@ -182,7 +183,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { pat match { case Typed(Ident(nme.WILDCARD), tpt) => NamelessEH(tpeTK(tpt).asClassBType, caseBody) case Ident(nme.WILDCARD) => NamelessEH(ThrowableReference, caseBody) - case Bind(_, _) => BoundEH (treeHelper(pat).symbol, caseBody) + case Bind(_, _) => BoundEH (pat.symbol, caseBody) } } @@ -210,7 +211,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { * please notice `tmp` has type tree.tpe, while `earlyReturnVar` has the method return type. * Because those two types can be different, dedicated vars are needed. */ - val tmp = if (guardResult) locals.makeLocal(tpeTK(tree), "tmp", treeHelper(tree).tpe, treeHelper(tree).pos) else null + val tmp = if (guardResult) locals.makeLocal(tpeTK(tree), "tmp", tree.tpe, tree.span) else null /* * upon early return from the try-body or one of its EHs (but not the EH-version of the finally-clause) @@ -320,7 +321,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { nopIfNeeded(startTryBody) val finalHandler = currProgramPoint() // version of the finally-clause reached via unhandled exception. protect(startTryBody, finalHandler, finalHandler, null) - val Local(eTK, _, eIdx, _) = locals(locals.makeLocal(ThrowableReference, "exc", defn.ThrowableType, treeHelper(finalizer).pos)) + val Local(eTK, _, eIdx, _) = locals(locals.makeLocal(ThrowableReference, "exc", defn.ThrowableType, finalizer.span)) bc.store(eIdx, eTK) emitFinalizer(finalizer, null, isDuplicate = true) bc.load(eIdx, eTK) @@ -407,11 +408,11 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { } /* Does this tree have a try-catch block? */ - def mayCleanStack(tree: Tree): Boolean = treeHelper(tree) exists { t => t match { + def mayCleanStack(tree: Tree): Boolean = tree.find { t => t match { case Try(_, _, _) => true case _ => false } - } + }.isDefined trait EHClause case class NamelessEH(typeToDrop: ClassBType, caseBody: Tree) extends EHClause diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 7614d70c98db..d557e39501c4 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -480,19 +480,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } - implicit def treeHelper(a: Tree): TreeHelper = new TreeHelper { - def symbol: Symbol = a.symbol - - def pos: Position = a.span - - def isEmpty: Boolean = a.isEmpty - - def tpe: Type = a.tpe - - def exists(pred: (Tree) => Boolean): Boolean = a.find(pred).isDefined - } - - implicit def annotHelper(a: Annotation): AnnotationHelper = new AnnotationHelper { def atp: Type = a.tree.tpe @@ -1161,13 +1148,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def symbolValue: Symbol } - abstract class TreeHelper{ - def symbol: Symbol - def tpe: Type - def isEmpty: Boolean - def pos: Position - def exists(pred: Tree => Boolean): Boolean - } abstract class SymbolHelper { def exists: Boolean @@ -1404,7 +1384,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma case Literal(_) => true case _ => false } - def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((treeHelper(t).symbol ne null) && symHelper(treeHelper(t).symbol).isModule) + def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((t.symbol ne null) && symHelper(t.symbol).isModule) def ifOneIsNull(l: Tree, r: Tree): Tree = if (isNull(l)) r else if (isNull(r)) l else null private val primitiveCompilationUnits = Set( From e8c06091bad380ee2f66c08b847aeb6c3e01a2a4 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 10:12:20 +0200 Subject: [PATCH 21/98] Remove extractor abstractions --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 4 +- .../backend/jvm/DottyBackendInterface.scala | 163 +----------------- 2 files changed, 9 insertions(+), 158 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 133a29d1dfe9..d46c198d423b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -329,7 +329,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case app @ Apply(_, _) => generatedType = genApply(app, expectedType) - case ThisBI(qual) => + case This(qual) => val symIsModuleClass = symHelper(tree.symbol).isModuleClass assert(tree.symbol == claszSymbol || symIsModuleClass, s"Trying to access the this of another class: tree.symbol = ${tree.symbol}, class symbol = $claszSymbol compilation unit: $cunit") @@ -396,7 +396,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(expr, expectedType) else genBlock(blck, expectedType) - case Typed(Super(_, _), _) => genLoad(ThisBI(claszSymbol), expectedType) + case Typed(Super(_, _), _) => genLoad(tpd.This(claszSymbol.asClass), expectedType) case Typed(expr, _) => genLoad(expr, expectedType) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index d557e39501c4..b6d484109ea5 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -868,7 +868,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def parents: List[Type] = tp.parents } - object SelectBI extends SelectDeconstructor { + object SelectBI extends DeconstructorCommon[Select] { var desugared: tpd.Select = null @@ -894,7 +894,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object ThrowBI extends ThrowDeconstructor { + object ThrowBI extends Deconstructor1Common[Throw, Tree] { def get: Tree = field.args.head override def unapply(s: Throw): ThrowBI.type = { @@ -907,21 +907,16 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object ThisBI extends ThisDeconstructor { - def get: Name = field.qual.name - def apply(s: Symbol): This = tpd.This(s.asClass) - } - - object ReturnBI extends ReturnDeconstructor { + object ReturnBI extends DeconstructorCommon[Return] { def _1: Tree = field.expr def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol } - object ThrownExceptionBI extends ThrownException { + object ThrownExceptionBI { def unapply(a: Annotation): Option[Symbol] = None // todo } - object ArrayValueBI extends ArrayValueDeconstructor { + object ArrayValueBI extends DeconstructorCommon[ArrayValue] { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => @@ -931,7 +926,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _2: List[Tree] = field.elems } - object TemplateBI extends TemplateDeconstructor { + object TemplateBI extends DeconstructorCommon[Template] { def _1: List[Tree] = field.parents def _2: ValDef = field.self def _3: List[Tree] = @@ -939,7 +934,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma else field.constr :: field.body } - object ClosureBI extends ClosureDeconstructor { + object ClosureBI extends DeconstructorCommon[Closure] { def _1: List[Tree] = field.env def _2: Tree = field.meth def _3: Symbol = { @@ -981,150 +976,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - abstract class ClassDefDeconstructor extends DeconstructorCommon[ClassDef] { - def _1: Null - def _2: Name - def _3: List[TypeDef] - def _4: Template - } - - abstract class BindDeconstructor extends DeconstructorCommon[Bind]{ - def _1: Name - def _2: Tree - } - - abstract class TemplateDeconstructor extends DeconstructorCommon[Template]{ - def _1: List[Tree] - def _2: ValDef - def _3: List[Tree] - } - - abstract class DefDefDeconstructor extends DeconstructorCommon[DefDef]{ - def _1: Null - def _2: Name - def _3: List[TypeDef] - def _4: List[List[ValDef]] - def _5: Tree - def _6: Tree - } - - abstract class ClosureDeconstructor extends DeconstructorCommon[Closure]{ - def _1: List[Tree] // environment - def _2: Tree // meth - def _3: Symbol // functionalInterface - } - - abstract class ThisDeconstructor extends Deconstructor1Common[This, Name]{ - def apply(s: Symbol): Tree - } - - abstract class IdentDeconstructor extends Deconstructor1Common[Ident, Name]{ - } - - abstract class LabeledDeconstructor extends DeconstructorCommon[Labeled]{ - def _1: Bind // bind - def _2: Tree // expr - } - - abstract class ReturnDeconstructor extends DeconstructorCommon[Return]{ - def _1: Tree // expr - def _2: Symbol // target label, NoSymbol if return to method - } - - abstract class WhileDoDeconstructor extends DeconstructorCommon[WhileDo]{ - def _1: Tree // cond - def _2: Tree // body - } - - abstract class ThrownException { - def unapply(a: Annotation): Option[Symbol] - } - - abstract class ThrowDeconstructor extends Deconstructor1Common[Throw, Tree]{ - } - - abstract class ConstantDeconstructor extends Deconstructor1Common[Constant, Any]{ - } - - abstract class NewDeconstructor extends Deconstructor1Common[New, Type]{ - } - - abstract class AlternativeDeconstructor extends Deconstructor1Common[Alternative, List[Tree]]{ - } - - abstract class BlockDeconstructor extends DeconstructorCommon[Block]{ - def _1: List[Tree] - def _2: Tree - } - - abstract class CaseDeconstructor extends DeconstructorCommon[CaseDef]{ - def _1: Tree - def _2: Tree - def _3: Tree - } - - abstract class MatchDeconstructor extends DeconstructorCommon[Match]{ - def _1: Tree - def _2: List[Tree] - } - - abstract class LiteralDeconstructor extends Deconstructor1Common[Literal, Constant]{ - } - - abstract class AssignDeconstructor extends DeconstructorCommon[Assign]{ - def _1: Tree - def _2: Tree - } - - abstract class SelectDeconstructor extends DeconstructorCommon[Select]{ - def _1: Tree - def _2: Name - } - - abstract class ApplyDeconstructor extends DeconstructorCommon[Apply] { - def _1: Tree - def _2: List[Tree] - } - - abstract class IfDeconstructor extends DeconstructorCommon[If]{ - def _1: Tree - def _2: Tree - def _3: Tree - } - - abstract class ValDefDeconstructor extends DeconstructorCommon[ValDef]{ - def _1: Null - def _2: Name - def _3: Tree - def _4: Tree - } - - - abstract class TryDeconstructor extends DeconstructorCommon[Try]{ - def _1: Tree - def _2: List[Tree] - def _3: Tree - } - - abstract class TypedDeconstrutor extends DeconstructorCommon[Typed]{ - def _1: Tree - def _2: Tree - } - - abstract class SuperDeconstructor extends DeconstructorCommon[Super]{ - def _1: Tree - def _2: Name - } - - abstract class ArrayValueDeconstructor extends DeconstructorCommon[ArrayValue]{ - def _1: Type - def _2: List[Tree] - } - - abstract class TypeApplyDeconstructor extends DeconstructorCommon[TypeApply]{ - def _1: Tree - def _2: List[Tree] - } abstract class PositionHelper { def isDefined: Boolean From d82ee3647c07626537e9a428f1c33c4790c166af Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 10:15:12 +0200 Subject: [PATCH 22/98] Remove nameHelper --- .../dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 6 +++--- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../tools/backend/jvm/DottyBackendInterface.scala | 14 -------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index d46c198d423b..6f6ea5da212b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1353,7 +1353,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genCZJUMP(success, failure, Primitives.NE, BOOL, targetIfNoJump) } else { // l == r -> if (l eq null) r eq null else l.equals(r) - val eqEqTempLocal = locals.makeLocal(ObjectReference, nameHelper(nme.EQEQ_LOCAL_VAR).mangledString, defn.ObjectType, r.span) + val eqEqTempLocal = locals.makeLocal(ObjectReference, nme.EQEQ_LOCAL_VAR.mangledString, defn.ObjectType, r.span) val lNull = new asm.Label val lNonNull = new asm.Label @@ -1398,7 +1398,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val targetHandle = new asm.Handle(invokeStyle, classBTypeFromSymbol(symHelper(lambdaTarget).owner).internalName, - nameHelper(lambdaTarget.name).mangledString, + lambdaTarget.name.mangledString, asmMethodType(lambdaTarget).descriptor, /* itf = */ isInterface) @@ -1414,7 +1414,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // TODO specialization val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(symHelper(lambdaTarget).tpe.resultType)).toASMType val abstractMethod = symHelper(functionalInterface).samMethod() - val methodName = nameHelper(abstractMethod.name).mangledString + val methodName = abstractMethod.name.mangledString val applyN = { val mt = asmMethodType(abstractMethod) mt.toASMType diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 98e9fa5476c7..2ca8489def12 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -376,7 +376,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val linkedClass = symHelper(moduleClass).companionClass lazy val conflictingNames: Set[Name] = { - (typeHelper(symHelper(linkedClass).info).members collect { case sym if nameHelper(sym.name).isTermName => sym.name }).toSet + (typeHelper(symHelper(linkedClass).info).members collect { case sym if sym.name.isTermName => sym.name }).toSet } debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index b6d484109ea5..d0f973a2f44f 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -504,13 +504,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - implicit def nameHelper(n: Name): NameHelper = new NameHelper { - def isTypeName: Boolean = n.isTypeName - def isTermName: Boolean = n.isTermName - def startsWith(s: String): Boolean = n.startsWith(s) - def mangledString: String = n.mangledString - } - implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper { def exists: Boolean = sym.exists @@ -1189,13 +1182,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def getPrimitive(sym: Symbol): Int } - abstract class NameHelper { - def isTypeName: Boolean - def isTermName: Boolean - def startsWith(s: String): Boolean - def mangledString: String - } - abstract class AnnotationHelper{ def atp: Type def symbol: Symbol From 2e8f5c5bd059a4cead02ac0b4d8d12df6c41e444 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 10:25:44 +0200 Subject: [PATCH 23/98] Remove positionHelper and annotHelper --- .../tools/backend/jvm/BCodeHelpers.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 6 +-- .../backend/jvm/DottyBackendInterface.scala | 54 ++++--------------- 3 files changed, 15 insertions(+), 47 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 2ca8489def12..6dcad1c96235 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -327,7 +327,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // TODO needed? for(ann <- m.annotations) { ann.symbol.initialize } val jgensig = getStaticForwarderGenericSignature(m, module) - val (throws, others) = symHelper(m).annotations partition (annotHelper(_).symbol == defn.ThrowsAnnot) + val (throws, others) = symHelper(m).annotations partition (_.tree.symbol == defn.ThrowsAnnot) val thrownExceptions: List[String] = getExceptions(throws) val jReturnType = toTypeKind(methodInfo.resultType) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index afb1956c1856..d868df636295 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -433,8 +433,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { case _ => false } ) } def lineNumber(tree: Tree): Unit = { - if (!emitLines || !positionHelper(tree.span).isDefined) return; - val nr = positionHelper(positionHelper(tree.span).finalPosition).line + if (!emitLines || !tree.span.exists) return; + val nr = sourcePos(tree.span).line + 1 if (nr != lastEmittedLineNr) { lastEmittedLineNr = nr lastInsn match { @@ -486,7 +486,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def initJMethod(flags: Int, paramAnnotations: List[List[Annotation]]): Unit = { val jgensig = getGenericSignature(methSymbol, claszSymbol) - val (excs, others) = symHelper(methSymbol).annotations partition (annotHelper(_).symbol == defn.ThrowsAnnot) + val (excs, others) = symHelper(methSymbol).annotations partition (_.tree.symbol == defn.ThrowsAnnot) val thrownExceptions: List[String] = getExceptions(excs) val bytecodeName = diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index d0f973a2f44f..0c706ae93475 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -130,7 +130,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } def isRuntimeVisible(annot: Annotation): Boolean = - if (toDenot(annotHelper(annot).atp.typeSymbol).hasAnnotation(AnnotationRetentionAttr)) + if (toDenot(annot.tree.tpe.typeSymbol).hasAnnotation(AnnotationRetentionAttr)) retentionPolicyOf(annot) == AnnotationRetentionRuntimeAttr else { // SI-8926: if the annotation class symbol doesn't have a @RetentionPolicy annotation, the @@ -141,12 +141,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def shouldEmitAnnotation(annot: Annotation): Boolean = { annot.symbol.isJavaDefined && - retentionPolicyOf(annot) != AnnotationRetentionSourceAttr && - annot.args.isEmpty + retentionPolicyOf(annot) != AnnotationRetentionSourceAttr } private def retentionPolicyOf(annot: Annotation): Symbol = - annot.atp.typeSymbol.getAnnotation(AnnotationRetentionAttr). + annot.tree.tpe.typeSymbol.getAnnotation(AnnotationRetentionAttr). flatMap(_.argumentConstant(0).map(_.symbolValue)).getOrElse(AnnotationRetentionClassAttr) private def normalizeArgument(arg: Tree): Tree = arg match { @@ -234,8 +233,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { for(annot <- annotations; if shouldEmitAnnotation(annot)) { - val typ = annot.atp - val assocs = annot.assocs + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) val av = cw.visitAnnotation(innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) emitAssocs(av, assocs, bcodeStore)(innerClasesStore) } @@ -251,8 +250,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def emitAnnotations(mw: asm.MethodVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { for(annot <- annotations; if shouldEmitAnnotation(annot)) { - val typ = annot.atp - val assocs = annot.assocs + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) val av = mw.visitAnnotation(innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) emitAssocs(av, assocs, bcodeStore)(innerClasesStore) } @@ -261,8 +260,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { for(annot <- annotations; if shouldEmitAnnotation(annot)) { - val typ = annot.atp - val assocs = annot.assocs + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) val av = fw.visitAnnotation(innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) emitAssocs(av, assocs, bcodeStore)(innerClasesStore) } @@ -274,8 +273,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma if (annotationss forall (_.isEmpty)) return for ((annots, idx) <- annotationss.zipWithIndex; annot <- annots) { - val typ = annot.atp - val assocs = annot.assocs + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) val pannVisitor: asm.AnnotationVisitor = jmethod.visitParameterAnnotation(idx, innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) emitAssocs(pannVisitor, assocs, bcodeStore)(innerClasesStore) } @@ -472,24 +471,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def sourceFileFor(cu: CompilationUnit): String = cu.source.file.name - - implicit def positionHelper(a: Position): PositionHelper = new PositionHelper { - def isDefined: Boolean = a.exists - def line: Int = sourcePos(a).line + 1 - def finalPosition: Position = a - } - - - implicit def annotHelper(a: Annotation): AnnotationHelper = new AnnotationHelper { - def atp: Type = a.tree.tpe - - def assocs: List[(Name, Tree)] = assocsFromApply(a.tree) - - def symbol: Symbol = a.tree.symbol - - def args: List[Tree] = List.empty // those arguments to scala-defined annotations. they are never emitted - } - def assocsFromApply(tree: Tree): List[(Name, Tree)] = { tree match { case Block(_, expr) => assocsFromApply(expr) @@ -970,12 +951,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } - abstract class PositionHelper { - def isDefined: Boolean - def finalPosition: Position - def line: Int - } - abstract class ConstantHelper { def tag: ConstantTag def longValue: Long @@ -1182,13 +1157,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def getPrimitive(sym: Symbol): Int } - abstract class AnnotationHelper{ - def atp: Type - def symbol: Symbol - def args: List[Tree] - def assocs: List[(Name, /* ClassfileAnnotArg*/ Object)] - } - abstract class Caches { def recordCache[T <: Clearable](cache: T): T def newWeakMap[K, V](): collection.mutable.WeakHashMap[K, V] From f8dbf7cccc0b7ce39550ed895f016b48932d6542 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 10:41:51 +0200 Subject: [PATCH 24/98] Remove aliases --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 10 +++---- .../backend/jvm/DottyBackendInterface.scala | 30 +------------------ 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 6f6ea5da212b..a50586f00122 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1061,7 +1061,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // Optimization for expressions of the form "" + x. We can avoid the StringBuilder. case List(Literal(Constant("")), arg) => genLoad(arg, ObjectReference) - genCallMethod(String_valueOf, InvokeStyle.Static) + genCallMethod(defn.String_valueOf_Object, InvokeStyle.Static) case concatenations => bc.genStartConcat @@ -1152,7 +1152,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* Generate the scala ## method. */ def genScalaHash(tree: Tree): BType = { genLoad(tree, ObjectReference) - genCallMethod(hashMethodSym, InvokeStyle.Static) + genCallMethod(NoSymbol, InvokeStyle.Static) // used to dispatch ## on primitives to ScalaRuntime.hash. Should be implemented by a miniphase } /* @@ -1325,9 +1325,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (mustUseAnyComparator) { val equalsMethod: Symbol = { if (l.tpe <:< symHelper(defn.BoxedNumberClass).tpe) { - if (r.tpe <:< symHelper(defn.BoxedNumberClass).tpe) externalEqualsNumNum - else if (r.tpe <:< symHelper(defn.BoxedCharClass).tpe) externalEqualsNumChar - else externalEqualsNumObject + if (r.tpe <:< symHelper(defn.BoxedNumberClass).tpe) defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumNum) + else if (r.tpe <:< symHelper(defn.BoxedCharClass).tpe) NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private + else defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject) } else externalEquals } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 0c706ae93475..6c2b4e360577 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -86,18 +86,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma case _ => false } - val hashMethodSym: Symbol = NoSymbol // used to dispatch ## on primitives to ScalaRuntime.hash. Should be implemented by a miniphase - 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.BoxesRunTimeModule.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol - val MaxFunctionArity: Int = Definitions.MaxImplementedFunctionArity - val FunctionClass: Array[Symbol] = defn.FunctionClassPerRun() - val AbstractFunctionClass: Array[Symbol] = defn.AbstractFunctionClassPerRun() - val PartialFunctionClass: Symbol = defn.PartialFunctionClass - val AbstractPartialFunctionClass: Symbol = defn.AbstractPartialFunctionClass - val String_valueOf: Symbol = defn.String_valueOf_Object - @threadUnsafe lazy val Predef_classOf: Symbol = defn.ScalaPredefModule.requiredMethod(nme.classOf) @threadUnsafe lazy val AnnotationRetentionAttr: ClassSymbol = ctx.requiredClass("java.lang.annotation.Retention") @threadUnsafe lazy val AnnotationRetentionSourceAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE") @@ -174,7 +163,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) } - case t: TypeApply if (t.fun.symbol == Predef_classOf) => + case t: TypeApply if (t.fun.symbol == defn.Predef_classOf) => av.visit(name, t.args.head.tpe.classSymbol.denot.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType) case Ident(nme.WILDCARD) => // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything @@ -951,23 +940,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } - abstract class ConstantHelper { - def tag: ConstantTag - def longValue: Long - def doubleValue: Double - def charValue: Char - def stringValue: String - def byteValue: Byte - def booleanValue: Boolean - def shortValue: Short - def intValue: Int - def value: Any - def floatValue: Float - def typeValue: Type - def symbolValue: Symbol - } - - abstract class SymbolHelper { def exists: Boolean From 62bb744c9741212d16ee13c7e63b26788a3a95f6 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 10:44:52 +0200 Subject: [PATCH 25/98] Remove custom ThrownException extractor --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 5 +++-- .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 6dcad1c96235..33e034c90482 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -408,8 +408,9 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def getExceptions(excs: List[Annotation]): List[String] = { - for (ThrownExceptionBI(exc) <- excs.distinct) - yield internalName(exc) + // for (ThrownException(exc) <- excs.distinct) + // yield internalName(exc) + Nil } } // end of trait BCForwardersGen diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 6c2b4e360577..1a216ab863fe 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -875,10 +875,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol } - object ThrownExceptionBI { - def unapply(a: Annotation): Option[Symbol] = None // todo - } - object ArrayValueBI extends DeconstructorCommon[ArrayValue] { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem From cebc10243f3a84e0ff3d240065cfa6664895c6a5 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 10:55:26 +0200 Subject: [PATCH 26/98] Remove some abstractions --- .../backend/jvm/DottyBackendInterface.scala | 28 ++++++------------- .../dotty/tools/backend/jvm/GenBCode.scala | 2 +- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 1a216ab863fe..1609127d0e47 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -806,7 +806,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma case tp => ctx.warning( - s"an unexpected type representation reached the compiler backend while compiling $currentUnit: $tp. " + + s"an unexpected type representation reached the compiler backend while compiling ${ctx.compilationUnit}: $tp. " + "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") tp match { @@ -857,10 +857,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - object ThrowBI extends Deconstructor1Common[Throw, Tree] { + object ThrowBI { + var field: Throw = _ + def isEmpty: Boolean = field eq null + def isDefined = !isEmpty def get: Tree = field.args.head - - override def unapply(s: Throw): ThrowBI.type = { + def unapply(s: Throw): ThrowBI.type = { if (s.fun.symbol eq defn.throwMethod) { field = s } else { @@ -909,7 +911,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - def currentUnit: CompilationUnit = ctx.compilationUnit + // def currentUnit: CompilationUnit = ctx.compilationUnit @@ -924,18 +926,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - abstract class Deconstructor1Common[T >: Null <: AnyRef, R]{ - var field: T = _ - def get: R - def isEmpty: Boolean = field eq null - def isDefined = !isEmpty - def unapply(s: T): this.type ={ - field = s - this - } - } - - abstract class SymbolHelper { def exists: Boolean @@ -1177,11 +1167,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma * Used only in assertions. */ def isCompilingPrimitive = { - primitiveCompilationUnits(sourceFileFor(currentUnit)) + primitiveCompilationUnits(sourceFileFor(ctx.compilationUnit)) } def isCompilingArray = { - sourceFileFor(currentUnit) == "Array.scala" + sourceFileFor(ctx.compilationUnit) == "Array.scala" } } diff --git a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala index e68c54d93e56..5e088891bcf1 100644 --- a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala @@ -530,7 +530,7 @@ class GenBCodePipeline(val int: DottyBackendInterface)(implicit ctx: Context) ex case PackageDef(_, stats) => stats foreach gen case ValDef(name, tpt, rhs) => () // module val not emitted case cd: TypeDef => - q1 add Item1(arrivalPos, cd, int.currentUnit) + q1 add Item1(arrivalPos, cd, int.ctx.compilationUnit) arrivalPos += 1 } } From 967cdea3fb5ff2df13fa0796aa2f4dc247d2c700 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 11:05:34 +0200 Subject: [PATCH 27/98] Remove some abstractions --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 7 ++++--- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 4 ++-- .../src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 8 +------- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index a50586f00122..b70d2f379e45 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -9,6 +9,7 @@ import scala.tools.asm.{Handle, Label, Opcodes} import BCodeHelpers.InvokeStyle import dotty.tools.dotc.core.Constants._ +import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames.nme import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.util.Spans.NoSpan @@ -323,7 +324,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(prefix) } - genLoadArguments(env, typeHelper(symHelper(fun.symbol).info).paramTypes map toTypeKind) + genLoadArguments(env, symHelper(fun.symbol).info.firstParamTypes map toTypeKind) generatedType = genInvokeDynamicLambda(NoSymbol, fun.symbol, env.size, functionalInterface) case app @ Apply(_, _) => @@ -1317,7 +1318,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * not using the rich equality is possible (their own equals method will do ok.) */ val mustUseAnyComparator: Boolean = { - val areSameFinals = typeHelper(l.tpe).isFinalType && typeHelper(r.tpe).isFinalType && (l.tpe =:= r.tpe) + val areSameFinals = l.tpe.typeSymbol.is(Flags.Final) && r.tpe.typeSymbol.is(Flags.Final) && (l.tpe =:= r.tpe) !areSameFinals && isMaybeBoxed(typeHelper(l.tpe).typeSymbol) && isMaybeBoxed(typeHelper(r.tpe).typeSymbol) } @@ -1402,7 +1403,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { asmMethodType(lambdaTarget).descriptor, /* itf = */ isInterface) - val (a,b) = typeHelper(symHelper(lambdaTarget).info).paramTypes.splitAt(environmentSize) + val (a,b) = symHelper(lambdaTarget).info.firstParamTypes.splitAt(environmentSize) var (capturedParamsTypes, lambdaParamTypes) = (a,b) if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = symHelper(symHelper(lambdaTarget).owner).info :: capturedParamsTypes diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 33e034c90482..ae51e9fa17d8 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -242,7 +242,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val resT: BType = if (symHelper(msym).isClassConstructor || symHelper(msym).isConstructor) UNIT else toTypeKind(symHelper(msym).tpe.resultType) - MethodBType(typeHelper(symHelper(msym).tpe).paramTypes map toTypeKind, resT) + MethodBType(symHelper(msym).tpe.firstParamTypes map toTypeKind, resT) } /** @@ -312,7 +312,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { private def addForwarder(jclass: asm.ClassVisitor, module: Symbol, m: Symbol): Unit = { val moduleName = internalName(module) val methodInfo = symHelper(module).thisType.memberInfo(m) - val paramJavaTypes: List[BType] = typeHelper(methodInfo).paramTypes map toTypeKind + val paramJavaTypes: List[BType] = methodInfo.firstParamTypes map toTypeKind // val paramNames = 0 until paramJavaTypes.length map ("x_" + _) /* Forwarders must not be marked final, diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index d868df636295..46f9aa0da9d4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -69,7 +69,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def paramTKs(app: Apply, take: Int = -1): List[BType] = app match { case Apply(fun, _) => val funSym = fun.symbol - (typeHelper(symHelper(funSym).info).paramTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) + (symHelper(funSym).info.firstParamTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) } def symInfoTK(sym: Symbol): BType = { diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 1609127d0e47..756315015b14 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -716,15 +716,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma implicit def typeHelper(tp: Type): TypeHelper = new TypeHelper { def member(string: Name): Symbol = tp.member(string.toTermName).symbol - def isFinalType: Boolean = tp.typeSymbol.is(Flags.Final) //in scalac checks for type parameters. Why? Aren't they gone by backend? - def underlying: Type = tp match { case t: TypeProxy => t.underlying case _ => tp } - def paramTypes: List[Type] = tp.firstParamTypes - def decl(name: Name): Symbol = tp.decl(name).symbol def decls: List[Symbol] = tp.decls.toList @@ -902,7 +898,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val t = field.tpt.tpe.typeSymbol if (t.exists) t else { - val arity = field.meth.tpe.widenDealias.paramTypes.size - _1.size + val arity = field.meth.tpe.widenDealias.firstParamTypes.size - _1.size val returnsUnit = field.meth.tpe.widenDealias.resultType.classSymbol == defn.UnitClass if (returnsUnit) ctx.requiredClass(("dotty.runtime.function.JProcedure" + arity)) else if (arity <= 2) ctx.requiredClass(("dotty.runtime.function.JFunction" + arity)) @@ -1080,7 +1076,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } abstract class TypeHelper { - def paramTypes: List[Type] def params: List[Symbol] /** The members of this type that have all of `required` flags but none of `excluded` flags set. @@ -1106,7 +1101,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma */ def toTypeKind(ctx: BCodeHelpers)(storage: ctx.BCInnerClassGen): ctx.bTypes.BType - def isFinalType: Boolean } abstract class Primitives { From 5298923ebfaa3c2e9f69765044e50b25de0e1b92 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 11:24:39 +0200 Subject: [PATCH 28/98] Remove helper methods --- .../tools/backend/jvm/BCodeAsmCommon.scala | 2 +- .../tools/backend/jvm/BCodeBodyBuilder.scala | 54 ++++++------- .../tools/backend/jvm/BCodeHelpers.scala | 20 ++--- .../tools/backend/jvm/BCodeSkelBuilder.scala | 20 ++--- .../tools/backend/jvm/BTypesFromSymbols.scala | 6 +- .../backend/jvm/DottyBackendInterface.scala | 77 +++++++++---------- 6 files changed, 86 insertions(+), 93 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index efed1c950876..9c36fdf841e1 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -22,7 +22,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { // Here used to be an `assert(!classSym.isDelambdafyFunction)`: delambdafy lambda classes are // always top-level. However, SI-8900 shows an example where the weak name-based implementation // of isDelambdafyFunction failed (for a function declared in a package named "lambda"). - symHelper(classSym).isAnonymousClass || { + classSym.isAnonymousClass || { val originalOwnerLexicallyEnclosingClass = symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass originalOwnerLexicallyEnclosingClass != NoSymbol && !symHelper(originalOwnerLexicallyEnclosingClass).isClass } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index b70d2f379e45..3cabcbe5f6f0 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -324,7 +324,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(prefix) } - genLoadArguments(env, symHelper(fun.symbol).info.firstParamTypes map toTypeKind) + genLoadArguments(env, fun.symbol.info.firstParamTypes map toTypeKind) generatedType = genInvokeDynamicLambda(NoSymbol, fun.symbol, env.size, functionalInterface) case app @ Apply(_, _) => @@ -445,7 +445,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { private def fieldOp(field: Symbol, isLoad: Boolean, specificReceiver: Symbol): Unit = { val useSpecificReceiver = specificReceiver != null && !symHelper(field).isScalaStatic - val owner = internalName(if (useSpecificReceiver) specificReceiver else symHelper(field).owner) + val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner) val fieldJName = symHelper(field).javaSimpleName.toString val fieldDescr = symInfoTK(field).descriptor val isStatic = symHelper(field).isStaticMember @@ -493,9 +493,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case EnumTag => val sym = const.symbolValue - val ownerName = internalName(symHelper(sym).owner) + val ownerName = internalName(sym.owner) val fieldName = symHelper(sym).javaSimpleName.toString - val fieldDesc = toTypeKind(typeHelper(symHelper(sym).tpe).underlying).descriptor + val fieldDesc = toTypeKind(typeHelper(sym.info).underlying).descriptor mnode.visitFieldInsn( asm.Opcodes.GETSTATIC, ownerName, @@ -551,7 +551,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * that cross cleanup boundaries. However, in theory such crossings are valid, so we should take care * of them. */ - val resultKind = toTypeKind(symHelper(fromSym).info) + val resultKind = toTypeKind(fromSym.info) genLoad(expr, resultKind) lineNumber(r) bc goTo programPoint(fromSym) @@ -707,7 +707,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // instance (on JVM, methods return VOID). case Apply(fun @ SelectBI(New(tpt), nme.CONSTRUCTOR), args) => val ctor = fun.symbol - assert(symHelper(ctor).isClassConstructor, s"'new' call to non-constructor: ${ctor.name}") + assert(ctor.isClassConstructor, s"'new' call to non-constructor: ${ctor.name}") generatedType = toTypeKind(tpt.tpe) assert(generatedType.isRef, s"Non reference type cannot be instantiated: $generatedType") @@ -717,7 +717,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { mkArrayConstructorCall(arr, app, args) case rt: ClassBType => - assert(classBTypeFromSymbol(symHelper(ctor).owner) == rt, s"Symbol ${symHelper(ctor).owner.showFullName} is different from $rt") + assert(classBTypeFromSymbol(ctor.owner) == rt, s"Symbol ${ctor.owner.showFullName} is different from $rt") mnode.visitTypeInsn(asm.Opcodes.NEW, rt.internalName) bc dup generatedType genLoadArguments(args, paramTKs(app)) @@ -749,7 +749,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } else { // normal method call val invokeStyle = if (symHelper(sym).isStaticMember) InvokeStyle.Static - else if (symHelper(sym).isPrivate || symHelper(sym).isClassConstructor) InvokeStyle.Special + else if (symHelper(sym).isPrivate || sym.isClassConstructor) InvokeStyle.Special else InvokeStyle.Virtual if (invokeStyle.hasInstance) genLoadQualifier(fun) @@ -784,7 +784,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // in the bytecode. Using the array descriptor (like we do for clone above) seems // to work as well, but it seems safer not to change this. Javac also uses Object. // Note that array apply/update/length are handled by isPrimitive (above). - assert(symHelper(sym).owner == defn.ObjectClass, s"unexpected array call: $app") + assert(sym.owner == defn.ObjectClass, s"unexpected array call: $app") defn.ObjectClass } else qualSym } @@ -988,7 +988,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { desugarIdent(t) match { case Some(sel) => genLoadQualifier(sel) case None => - assert(symHelper(t.symbol).owner == this.claszSymbol) + assert(t.symbol.owner == this.claszSymbol) } case _ => abort(s"Unknown qualifier $tree") } @@ -1001,7 +1001,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(tree: Tree): BType = { val module = ( if (!symHelper(tree.symbol).isPackageClass) tree.symbol - else typeHelper(symHelper(tree.symbol).info).member(nme.PACKAGE) match { + else typeHelper(tree.symbol.info).member(nme.PACKAGE) match { case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree") case s => abort(s"SI-5604: found package class where package object expected: $tree") } @@ -1090,7 +1090,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * prevent an IllegalAccessError, (aladdin bug 455). */ def genCallMethod(method: Symbol, style: InvokeStyle, pos: Position = NoSpan, specificReceiver: Symbol = null): BType = { - val methodOwner = symHelper(method).owner + val methodOwner = method.owner // the class used in the invocation's method descriptor in the classfile val receiverClass = { @@ -1117,15 +1117,15 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { receiver != methodOwner && // fast path - the boolean is used to pick either of these two, if they are the same it does not matter style.isVirtual && symHelper(receiver).isEmittedInterface && - symHelper(typeHelper(defn.ObjectType).decl(method.name)).exists && { // fast path - compute overrideChain on the next line only if necessary + typeHelper(defn.ObjectType).decl(method.name).exists && { // fast path - compute overrideChain on the next line only if necessary val syms = symHelper(method).allOverriddenSymbols - !syms.isEmpty && symHelper(syms.last).owner == defn.ObjectClass + !syms.isEmpty && syms.last.owner == defn.ObjectClass } } if (isTraitMethodOverridingObjectMember) methodOwner else receiver } - symHelper(receiverClass).info // ensure types the type is up to date; erasure may add lateINTERFACE to traits + receiverClass.info // ensure types the type is up to date; erasure may add lateINTERFACE to traits val receiverName = internalName(receiverClass) val jname = symHelper(method).javaSimpleName.toString @@ -1325,9 +1325,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (mustUseAnyComparator) { val equalsMethod: Symbol = { - if (l.tpe <:< symHelper(defn.BoxedNumberClass).tpe) { - if (r.tpe <:< symHelper(defn.BoxedNumberClass).tpe) defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumNum) - else if (r.tpe <:< symHelper(defn.BoxedCharClass).tpe) NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private + if (l.tpe <:< defn.BoxedNumberClass.info) { + if (r.tpe <:< defn.BoxedNumberClass.info) defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumNum) + else if (r.tpe <:< defn.BoxedCharClass.info) NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private else defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject) } else externalEquals } @@ -1384,36 +1384,36 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genInvokeDynamicLambda(ctor: Symbol, lambdaTarget: Symbol, environmentSize: Int, functionalInterface: Symbol): BType = { import java.lang.invoke.LambdaMetafactory.FLAG_SERIALIZABLE - debuglog(s"Using invokedynamic rather than `new ${symHelper(ctor).owner}`") + debuglog(s"Using invokedynamic rather than `new ${ctor.owner}`") val generatedType = classBTypeFromSymbol(functionalInterface) // Lambdas should be serializable if they implement a SAM that extends Serializable or if they // implement a scala.Function* class. - val isSerializable = symHelper(functionalInterface).isSerializable || symHelper(functionalInterface).isFunctionClass - val isInterface = symHelper(symHelper(lambdaTarget).owner).isEmittedInterface + val isSerializable = functionalInterface.isSerializable || symHelper(functionalInterface).isFunctionClass + val isInterface = symHelper(lambdaTarget.owner).isEmittedInterface val invokeStyle = if (symHelper(lambdaTarget).isStaticMember) asm.Opcodes.H_INVOKESTATIC - else if (symHelper(lambdaTarget).isPrivate || symHelper(lambdaTarget).isClassConstructor) asm.Opcodes.H_INVOKESPECIAL + else if (symHelper(lambdaTarget).isPrivate || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL else if (isInterface) asm.Opcodes.H_INVOKEINTERFACE else asm.Opcodes.H_INVOKEVIRTUAL val targetHandle = new asm.Handle(invokeStyle, - classBTypeFromSymbol(symHelper(lambdaTarget).owner).internalName, + classBTypeFromSymbol(lambdaTarget.owner).internalName, lambdaTarget.name.mangledString, asmMethodType(lambdaTarget).descriptor, /* itf = */ isInterface) - val (a,b) = symHelper(lambdaTarget).info.firstParamTypes.splitAt(environmentSize) + val (a,b) = lambdaTarget.info.firstParamTypes.splitAt(environmentSize) var (capturedParamsTypes, lambdaParamTypes) = (a,b) - if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = symHelper(symHelper(lambdaTarget).owner).info :: capturedParamsTypes + if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = lambdaTarget.owner.info :: capturedParamsTypes // Requires https://github.com/scala/scala-java8-compat on the runtime classpath - val returnUnit = typeHelper(symHelper(lambdaTarget).info.resultType).typeSymbol == defn.UnitClass + val returnUnit = typeHelper(lambdaTarget.info.resultType).typeSymbol == defn.UnitClass val functionalInterfaceDesc: String = generatedType.descriptor val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc // TODO specialization - val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(symHelper(lambdaTarget).tpe.resultType)).toASMType + val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(lambdaTarget.info.resultType)).toASMType val abstractMethod = symHelper(functionalInterface).samMethod() val methodName = abstractMethod.name.mangledString val applyN = { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index ae51e9fa17d8..f65f0a0bf862 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -240,9 +240,9 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { final def asmMethodType(msym: Symbol): MethodBType = { assert(symHelper(msym).isMethod, s"not a method-symbol: $msym") val resT: BType = - if (symHelper(msym).isClassConstructor || symHelper(msym).isConstructor) UNIT - else toTypeKind(symHelper(msym).tpe.resultType) - MethodBType(symHelper(msym).tpe.firstParamTypes map toTypeKind, resT) + if (msym.isClassConstructor || msym.isConstructor) UNIT + else toTypeKind(msym.info.resultType) + MethodBType(msym.info.firstParamTypes map toTypeKind, resT) } /** @@ -311,7 +311,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ private def addForwarder(jclass: asm.ClassVisitor, module: Symbol, m: Symbol): Unit = { val moduleName = internalName(module) - val methodInfo = symHelper(module).thisType.memberInfo(m) + val methodInfo = module.thisType.memberInfo(m) val paramJavaTypes: List[BType] = methodInfo.firstParamTypes map toTypeKind // val paramNames = 0 until paramJavaTypes.length map ("x_" + _) @@ -342,7 +342,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ) emitAnnotations(mirrorMethod, others) - emitParamAnnotations(mirrorMethod, typeHelper(symHelper(m).info).params.map(symHelper(_).annotations)) + emitParamAnnotations(mirrorMethod, typeHelper(m.info).params.map(symHelper(_).annotations)) mirrorMethod.visitCode() @@ -376,18 +376,18 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val linkedClass = symHelper(moduleClass).companionClass lazy val conflictingNames: Set[Name] = { - (typeHelper(symHelper(linkedClass).info).members collect { case sym if sym.name.isTermName => sym.name }).toSet + (typeHelper(linkedClass.info).members collect { case sym if sym.name.isTermName => sym.name }).toSet } debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") - for (m0 <- typeHelper(symHelper(moduleClass).info).sortedMembersBasedOnFlags(required = Flag_METHOD, excluded = ExcludedForwarderFlags)) { - val m = if (symHelper(m0).isBridge) symHelper(m0).nextOverriddenSymbol else m0 + for (m0 <- typeHelper(moduleClass.info).sortedMembersBasedOnFlags(required = Flag_METHOD, excluded = ExcludedForwarderFlags)) { + val m = if (symHelper(m0).isBridge) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") - else if (symHelper(m).isType || symHelper(m).isDeferred || (symHelper(m).owner eq defn.ObjectClass) || symHelper(m).isConstructor || symHelper(m).isExpanded) + else if (m.isType || symHelper(m).isDeferred || (m.owner eq defn.ObjectClass) || m.isConstructor || symHelper(m).isExpanded) debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(m.name)) - log(s"No forwarder for $m due to conflict with ${typeHelper(symHelper(linkedClass).info).member(m.name)}") + log(s"No forwarder for $m due to conflict with ${typeHelper(linkedClass.info).member(m.name)}") else if (symHelper(m).hasAccessBoundary) log(s"No forwarder for non-public member $m") else { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 46f9aa0da9d4..593c14af9a5b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -69,11 +69,11 @@ trait BCodeSkelBuilder extends BCodeHelpers { def paramTKs(app: Apply, take: Int = -1): List[BType] = app match { case Apply(fun, _) => val funSym = fun.symbol - (symHelper(funSym).info.firstParamTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) + (funSym.info.firstParamTypes map toTypeKind) // this tracks mentioned inner classes (in innerClassBufferASM) } def symInfoTK(sym: Symbol): BType = { - toTypeKind(symHelper(sym).info) // this tracks mentioned inner classes (in innerClassBufferASM) + toTypeKind(sym.info) // this tracks mentioned inner classes (in innerClassBufferASM) } def tpeTK(tree: Tree): BType = { toTypeKind(tree.tpe) } @@ -126,7 +126,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ private def initJClass(jclass: asm.ClassVisitor): Unit = { - val ps = typeHelper(symHelper(claszSymbol).info).parents + val ps = typeHelper(claszSymbol.info).parents val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(typeHelper(ps.head).typeSymbol) val interfaceNames = classBTypeFromSymbol(claszSymbol).info.interfaces map { case classBType => @@ -136,7 +136,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val flags = javaFlags(claszSymbol) - val thisSignature = getGenericSignature(claszSymbol, symHelper(claszSymbol).owner) + val thisSignature = getGenericSignature(claszSymbol, claszSymbol.owner) cnode.visit(classfileVersion, flags, thisName, thisSignature, superClass, interfaceNames.toArray) @@ -538,7 +538,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } val isNative = symHelper(methSymbol).hasAnnotation(NativeAttr) - val isAbstractMethod = (symHelper(methSymbol).isDeferred || (symHelper(symHelper(methSymbol).owner).isInterface && !symHelper(methSymbol).isJavaDefaultMethod)) + val isAbstractMethod = (symHelper(methSymbol).isDeferred || (symHelper(methSymbol.owner).isInterface && !symHelper(methSymbol).isJavaDefaultMethod)) val flags = GenBCodeOps.mkFlags( javaFlags(methSymbol), if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0, @@ -560,7 +560,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { case ReturnBI(_) | Block(_, ReturnBI(_)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () case tpd.EmptyTree => error(NoSpan, "Concrete method has no definition: " + dd + ( - if (settings_debug) "(found: " + typeHelper(symHelper(symHelper(methSymbol).owner).info).decls.toList.mkString(", ") + ")" + if (settings_debug) "(found: " + typeHelper(methSymbol.owner.info).decls.toList.mkString(", ") + ")" else "") ) case _ => @@ -629,9 +629,9 @@ trait BCodeSkelBuilder extends BCodeHelpers { val className = internalName(symHelper(methSymbol).enclClass) insnModA = new asm.tree.TypeInsnNode(asm.Opcodes.NEW, className) // INVOKESPECIAL - val callee = symHelper(symHelper(methSymbol).enclClass).primaryConstructor + val callee = symHelper(methSymbol).enclClass.primaryConstructor val jname = symHelper(callee).javaSimpleName.toString - val jowner = internalName(symHelper(callee).owner) + val jowner = internalName(callee.owner) val jtype = asmMethodType(callee).descriptor insnModB = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESPECIAL, jowner, jname, jtype, false) } @@ -650,8 +650,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { null ) // INVOKESTATIC CREATOR(): android.os.Parcelable$Creator; -- TODO where does this Android method come from? - val callee = typeHelper(symHelper(symHelper(claszSymbol).companionModule).info).member(androidFieldName) - val jowner = internalName(symHelper(callee).owner) + val callee = typeHelper(symHelper(claszSymbol).companionModule.info).member(androidFieldName) + val jowner = internalName(callee.owner) val jname = symHelper(callee).javaSimpleName.toString val jtype = asmMethodType(callee).descriptor insnParcA = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESTATIC, jowner, jname, jtype, false) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 30abcf4ee59d..c92267e03c06 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -127,7 +127,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (symHelper(s).isJavaDefined && symHelper(s).isModuleClass) { // We could also search in nestedClassSymbols for s.linkedClassOfClass, but sometimes that // returns NoSymbol, so it doesn't work. - val nb = nestedClassSymbols.count(mc => mc.name == s.name && symHelper(mc).owner == symHelper(s).owner) + val nb = nestedClassSymbols.count(mc => mc.name == s.name && mc.owner == s.owner) // this assertion is specific to how ScalaC works. It doesn't apply to dotty, as n dotty there will be B & B$ // assert(nb == 2, s"Java member module without member class: $s - $nestedClassSymbols") false @@ -170,7 +170,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { } val innerName: Option[String] = { - if (symHelper(innerClassSym).isAnonymousClass || symHelper(innerClassSym).isAnonymousFunction) None + if (innerClassSym.isAnonymousClass || innerClassSym.isAnonymousFunction) None else Some(symHelper(innerClassSym).rawname + symHelper(innerClassSym).moduleSuffix) // moduleSuffix for module classes } @@ -225,7 +225,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (symHelper(sym).hasEnumFlag) ACC_ENUM else 0, if (symHelper(sym).isVarargsMethod) ACC_VARARGS else 0, if (symHelper(sym).isSynchronized) ACC_SYNCHRONIZED else 0, - if (symHelper(sym).isDeprecated) asm.Opcodes.ACC_DEPRECATED else 0, + if (false /*sym.isDeprecated*/) asm.Opcodes.ACC_DEPRECATED else 0, if (symHelper(sym).isEnum) asm.Opcodes.ACC_ENUM else 0 ) } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 756315015b14..04b2f451c3bf 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -475,8 +475,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper { - def exists: Boolean = sym.exists - // names def javaSimpleName: String = toDenot(sym).name.mangledString // addModuleSuffix(simpleName.dropLocal) def javaBinaryName: String = javaClassName.replace('.', '/') // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/')) @@ -486,20 +484,15 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma 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 - // 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 isType: Boolean = sym.isType + // def isAnonymousClass: Boolean = toDenot(sym).isAnonymousClass + // def isConstructor: Boolean = toDenot(sym).isConstructor def isExpanded: Boolean = sym.name.is(ExpandedName) - def isAnonymousFunction: Boolean = toDenot(sym).isAnonymousFunction + // def isAnonymousFunction: Boolean = toDenot(sym).isAnonymousFunction def isMethod: Boolean = sym.is(Flags.Method) def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) def isSynthetic: Boolean = sym.is(Flags.Synthetic) @@ -510,8 +503,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isLabel: Boolean = sym.is(Flags.Label) def hasPackageFlag: Boolean = sym.is(Flags.Package) 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 = toDenot(sym).isGetter + // def isSetter: Boolean = toDenot(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) @@ -520,6 +513,15 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def getsJavaFinalFlag: Boolean = isFinal && !toDenot(sym).isClassConstructor && !(sym.is(Flags.Mutable)) && !(sym.enclosingClass.is(Flags.Trait)) + /** Does this symbol actually correspond to an interface that will be emitted? + * In the backend, this should be preferred over `isInterface` because it + * also returns true for the symbols of the fake companion objects we + * create for Java-defined classes as well as for Java annotations + * which we represent as classes. + */ + def isEmittedInterface: Boolean = isInterface || + isJavaDefined && (toDenot(sym).isAnnotation || isModuleClass && symHelper(companionClass).isInterface) + def getsJavaPrivateFlag: Boolean = isPrivate || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) @@ -536,7 +538,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def hasEnumFlag: Boolean = sym.isAllOf(Flags.JavaEnumTrait) def hasAccessBoundary: Boolean = sym.accessBoundary(defn.RootClass) ne defn.RootClass def isVarargsMethod: Boolean = sym.is(Flags.JavaVarargs) - def isDeprecated: Boolean = false + // def isDeprecated: Boolean = false def isMutable: Boolean = sym.is(Flags.Mutable) def hasAbstractFlag: Boolean = sym.isOneOf(Flags.AbstractOrTrait) def hasModuleFlag: Boolean = sym.is(Flags.Module) @@ -547,9 +549,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma (sym.is(Flags.Module)) && sym.isStatic def isEnum = sym.is(Flags.Enum) - def isClassConstructor: Boolean = toDenot(sym).isClassConstructor - def isAnnotation: Boolean = toDenot(sym).isAnnotation - def isSerializable: Boolean = toDenot(sym).isSerializable + // def isClassConstructor: Boolean = toDenot(sym).isClassConstructor + // def isAnnotation: Boolean = toDenot(sym).isAnnotation + // def isSerializable: Boolean = toDenot(sym).isSerializable /** * True for module classes of modules that are top-level or owned only by objects. Module classes @@ -566,11 +568,10 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma toDenot(sym)(shiftedContext).isStatic(shiftedContext) } - def isStaticConstructor: Boolean = (isStaticMember && isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) + def isStaticConstructor: Boolean = (isStaticMember && sym.isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) // navigation - def owner: Symbol = toDenot(sym).owner def rawowner: Symbol = { originalOwner.originalLexicallyEnclosingClass } @@ -609,11 +610,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val shiftedContext = ctx.withPhase(validity.phaseId) toDenot(sym)(shiftedContext).lexicallyEnclosingClass(shiftedContext) } else NoSymbol - def nextOverriddenSymbol: Symbol = toDenot(sym).nextOverriddenSymbol + // def nextOverriddenSymbol: Symbol = toDenot(sym).nextOverriddenSymbol def allOverriddenSymbols: List[Symbol] = toDenot(sym).allOverriddenSymbols.toList // members - def primaryConstructor: Symbol = toDenot(sym).primaryConstructor + // def primaryConstructor: Symbol = toDenot(sym).primaryConstructor /** For currently compiled classes: All locally defined classes including local classes. * The empty list for classes that are not currently compiled. @@ -923,7 +924,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } abstract class SymbolHelper { - def exists: Boolean // names def javaSimpleName: String @@ -931,27 +931,21 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def javaClassName: String def rawname: String - // types - def info: Type - def tpe: Type // todo whats the differentce between tpe and info? - def thisType: Type - /** Does this symbol actually correspond to an interface that will be emitted? * In the backend, this should be preferred over `isInterface` because it * also returns true for the symbols of the fake companion objects we * create for Java-defined classes as well as for Java annotations * which we represent as classes. */ - final def isEmittedInterface: Boolean = isInterface || - isJavaDefined && (isAnnotation || isModuleClass && symHelper(companionClass).isInterface) + def isEmittedInterface: Boolean // tests def isClass: Boolean - def isType: Boolean - def isAnonymousClass: Boolean - def isConstructor: Boolean + // def isType: Boolean + // def isAnonymousClass: Boolean + // def isConstructor: Boolean def isExpanded: Boolean - def isAnonymousFunction: Boolean + // def isAnonymousFunction: Boolean def isMethod: Boolean def isPublic: Boolean def isSynthetic: Boolean @@ -962,8 +956,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isLabel: Boolean def hasPackageFlag: Boolean def isInterface: Boolean - def isGetter: Boolean - def isSetter: Boolean + // def isGetter: Boolean + // def isSetter: Boolean def isGetClass: Boolean def isJavaDefined: Boolean def isDeferred: Boolean @@ -979,7 +973,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def hasEnumFlag: Boolean def hasAccessBoundary: Boolean def isVarargsMethod: Boolean - def isDeprecated: Boolean + // def isDeprecated: Boolean def isMutable: Boolean def hasAbstractFlag: Boolean def hasModuleFlag: Boolean @@ -988,9 +982,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def hasAnnotation(sym: Symbol): Boolean def shouldEmitForwarders: Boolean def isJavaDefaultMethod: Boolean - def isClassConstructor: Boolean - def isAnnotation: Boolean - def isSerializable: Boolean + // def isClassConstructor: Boolean + // def isAnnotation: Boolean + // def isSerializable: Boolean def isEnum: Boolean /** @@ -1003,7 +997,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma // navigation - def owner: Symbol def rawowner: Symbol // todo ??? def originalOwner: Symbol def parentSymbols: List[Symbol] @@ -1017,12 +1010,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def moduleClass: Symbol def enclosingClassSym: Symbol def originalLexicallyEnclosingClass: Symbol - def nextOverriddenSymbol: Symbol + // def nextOverriddenSymbol: Symbol def allOverriddenSymbols: List[Symbol] // members - def primaryConstructor: Symbol + // def primaryConstructor: Symbol def nestedClasses: List[Symbol] def memberClasses: List[Symbol] def annotations: List[Annotation] From 92918543ef8ddc70a1739b633554165ee8f82b04 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 11:42:09 +0200 Subject: [PATCH 29/98] Remove methods form typeHelper --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 23 +++++++----- .../tools/backend/jvm/BCodeHelpers.scala | 11 ++++-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 8 ++--- .../backend/jvm/DottyBackendInterface.scala | 35 ++----------------- 4 files changed, 29 insertions(+), 48 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 3cabcbe5f6f0..54d08996ba70 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -10,6 +10,7 @@ import BCodeHelpers.InvokeStyle import dotty.tools.dotc.core.Constants._ import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.StdNames.nme import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.util.Spans.NoSpan @@ -70,7 +71,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoad(rhs, symInfoTK(lhs.symbol)) lineNumber(tree) // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError - val receiverClass = typeHelper(qual.tpe).typeSymbol + val receiverClass = qual.tpe.widenDealias.typeSymbol fieldStore(lhs.symbol, receiverClass) case Assign(lhs, rhs) => @@ -303,7 +304,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType = genThrow(expr) case New(tpt) => - abort(s"Unexpected New(${typeHelper(tpt.tpe).summaryString}/$tpt) reached GenBCode.\n" + + abort(s"Unexpected New(${tpt.tpe.showSummary()}/$tpt) reached GenBCode.\n" + " Call was genLoad" + ((tree, expectedType))) case app @ ClosureBI(env, call, functionalInterface) => @@ -356,7 +357,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } } // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError - def receiverClass = typeHelper(qualifier.tpe).typeSymbol + def receiverClass = qualifier.tpe.widenDealias.typeSymbol if (symHelper(sym).isModule) { genLoadQualUnlessElidable() genLoadModule(tree) @@ -495,7 +496,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val sym = const.symbolValue val ownerName = internalName(sym.owner) val fieldName = symHelper(sym).javaSimpleName.toString - val fieldDesc = toTypeKind(typeHelper(sym.info).underlying).descriptor + val underlying = sym.info match { + case t: TypeProxy => t.underlying + case t => t + } + val fieldDesc = toTypeKind(underlying).descriptor mnode.visitFieldInsn( asm.Opcodes.GETSTATIC, ownerName, @@ -778,7 +783,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val receiverClass = if (!invokeStyle.isVirtual) null else { // receiverClass is used in the bytecode to as the method receiver. using sym.owner // may lead to IllegalAccessErrors, see 9954eaf / aladdin bug 455. - val qualSym = typeHelper(qual.tpe).typeSymbol + val qualSym = qual.tpe.widenDealias.typeSymbol if (qualSym == defn.ArrayClass) { // For invocations like `Array(1).hashCode` or `.wait()`, use Object as receiver // in the bytecode. Using the array descriptor (like we do for clone above) seems @@ -1001,7 +1006,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(tree: Tree): BType = { val module = ( if (!symHelper(tree.symbol).isPackageClass) tree.symbol - else typeHelper(tree.symbol.info).member(nme.PACKAGE) match { + else tree.symbol.info.member(nme.PACKAGE).symbol match { case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree") case s => abort(s"SI-5604: found package class where package object expected: $tree") } @@ -1117,7 +1122,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { receiver != methodOwner && // fast path - the boolean is used to pick either of these two, if they are the same it does not matter style.isVirtual && symHelper(receiver).isEmittedInterface && - typeHelper(defn.ObjectType).decl(method.name).exists && { // fast path - compute overrideChain on the next line only if necessary + defn.ObjectType.decl(method.name).symbol.exists && { // fast path - compute overrideChain on the next line only if necessary val syms = symHelper(method).allOverriddenSymbols !syms.isEmpty && syms.last.owner == defn.ObjectClass } @@ -1320,7 +1325,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val mustUseAnyComparator: Boolean = { val areSameFinals = l.tpe.typeSymbol.is(Flags.Final) && r.tpe.typeSymbol.is(Flags.Final) && (l.tpe =:= r.tpe) - !areSameFinals && isMaybeBoxed(typeHelper(l.tpe).typeSymbol) && isMaybeBoxed(typeHelper(r.tpe).typeSymbol) + !areSameFinals && isMaybeBoxed(l.tpe.widenDealias.typeSymbol) && isMaybeBoxed(r.tpe.widenDealias.typeSymbol) } if (mustUseAnyComparator) { @@ -1409,7 +1414,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (invokeStyle != asm.Opcodes.H_INVOKESTATIC) capturedParamsTypes = lambdaTarget.owner.info :: capturedParamsTypes // Requires https://github.com/scala/scala-java8-compat on the runtime classpath - val returnUnit = typeHelper(lambdaTarget.info.resultType).typeSymbol == defn.UnitClass + val returnUnit = lambdaTarget.info.resultType.widenDealias.typeSymbol == defn.UnitClass val functionalInterfaceDesc: String = generatedType.descriptor val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc // TODO specialization diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index f65f0a0bf862..e93e7938052a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -342,7 +342,12 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ) emitAnnotations(mirrorMethod, others) - emitParamAnnotations(mirrorMethod, typeHelper(m.info).params.map(symHelper(_).annotations)) + val params = Nil // backend uses this to emit annotations on parameter lists of forwarders + // to static methods of companion class + // in Dotty this link does not exists: there is no way to get from method type + // to inner symbols of DefDef + // todo: somehow handle. + emitParamAnnotations(mirrorMethod, params.map(symHelper(_).annotations)) mirrorMethod.visitCode() @@ -376,7 +381,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val linkedClass = symHelper(moduleClass).companionClass lazy val conflictingNames: Set[Name] = { - (typeHelper(linkedClass.info).members collect { case sym if sym.name.isTermName => sym.name }).toSet + (linkedClass.info.allMembers.map(_.symbol) collect { case sym if sym.name.isTermName => sym.name }).toSet } debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") @@ -387,7 +392,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { else if (m.isType || symHelper(m).isDeferred || (m.owner eq defn.ObjectClass) || m.isConstructor || symHelper(m).isExpanded) debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(m.name)) - log(s"No forwarder for $m due to conflict with ${typeHelper(linkedClass.info).member(m.name)}") + log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") else if (symHelper(m).hasAccessBoundary) log(s"No forwarder for non-public member $m") else { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 593c14af9a5b..4f4275291eef 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -126,8 +126,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ private def initJClass(jclass: asm.ClassVisitor): Unit = { - val ps = typeHelper(claszSymbol.info).parents - val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(typeHelper(ps.head).typeSymbol) + val ps = claszSymbol.info.parents + val superClass: String = if (ps.isEmpty) ObjectReference.internalName else internalName(ps.head.widenDealias.typeSymbol) val interfaceNames = classBTypeFromSymbol(claszSymbol).info.interfaces map { case classBType => if (classBType.isNestedClass) { innerClassBufferASM += classBType } @@ -560,7 +560,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { case ReturnBI(_) | Block(_, ReturnBI(_)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () case tpd.EmptyTree => error(NoSpan, "Concrete method has no definition: " + dd + ( - if (settings_debug) "(found: " + typeHelper(methSymbol.owner.info).decls.toList.mkString(", ") + ")" + if (settings_debug) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" else "") ) case _ => @@ -650,7 +650,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { null ) // INVOKESTATIC CREATOR(): android.os.Parcelable$Creator; -- TODO where does this Android method come from? - val callee = typeHelper(symHelper(claszSymbol).companionModule.info).member(androidFieldName) + val callee = symHelper(claszSymbol).companionModule.info.member(androidFieldName).symbol val jowner = internalName(callee.owner) val jname = symHelper(callee).javaSimpleName.toString val jtype = asmMethodType(callee).descriptor diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 04b2f451c3bf..78d59588e7f3 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -715,20 +715,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma implicit def typeHelper(tp: Type): TypeHelper = new TypeHelper { - def member(string: Name): Symbol = tp.member(string.toTermName).symbol - def underlying: Type = tp match { - case t: TypeProxy => t.underlying - case _ => tp - } - - def decl(name: Name): Symbol = tp.decl(name).symbol - - def decls: List[Symbol] = tp.decls.toList - - def members: List[Symbol] = tp.allMembers.map(_.symbol).toList - - def typeSymbol: Symbol = tp.widenDealias.typeSymbol def sortedMembersBasedOnFlags(required: Flags, excluded: Flags): List[Symbol] = { val requiredFlagSet = termFlagSet(required) @@ -816,16 +803,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - def summaryString: String = tp.showSummary() - - def params: List[Symbol] = - Nil // backend uses this to emit annotations on parameter lists of forwarders - // to static methods of companion class - // in Dotty this link does not exists: there is no way to get from method type - // to inner symbols of DefDef - // todo: somehow handle. - - def parents: List[Type] = tp.parents } object SelectBI extends DeconstructorCommon[Select] { @@ -1069,20 +1046,14 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } abstract class TypeHelper { - def params: List[Symbol] + // def params: List[Symbol] /** The members of this type that have all of `required` flags but none of `excluded` flags set. * The members are sorted by name and signature to guarantee a stable ordering. */ def sortedMembersBasedOnFlags(required: Flags, excluded: Flags): List[Symbol] - def members: List[Symbol] - def decl(name: Name): Symbol - def decls: List[Symbol] - def underlying: Type - def parents: List[Type] - def summaryString: String - def typeSymbol: Symbol - def member(string: Name): Symbol + + /** * This method returns the BType for a type reference, for example a parameter type. * From f6b075d89a37b63e56ea02dc7e83c53bf1b90fc0 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 11:48:40 +0200 Subject: [PATCH 30/98] Remove typeHelper --- .../tools/backend/jvm/BCodeHelpers.scala | 4 +- .../backend/jvm/DottyBackendInterface.scala | 199 ++++++++---------- 2 files changed, 94 insertions(+), 109 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index e93e7938052a..8bcc557bcba0 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -257,7 +257,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ final def symDescriptor(sym: Symbol): String = { getClassBTypeAndRegisterInnerClass(sym).descriptor } - final def toTypeKind(tp: Type): BType = typeHelper(tp).toTypeKind(BCodeHelpers.this)(this) + final def toTypeKind(tp: Type): BType = typeToTypeKind(tp)(BCodeHelpers.this)(this) } // end of trait BCInnerClassGen @@ -385,7 +385,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") - for (m0 <- typeHelper(moduleClass.info).sortedMembersBasedOnFlags(required = Flag_METHOD, excluded = ExcludedForwarderFlags)) { + for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flag_METHOD, excluded = ExcludedForwarderFlags)) { val m = if (symHelper(m0).isBridge) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 78d59588e7f3..07fccf322316 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -157,14 +157,14 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma case StringTag => assert(const.value != null, const) // TODO this invariant isn't documented in `case class Constant` av.visit(name, const.stringValue) // `stringValue` special-cases null, but that execution path isn't exercised for a const with StringTag - case ClazzTag => av.visit(name, const.typeValue.toTypeKind(bcodeStore)(innerClasesStore).toASMType) + case ClazzTag => av.visit(name, typeToTypeKind(const.typeValue)(bcodeStore)(innerClasesStore).toASMType) case EnumTag => val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) } case t: TypeApply if (t.fun.symbol == defn.Predef_classOf) => - av.visit(name, t.args.head.tpe.classSymbol.denot.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType) + av.visit(name, typeToTypeKind(t.args.head.tpe.classSymbol.denot.info)(bcodeStore)(innerClasesStore).toASMType) case Ident(nme.WILDCARD) => // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => @@ -714,95 +714,102 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } - implicit def typeHelper(tp: Type): TypeHelper = new TypeHelper { - - - def sortedMembersBasedOnFlags(required: Flags, excluded: Flags): List[Symbol] = { - val requiredFlagSet = termFlagSet(required) - val excludedFlagSet = termFlagSet(excluded) - // The output of `memberNames` is a Set, sort it to guarantee a stable ordering. - val names = tp.memberNames(takeAllFilter).toSeq.sorted - val buffer = mutable.ListBuffer[Symbol]() - names.foreach { name => - buffer ++= tp.memberBasedOnFlags(name, requiredFlagSet, excludedFlagSet) - .alternatives.sortBy(_.signature)(Signature.lexicographicOrdering).map(_.symbol) - } - buffer.toList + /** The members of this type that have all of `required` flags but none of `excluded` flags set. + * The members are sorted by name and signature to guarantee a stable ordering. + */ + def sortedMembersBasedOnFlags(tp: Type, required: Flags, excluded: Flags): List[Symbol] = { + val requiredFlagSet = termFlagSet(required) + val excludedFlagSet = termFlagSet(excluded) + // The output of `memberNames` is a Set, sort it to guarantee a stable ordering. + val names = tp.memberNames(takeAllFilter).toSeq.sorted + val buffer = mutable.ListBuffer[Symbol]() + names.foreach { name => + buffer ++= tp.memberBasedOnFlags(name, requiredFlagSet, excludedFlagSet) + .alternatives.sortBy(_.signature)(Signature.lexicographicOrdering).map(_.symbol) } + buffer.toList + } - def toTypeKind(ct: BCodeHelpers)(storage: ct.BCInnerClassGen): ct.bTypes.BType = { - import ct.bTypes._ - val defn = ctx.definitions - import coreBTypes._ - import Types._ - /** - * Primitive types are represented as TypeRefs to the class symbol of, for example, scala.Int. - * The `primitiveTypeMap` maps those class symbols to the corresponding PrimitiveBType. - */ - def primitiveOrClassToBType(sym: Symbol): BType = { - assert(sym.isClass, sym) - assert(sym != defn.ArrayClass || isCompilingArray, sym) - primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], - storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] - } + /** + * This method returns the BType for a type reference, for example a parameter type. + * + * If the result is a ClassBType for a nested class, it is added to the innerClassBufferASM. + * + * If `t` references a class, toTypeKind ensures that the class is not an implementation class. + * See also comment on getClassBTypeAndRegisterInnerClass, which is invoked for implementation + * classes. + */ + def typeToTypeKind(tp: Type)(ct: BCodeHelpers)(storage: ct.BCInnerClassGen): ct.bTypes.BType = { + import ct.bTypes._ + val defn = ctx.definitions + import coreBTypes._ + import Types._ + /** + * Primitive types are represented as TypeRefs to the class symbol of, for example, scala.Int. + * The `primitiveTypeMap` maps those class symbols to the corresponding PrimitiveBType. + */ + def primitiveOrClassToBType(sym: Symbol): BType = { + assert(sym.isClass, sym) + assert(sym != defn.ArrayClass || isCompilingArray, sym) + primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], + storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] + } - /** - * When compiling Array.scala, the type parameter T is not erased and shows up in method - * signatures, e.g. `def apply(i: Int): T`. A TyperRef to T is replaced by ObjectReference. - */ - def nonClassTypeRefToBType(sym: Symbol): ClassBType = { - assert(sym.isType && isCompilingArray, sym) - ObjectReference.asInstanceOf[ct.bTypes.ClassBType] - } + /** + * When compiling Array.scala, the type parameter T is not erased and shows up in method + * signatures, e.g. `def apply(i: Int): T`. A TyperRef to T is replaced by ObjectReference. + */ + def nonClassTypeRefToBType(sym: Symbol): ClassBType = { + assert(sym.isType && isCompilingArray, sym) + ObjectReference.asInstanceOf[ct.bTypes.ClassBType] + } - tp.widenDealias match { - case JavaArrayType(el) =>ArrayBType(el.toTypeKind(ct)(storage)) // Array type such as Array[Int] (kept by erasure) - case t: TypeRef => - t.info match { + tp.widenDealias match { + case JavaArrayType(el) =>ArrayBType(typeToTypeKind(el)(ct)(storage)) // Array type such as Array[Int] (kept by erasure) + case t: TypeRef => + t.info match { - case _ => - if (!t.symbol.isClass) nonClassTypeRefToBType(t.symbol) // See comment on nonClassTypeRefToBType - else primitiveOrClassToBType(t.symbol) // Common reference to a type such as scala.Int or java.lang.String - } - case Types.ClassInfo(_, sym, _, _, _) => primitiveOrClassToBType(sym) // We get here, for example, for genLoadModule, which invokes toTypeKind(moduleClassSymbol.info) - - /* AnnotatedType should (probably) be eliminated by erasure. However we know it happens for - * meta-annotated annotations (@(ann @getter) val x = 0), so we don't emit a warning. - * The type in the AnnotationInfo is an AnnotatedTpe. Tested in jvm/annotations.scala. - */ - case a @ AnnotatedType(t, _) => - debuglog(s"typeKind of annotated type $a") - t.toTypeKind(ct)(storage) - - /* ExistentialType should (probably) be eliminated by erasure. We know they get here for - * classOf constants: - * class C[T] - * class T { final val k = classOf[C[_]] } - */ - /* case e @ ExistentialType(_, t) => - debuglog(s"typeKind of existential type $e") - t.toTypeKind(ctx)(storage)*/ - - /* The cases below should probably never occur. They are kept for now to avoid introducing - * new compiler crashes, but we added a warning. The compiler / library bootstrap and the - * test suite don't produce any warning. - */ - - case tp => - ctx.warning( - s"an unexpected type representation reached the compiler backend while compiling ${ctx.compilationUnit}: $tp. " + - "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") - - tp match { - case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test - case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) - // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) - case t: SingletonType => t.underlying.toTypeKind(ct)(storage) - case t: RefinedType => t.parent.toTypeKind(ct)(storage) //parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b)) - } - } + case _ => + if (!t.symbol.isClass) nonClassTypeRefToBType(t.symbol) // See comment on nonClassTypeRefToBType + else primitiveOrClassToBType(t.symbol) // Common reference to a type such as scala.Int or java.lang.String + } + case Types.ClassInfo(_, sym, _, _, _) => primitiveOrClassToBType(sym) // We get here, for example, for genLoadModule, which invokes toTypeKind(moduleClassSymbol.info) + + /* AnnotatedType should (probably) be eliminated by erasure. However we know it happens for + * meta-annotated annotations (@(ann @getter) val x = 0), so we don't emit a warning. + * The type in the AnnotationInfo is an AnnotatedTpe. Tested in jvm/annotations.scala. + */ + case a @ AnnotatedType(t, _) => + debuglog(s"typeKind of annotated type $a") + typeToTypeKind(t)(ct)(storage) + + /* ExistentialType should (probably) be eliminated by erasure. We know they get here for + * classOf constants: + * class C[T] + * class T { final val k = classOf[C[_]] } + */ + /* case e @ ExistentialType(_, t) => + debuglog(s"typeKind of existential type $e") + t.toTypeKind(ctx)(storage)*/ + + /* The cases below should probably never occur. They are kept for now to avoid introducing + * new compiler crashes, but we added a warning. The compiler / library bootstrap and the + * test suite don't produce any warning. + */ + + case tp => + ctx.warning( + s"an unexpected type representation reached the compiler backend while compiling ${ctx.compilationUnit}: $tp. " + + "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") + + tp match { + case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test + case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) + // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) + case t: SingletonType => typeToTypeKind(t.underlying)(ct)(storage) + case t: RefinedType => typeToTypeKind(t.parent)(ct)(storage) //parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b)) + } } - } object SelectBI extends DeconstructorCommon[Select] { @@ -1045,28 +1052,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isFunctionClass: Boolean } - abstract class TypeHelper { - // def params: List[Symbol] - - /** The members of this type that have all of `required` flags but none of `excluded` flags set. - * The members are sorted by name and signature to guarantee a stable ordering. - */ - def sortedMembersBasedOnFlags(required: Flags, excluded: Flags): List[Symbol] - - - /** - * This method returns the BType for a type reference, for example a parameter type. - * - * If the result is a ClassBType for a nested class, it is added to the innerClassBufferASM. - * - * If `t` references a class, toTypeKind ensures that the class is not an implementation class. - * See also comment on getClassBTypeAndRegisterInnerClass, which is invoked for implementation - * classes. - */ - def toTypeKind(ctx: BCodeHelpers)(storage: ctx.BCInnerClassGen): ctx.bTypes.BType - - } - abstract class Primitives { def getPrimitive(app: Apply, receiver: Type): Int def isPrimitive(fun: Tree): Boolean From d171865ff3bfef5e67906af4478d01077614babe Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 12:09:45 +0200 Subject: [PATCH 31/98] Remove aliases --- .../tools/backend/jvm/BCodeAsmCommon.scala | 2 +- .../tools/backend/jvm/BCodeBodyBuilder.scala | 22 +++++----- .../tools/backend/jvm/BCodeHelpers.scala | 25 ++++++----- .../tools/backend/jvm/BCodeIdiomatic.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 14 +++--- .../tools/backend/jvm/BytecodeWriters.scala | 8 ++-- .../backend/jvm/DottyBackendInterface.scala | 43 +------------------ 7 files changed, 42 insertions(+), 74 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 9c36fdf841e1..91a4814461c9 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -87,7 +87,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { def enclosingMethodAttribute(classSym: Symbol, classDesc: Symbol => String, methodDesc: Symbol => String): Option[EnclosingMethodEntry] = { if (isAnonymousOrLocalClass(classSym)) { val methodOpt = enclosingMethodForEnclosingMethodAttribute(classSym) - debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(symHelper(_).enclClass)})") + ctx.debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(symHelper(_).enclClass)})") Some(EnclosingMethodEntry( classDesc(enclosingClassForEnclosingMethodAttribute(classSym)), methodOpt.map(symHelper(_).javaSimpleName.toString).orNull, diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 54d08996ba70..7e15adfffb76 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -8,13 +8,15 @@ import scala.tools.asm import scala.tools.asm.{Handle, Label, Opcodes} import BCodeHelpers.InvokeStyle +import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Constants._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Types._ -import dotty.tools.dotc.core.StdNames.nme +import dotty.tools.dotc.core.StdNames.{nme, str} import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.transform.Erasure import dotty.tools.dotc.util.Spans.NoSpan -import dotty.tools.dotc.ast.tpd + /* * @@ -267,7 +269,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { tree match { case ValDef(nme.THIS, _, _) => - debuglog("skipping trivial assign to _$this: " + tree) + ctx.debuglog("skipping trivial assign to _$this: " + tree) case tree@ValDef(_, _, _) => val sym = tree.symbol @@ -352,7 +354,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case SelectBI(qualifier, _) => val sym = tree.symbol generatedType = symInfoTK(sym) - val qualSafeToElide = isQualifierSafeToElide(qualifier) + val qualSafeToElide = tpd.isIdempotentExpr(qualifier) def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } } @@ -690,7 +692,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { mnode.visitFieldInsn( asm.Opcodes.PUTSTATIC, thisName, - MODULE_INSTANCE_FIELD, + str.MODULE_INSTANCE_FIELD, "L" + thisName + ";" ) } @@ -732,14 +734,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { abort(s"Cannot instantiate $tpt of kind: $generatedType") } - case Apply(fun, List(expr)) if isBox(fun.symbol) => + case Apply(fun, List(expr)) if Erasure.Boxing.isBox(fun.symbol) && fun.symbol.denot.owner != defn.UnitModuleClass => val nativeKind = tpeTK(expr) genLoad(expr, nativeKind) val MethodNameAndType(mname, methodType) = asmBoxTo(nativeKind) bc.invokestatic(BoxesRunTime.internalName, mname, methodType.descriptor, itf = false) generatedType = boxResultType(fun.symbol) // was toTypeKind(fun.symbol.tpe.resultType) - case Apply(fun, List(expr)) if isUnbox(fun.symbol) => + case Apply(fun, List(expr)) if Erasure.Boxing.isUnbox(fun.symbol) && fun.symbol.denot.owner != defn.UnitModuleClass => genLoad(expr) val boxType = unboxResultType(fun.symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) generatedType = boxType @@ -1025,7 +1027,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { mnode.visitFieldInsn( asm.Opcodes.GETSTATIC, mbt.internalName /* + "$" */ , - MODULE_INSTANCE_FIELD, + str.MODULE_INSTANCE_FIELD, mbt.descriptor // for nostalgics: toTypeKind(module.tpe).descriptor ) } @@ -1073,7 +1075,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { bc.genStartConcat for (elem <- concatenations) { val loadedElem = elem match { - case Apply(boxOp, value :: Nil) if isBox(boxOp.symbol) => + case Apply(boxOp, value :: Nil) if Erasure.Boxing.isBox(boxOp.symbol) && boxOp.symbol.denot.owner != defn.UnitModuleClass => // Eliminate boxing of primitive values. Boxing is introduced by erasure because // there's only a single synthetic `+` method "added" to the string class. value @@ -1389,7 +1391,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genInvokeDynamicLambda(ctor: Symbol, lambdaTarget: Symbol, environmentSize: Int, functionalInterface: Symbol): BType = { import java.lang.invoke.LambdaMetafactory.FLAG_SERIALIZABLE - debuglog(s"Using invokedynamic rather than `new ${ctor.owner}`") + ctx.debuglog(s"Using invokedynamic rather than `new ${ctor.owner}`") val generatedType = classBTypeFromSymbol(functionalInterface) // Lambdas should be serializable if they implement a SAM that extends Serializable or if they // implement a scala.Function* class. diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 8bcc557bcba0..5e5a4938ebf8 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -8,6 +8,9 @@ import scala.collection.mutable import dotty.tools.io.AbstractFile import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.StdNames.str +import dotty.tools.dotc.core.Decorators._ +import dotty.tools.dotc.core.Flags /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -351,7 +354,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { mirrorMethod.visitCode() - mirrorMethod.visitFieldInsn(asm.Opcodes.GETSTATIC, moduleName, MODULE_INSTANCE_FIELD, symDescriptor(module)) + mirrorMethod.visitFieldInsn(asm.Opcodes.GETSTATIC, moduleName, str.MODULE_INSTANCE_FIELD, symDescriptor(module)) var index = 0 for(jparamType <- paramJavaTypes) { @@ -377,26 +380,26 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ def addForwarders(jclass: asm.ClassVisitor, jclassName: String, moduleClass: Symbol): Unit = { assert(symHelper(moduleClass).isModuleClass, moduleClass) - debuglog(s"Dumping mirror class for object: $moduleClass") + ctx.debuglog(s"Dumping mirror class for object: $moduleClass") val linkedClass = symHelper(moduleClass).companionClass lazy val conflictingNames: Set[Name] = { (linkedClass.info.allMembers.map(_.symbol) collect { case sym if sym.name.isTermName => sym.name }).toSet } - debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") + ctx.debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") - for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flag_METHOD, excluded = ExcludedForwarderFlags)) { + for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flags.Method.bits, excluded = DottyBackendInterface.ExcludedForwarderFlags.bits)) { val m = if (symHelper(m0).isBridge) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) - log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") + ctx.log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") else if (m.isType || symHelper(m).isDeferred || (m.owner eq defn.ObjectClass) || m.isConstructor || symHelper(m).isExpanded) - debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") + ctx.debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(m.name)) - log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") + ctx.log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") else if (symHelper(m).hasAccessBoundary) - log(s"No forwarder for non-public member $m") + ctx.log(s"No forwarder for non-public member $m") else { - log(s"Adding static forwarder for '$m' from $jclassName to '$moduleClass'") + ctx.log(s"Adding static forwarder for '$m' from $jclassName to '$moduleClass'") addForwarder(jclass, moduleClass, m) } } @@ -515,7 +518,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * Classes implementing the `Parcelable` interface must also have a static field called `CREATOR`, * which is an object implementing the `Parcelable.Creator` interface. */ - val androidFieldName = newTermName("CREATOR") + val androidFieldName = "CREATOR".toTermName lazy val AndroidParcelableInterface : Symbol = getClassIfDefined("android.os.Parcelable") lazy val AndroidCreatorClass : Symbol = getClassIfDefined("android.os.Parcelable$Creator") @@ -549,7 +552,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { clinit.visitFieldInsn( asm.Opcodes.GETSTATIC, moduleName, - MODULE_INSTANCE_FIELD, + str.MODULE_INSTANCE_FIELD, "L" + moduleName + ";" ) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala b/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala index 785644e24159..90519a5d105f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala @@ -23,7 +23,7 @@ trait BCodeIdiomatic { import bTypes._ import coreBTypes._ - lazy val classfileVersion: Int = targetPlatform match { + lazy val classfileVersion: Int = ctx.settings.target.value match { case "jvm-1.5" => asm.Opcodes.V1_5 case "jvm-1.6" => asm.Opcodes.V1_6 case "jvm-1.7" => asm.Opcodes.V1_7 diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 4f4275291eef..5f0eaa961971 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -9,9 +9,11 @@ import scala.tools.asm import scala.tools.asm.util.{TraceMethodVisitor, ASMifier} import java.io.PrintWriter +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.util.Spans.NoSpan -import dotty.tools.dotc.ast.tpd /* * @@ -161,7 +163,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } else { - val skipStaticForwarders = (symHelper(claszSymbol).isInterface || symHelper(claszSymbol).isModule || noForwarders) + val skipStaticForwarders = (symHelper(claszSymbol).isInterface || symHelper(claszSymbol).isModule || ctx.settings.XnoForwarders.value) if (!skipStaticForwarders) { val lmoc = symHelper(claszSymbol).companionModule // add static forwarders if there are no name conflicts; see bugs #363 and #1735 @@ -169,7 +171,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // it must be a top level class (name contains no $s) val isCandidateForForwarders = symHelper(lmoc).shouldEmitForwarders if (isCandidateForForwarders) { - log(s"Adding static forwarders from '$claszSymbol' to implementations in '$lmoc'") + ctx.log(s"Adding static forwarders from '$claszSymbol' to implementations in '$lmoc'") addForwarders(cnode, thisName, symHelper(lmoc).moduleClass) } } @@ -187,7 +189,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { private def addModuleInstanceField(): Unit = { val fv = cnode.visitField(GenBCodeOps.PublicStaticFinal, // TODO confirm whether we really don't want ACC_SYNTHETIC nor ACC_DEPRECATED - MODULE_INSTANCE_FIELD, + str.MODULE_INSTANCE_FIELD, "L" + thisName + ";", null, // no java-generic-signature null // no initial value @@ -365,7 +367,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ def makeLocal(tk: BType, name: String, tpe: Type, pos: Position): Symbol = { - val locSym = symHelper(methSymbol).freshLocal(cunit, name, tpe, pos, Flag_SYNTHETIC) // setInfo tpe + val locSym = symHelper(methSymbol).freshLocal(cunit, name, tpe, pos, Flags.Synthetic.bits) // setInfo tpe makeLocal(locSym, tk) locSym } @@ -560,7 +562,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { case ReturnBI(_) | Block(_, ReturnBI(_)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () case tpd.EmptyTree => error(NoSpan, "Concrete method has no definition: " + dd + ( - if (settings_debug) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" + if (ctx.settings.Ydebug.value) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" else "") ) case _ => diff --git a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala index 28ff01e6542b..cd7dae4100a6 100644 --- a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala +++ b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala @@ -34,7 +34,7 @@ trait BytecodeWriters { getFile(symHelper(sym).outputDirectory, clsName, suffix) def factoryNonJarBytecodeWriter(): BytecodeWriter = { - val emitAsmp = int.emitAsmp + val emitAsmp = None val doDump = int.dumpClasses (emitAsmp.isDefined, doDump.isDefined) match { case (false, false) => new ClassBytecodeWriter { } @@ -61,7 +61,7 @@ trait BytecodeWriters { try out.write(jclassBytes, 0, jclassBytes.length) finally out.flush() - informProgress("added " + label + path + " to jar") + ctx.informProgress("added " + label + path + " to jar") } override def close() = writer.close() } @@ -77,7 +77,7 @@ trait BytecodeWriters { trait AsmpBytecodeWriter extends BytecodeWriter { import scala.tools.asm - private val baseDir = Directory(int.emitAsmp.get).createDirectory() + private val baseDir = Directory(None.get).createDirectory() // FIXME missing directoy private def emitAsmp(jclassBytes: Array[Byte], asmpFile: dotty.tools.io.File): Unit = { val pw = asmpFile.printWriter() @@ -111,7 +111,7 @@ trait BytecodeWriters { try outstream.write(jclassBytes, 0, jclassBytes.length) finally outstream.close() - informProgress("wrote '" + label + "' to " + outfile) + ctx.informProgress("wrote '" + label + "' to " + outfile) } } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 07fccf322316..4918e1741d91 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -104,19 +104,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma s eq defn.newArrayMethod } - def isBox(sym: Symbol): Boolean = - Erasure.Boxing.isBox(sym) && sym.denot.owner != defn.UnitModuleClass - def isUnbox(sym: Symbol): Boolean = - Erasure.Boxing.isUnbox(sym) && sym.denot.owner != defn.UnitModuleClass - - val primitives: Primitives = new Primitives { - val primitives = new DottyPrimitives(ctx) - def getPrimitive(app: Apply, receiver: Type): Int = primitives.getPrimitive(app, receiver) - - def getPrimitive(sym: Symbol): Int = primitives.getPrimitive(sym) - - def isPrimitive(fun: Tree): Boolean = primitives.isPrimitive(fun) - } + val primitives = new DottyPrimitives(ctx) def isRuntimeVisible(annot: Annotation): Boolean = if (toDenot(annot.tree.tpe.typeSymbol).hasAnnotation(AnnotationRetentionAttr)) @@ -290,9 +278,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma ctx.requiredModule(className) } - def debuglog(msg: => String): Unit = ctx.debuglog(msg) - def informProgress(msg: String): Unit = ctx.informProgress(msg) - def log(msg: => String): Unit = ctx.log(msg) def error(pos: Position, msg: String): Unit = ctx.error(msg, sourcePos(pos)) def warning(pos: Position, msg: String): Unit = ctx.warning(msg, sourcePos(pos)) def abort(msg: String): Nothing = { @@ -302,16 +287,11 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def sourcePos(pos: Position)(implicit ctx: Context): util.SourcePosition = ctx.source.atSpan(pos) - def emitAsmp: Option[String] = None - def dumpClasses: Option[String] = if (ctx.settings.Ydumpclasses.isDefault) None else Some(ctx.settings.Ydumpclasses.value) - def noForwarders: Boolean = ctx.settings.XnoForwarders.value def debuglevel: Int = 3 // 0 -> no debug info; 1-> filename; 2-> lines; 3-> varnames - def settings_debug: Boolean = ctx.settings.Ydebug.value - def targetPlatform: String = ctx.settings.target.value val perRunCaches: Caches = new Caches { def newAnyRefMap[K <: AnyRef, V](): mutable.AnyRefMap[K, V] = new mutable.AnyRefMap[K, V]() @@ -322,19 +302,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def newSet[K](): mutable.Set[K] = new mutable.HashSet[K] } - val MODULE_INSTANCE_FIELD: String = str.MODULE_INSTANCE_FIELD - def dropModule(str: String): String = if (!str.isEmpty && str.last == '$') str.take(str.length - 1) else str - def newTermName(prefix: String): Name = prefix.toTermName - - val Flag_SYNTHETIC: Flags = Flags.Synthetic.bits - val Flag_METHOD: Flags = Flags.Method.bits - val ExcludedForwarderFlags: Flags = DottyBackendInterface.ExcludedForwarderFlags.bits - - def isQualifierSafeToElide(qual: Tree): Boolean = tpd.isIdempotentExpr(qual) - private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] def desugarIdent(i: Ident): Option[tpd.Select] = { @@ -488,11 +458,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma 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 isExpanded: Boolean = sym.name.is(ExpandedName) - // def isAnonymousFunction: Boolean = toDenot(sym).isAnonymousFunction def isMethod: Boolean = sym.is(Flags.Method) def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) def isSynthetic: Boolean = sym.is(Flags.Synthetic) @@ -503,8 +469,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def isLabel: Boolean = sym.is(Flags.Label) def hasPackageFlag: Boolean = sym.is(Flags.Package) def isInterface: Boolean = (sym.is(Flags.PureInterface)) || (sym.is(Flags.Trait)) - // def isGetter: Boolean = toDenot(sym).isGetter - // def isSetter: Boolean = toDenot(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) @@ -549,9 +513,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma (sym.is(Flags.Module)) && sym.isStatic def isEnum = sym.is(Flags.Enum) - // def isClassConstructor: Boolean = toDenot(sym).isClassConstructor - // def isAnnotation: Boolean = toDenot(sym).isAnnotation - // def isSerializable: Boolean = toDenot(sym).isSerializable /** * True for module classes of modules that are top-level or owned only by objects. Module classes @@ -780,7 +741,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma * The type in the AnnotationInfo is an AnnotatedTpe. Tested in jvm/annotations.scala. */ case a @ AnnotatedType(t, _) => - debuglog(s"typeKind of annotated type $a") + ctx.debuglog(s"typeKind of annotated type $a") typeToTypeKind(t)(ct)(storage) /* ExistentialType should (probably) be eliminated by erasure. We know they get here for From b2f11885385d9b22c10e0acb8c282d38f374aafa Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 12:16:43 +0200 Subject: [PATCH 32/98] Remove more aliases --- .../tools/backend/jvm/BCodeAsmCommon.scala | 2 +- .../tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- .../tools/backend/jvm/BCodeHelpers.scala | 4 +-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 10 +++--- .../tools/backend/jvm/BTypesFromSymbols.scala | 2 +- .../backend/jvm/DottyBackendInterface.scala | 34 ++++++++----------- 6 files changed, 24 insertions(+), 30 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 91a4814461c9..d55d4c286df7 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -87,7 +87,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { def enclosingMethodAttribute(classSym: Symbol, classDesc: Symbol => String, methodDesc: Symbol => String): Option[EnclosingMethodEntry] = { if (isAnonymousOrLocalClass(classSym)) { val methodOpt = enclosingMethodForEnclosingMethodAttribute(classSym) - ctx.debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(symHelper(_).enclClass)})") + ctx.debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(_.enclosingClass)})") Some(EnclosingMethodEntry( classDesc(enclosingClassForEnclosingMethodAttribute(classSym)), methodOpt.map(symHelper(_).javaSimpleName.toString).orNull, diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 7e15adfffb76..b2d0e1950753 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1020,7 +1020,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(module: Symbol): Unit = { def inStaticMethod = methSymbol != null && symHelper(methSymbol).isStaticMember - if (claszSymbol == symHelper(module).moduleClass && jMethodName != "readResolve" && !inStaticMethod) { + if (claszSymbol == module.moduleClass && jMethodName != "readResolve" && !inStaticMethod) { mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) } else { val mbt = symInfoTK(module).asClassBType diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 5e5a4938ebf8..667a28c9121e 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -382,7 +382,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { assert(symHelper(moduleClass).isModuleClass, moduleClass) ctx.debuglog(s"Dumping mirror class for object: $moduleClass") - val linkedClass = symHelper(moduleClass).companionClass + val linkedClass = moduleClass.companionClass lazy val conflictingNames: Set[Name] = { (linkedClass.info.allMembers.map(_.symbol) collect { case sym if sym.name.isTermName => sym.name }).toSet } @@ -470,7 +470,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ def genMirrorClass(moduleClass: Symbol, cunit: CompilationUnit): asm.tree.ClassNode = { assert(symHelper(moduleClass).isModuleClass) - assert(symHelper(moduleClass).companionClass == NoSymbol, moduleClass) + assert(moduleClass.companionClass == NoSymbol, moduleClass) innerClassBufferASM.clear() this.cunit = cunit val moduleName = internalName(moduleClass) // + "$" diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 5f0eaa961971..a3ecd94be545 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -165,14 +165,14 @@ trait BCodeSkelBuilder extends BCodeHelpers { val skipStaticForwarders = (symHelper(claszSymbol).isInterface || symHelper(claszSymbol).isModule || ctx.settings.XnoForwarders.value) if (!skipStaticForwarders) { - val lmoc = symHelper(claszSymbol).companionModule + val lmoc = claszSymbol.companionModule // add static forwarders if there are no name conflicts; see bugs #363 and #1735 if (lmoc != NoSymbol) { // it must be a top level class (name contains no $s) val isCandidateForForwarders = symHelper(lmoc).shouldEmitForwarders if (isCandidateForForwarders) { ctx.log(s"Adding static forwarders from '$claszSymbol' to implementations in '$lmoc'") - addForwarders(cnode, thisName, symHelper(lmoc).moduleClass) + addForwarders(cnode, thisName, lmoc.moduleClass) } } } @@ -628,10 +628,10 @@ trait BCodeSkelBuilder extends BCodeHelpers { // call object's private ctor from static ctor if (isCZStaticModule) { // NEW `moduleName` - val className = internalName(symHelper(methSymbol).enclClass) + val className = internalName(methSymbol.enclosingClass) insnModA = new asm.tree.TypeInsnNode(asm.Opcodes.NEW, className) // INVOKESPECIAL - val callee = symHelper(methSymbol).enclClass.primaryConstructor + val callee = methSymbol.enclosingClass.primaryConstructor val jname = symHelper(callee).javaSimpleName.toString val jowner = internalName(callee.owner) val jtype = asmMethodType(callee).descriptor @@ -652,7 +652,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { null ) // INVOKESTATIC CREATOR(): android.os.Parcelable$Creator; -- TODO where does this Android method come from? - val callee = symHelper(claszSymbol).companionModule.info.member(androidFieldName).symbol + val callee = claszSymbol.companionModule.info.member(androidFieldName).symbol val jowner = internalName(callee.owner) val jname = symHelper(callee).javaSimpleName.toString val jtype = asmMethodType(callee).descriptor diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index c92267e03c06..6be27c3af2bc 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -111,7 +111,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // This is done by buildNestedInfo, the reason is Java compatibility, see comment in BTypes. // For consistency, the InnerClass entry for D needs to be present in C - to Java it looks // like D is a member of C, not C$. - val linkedClass = symHelper(classSym).linkedClass + val linkedClass = classSym.linkedClass val companionModuleMembers = symHelper(classSym).companionModuleMembers nestedClasses ++ companionModuleMembers diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 4918e1741d91..e78c3fe20b55 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -484,7 +484,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma * which we represent as classes. */ def isEmittedInterface: Boolean = isInterface || - isJavaDefined && (toDenot(sym).isAnnotation || isModuleClass && symHelper(companionClass).isInterface) + isJavaDefined && (toDenot(sym).isAnnotation || isModuleClass && symHelper(sym.companionClass).isInterface) def getsJavaPrivateFlag: Boolean = isPrivate || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) @@ -549,13 +549,13 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } else t } - def enclClass: Symbol = toDenot(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 companionSymbol: Symbol = if (sym.is(Flags.Module)) companionClass else companionModule - def moduleClass: Symbol = toDenot(sym).moduleClass + // def enclClass: Symbol = toDenot(sym).enclosingClass + def linkedClassOfClass: Symbol = sym.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 companionSymbol: Symbol = if (sym.is(Flags.Module)) sym.companionClass else sym.companionModule + // def moduleClass: Symbol = toDenot(sym).moduleClass def enclosingClassSym: Symbol = { if (this.isClass) { val ct = ctx.withPhase(ctx.flattenPhase.prev) @@ -599,7 +599,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma 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 example) that were lifted by lambdalift. - if (linkedClass.isTopLevelModuleClass) /*exitingPickler*/ linkedClass.memberClasses + if (sym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ sym.linkedClass.memberClasses else Nil } def fieldSymbols: List[Symbol] = { @@ -625,9 +625,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos) } - def getter(clz: Symbol): Symbol = decorateSymbol(sym).getter - def setter(clz: Symbol): Symbol = decorateSymbol(sym).setter - def moduleSuffix: String = "" // todo: validate that names already have $ suffix def outputDirectory: AbstractFile = DottyBackendInterface.this.outputDirectory def pos: Position = sym.span @@ -946,13 +943,13 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def originalOwner: Symbol def parentSymbols: List[Symbol] def superClass: Symbol - def enclClass: Symbol + // def enclClass: Symbol def linkedClassOfClass: Symbol - def linkedClass: Symbol - def companionClass: Symbol - def companionModule: Symbol + // def linkedClass: Symbol + // def companionClass: Symbol + // def companionModule: Symbol def companionSymbol: Symbol - def moduleClass: Symbol + // def moduleClass: Symbol def enclosingClassSym: Symbol def originalLexicallyEnclosingClass: Symbol // def nextOverriddenSymbol: Symbol @@ -972,9 +969,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol - def getter(clz: Symbol): Symbol - def setter(clz: Symbol): Symbol - def moduleSuffix: String def outputDirectory: AbstractFile def pos: Position From dd16adbb4422bf7834a3bd76de9c16800c260945 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 15:31:30 +0200 Subject: [PATCH 33/98] Remove some methods from symbolHelper --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- .../tools/backend/jvm/BCodeHelpers.scala | 4 ++-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 6 ++--- .../tools/backend/jvm/BTypesFromSymbols.scala | 2 +- .../tools/backend/jvm/BytecodeWriters.scala | 2 +- .../backend/jvm/DottyBackendInterface.scala | 23 +------------------ 6 files changed, 9 insertions(+), 30 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index b2d0e1950753..ea72a599f05d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1395,7 +1395,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val generatedType = classBTypeFromSymbol(functionalInterface) // Lambdas should be serializable if they implement a SAM that extends Serializable or if they // implement a scala.Function* class. - val isSerializable = functionalInterface.isSerializable || symHelper(functionalInterface).isFunctionClass + val isSerializable = functionalInterface.isSerializable || defn.isFunctionClass(functionalInterface) val isInterface = symHelper(lambdaTarget.owner).isEmittedInterface val invokeStyle = if (symHelper(lambdaTarget).isStaticMember) asm.Opcodes.H_INVOKESTATIC diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 667a28c9121e..77d5a60fe7e3 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -44,10 +44,10 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ def getOutFolder(csym: Symbol, cName: String): AbstractFile = { try { - symHelper(csym).outputDirectory + outputDirectory } catch { case ex: Throwable => - int.error(symHelper(csym).pos, s"Couldn't create file for class $cName\n${ex.getMessage}") + int.error(csym.span, s"Couldn't create file for class $cName\n${ex.getMessage}") null } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index a3ecd94be545..5ed798b47965 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -284,7 +284,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ var jumpDest: immutable.Map[ /* Labeled or LabelDef */ Symbol, asm.Label ] = null def programPoint(labelSym: Symbol): asm.Label = { - assert(symHelper(labelSym).isLabel, s"trying to map a non-label symbol to an asm.Label, at: ${symHelper(labelSym).pos}") + assert(symHelper(labelSym).isLabel, s"trying to map a non-label symbol to an asm.Label, at: ${labelSym.span}") jumpDest.getOrElse(labelSym, { val pp = new asm.Label jumpDest += (labelSym -> pp) @@ -386,7 +386,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val loc = Local(tk, symHelper(sym).javaSimpleName.toString, nxtIdx, symHelper(sym).isSynthetic) val existing = slots.put(sym, loc) if (existing.isDefined) - error(symHelper(sym).pos, "attempt to create duplicate local var.") + error(sym.span, "attempt to create duplicate local var.") assert(tk.size > 0, "makeLocal called for a symbol whose type is Unit.") nxtIdx += tk.size loc @@ -535,7 +535,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { if (params.size > MaximumJvmParameters) { // SI-7324 - error(symHelper(methSymbol).pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.") + error(methSymbol.span, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.") return } diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 6be27c3af2bc..b8165141f7de 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -171,7 +171,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val innerName: Option[String] = { if (innerClassSym.isAnonymousClass || innerClassSym.isAnonymousFunction) None - else Some(symHelper(innerClassSym).rawname + symHelper(innerClassSym).moduleSuffix) // moduleSuffix for module classes + else Some(symHelper(innerClassSym).rawname) // moduleSuffix for module classes } Some(NestedInfo(enclosingClass, outerName, innerName, isStaticNestedClass)) diff --git a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala index cd7dae4100a6..c95f4a77389c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala +++ b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala @@ -31,7 +31,7 @@ trait BytecodeWriters { ensureDirectory(dir) fileNamed pathParts.last + suffix } def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile = - getFile(symHelper(sym).outputDirectory, clsName, suffix) + getFile(outputDirectory, clsName, suffix) def factoryNonJarBytecodeWriter(): BytecodeWriter = { val emitAsmp = None diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index e78c3fe20b55..9b9217f3ec23 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -32,7 +32,7 @@ import StdNames.{nme, str} import NameKinds.{DefaultGetterName, ExpandedName} import Names.TermName -class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit val ctx: Context) { +class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit val ctx: Context) { 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. @@ -625,10 +625,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos) } - def moduleSuffix: String = "" // todo: validate that names already have $ suffix - def outputDirectory: AbstractFile = DottyBackendInterface.this.outputDirectory - def pos: Position = sym.span - def throwsAnnotations: List[Symbol] = Nil /** @@ -667,8 +663,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } } - def isFunctionClass: Boolean = - defn.isFunctionClass(sym) } @@ -969,10 +963,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol - def moduleSuffix: String - def outputDirectory: AbstractFile - def pos: Position - def throwsAnnotations: List[Symbol] /** @@ -1000,17 +990,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma isPackageClass || isModuleClass && symHelper(symHelper(originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner def samMethod(): Symbol - - /** Is this the symbol of one of the `scala.Function*` class ? - * Note that this will return false for subclasses of these classes. - */ - def isFunctionClass: Boolean - } - - abstract class Primitives { - def getPrimitive(app: Apply, receiver: Type): Int - def isPrimitive(fun: Tree): Boolean - def getPrimitive(sym: Symbol): Int } abstract class Caches { From 4601c6a7737e2b2febb9e88c666fc6956251ab67 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 16:16:55 +0200 Subject: [PATCH 34/98] Remove methods from DottyBackendInterface --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 10 +++++++ .../tools/backend/jvm/BCodeHelpers.scala | 8 +++--- .../tools/backend/jvm/BCodeSkelBuilder.scala | 22 +++++++++++---- .../backend/jvm/DottyBackendInterface.scala | 28 +------------------ 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index ea72a599f05d..6a646c052ef6 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1250,6 +1250,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genComparisonOp(l: Tree, r: Tree, code: Int): Unit = { val op = testOpForPrimitive(code) + def isNull(t: Tree): Boolean = t match { + case Literal(Constant(null)) => true + case _ => false + } + def ifOneIsNull(l: Tree, r: Tree): Tree = if (isNull(l)) r else if (isNull(r)) l else null val nonNullSide = if (ScalaPrimitivesOps.isReferenceEqualityOp(code)) ifOneIsNull(l, r) else null if (nonNullSide != null) { // special-case reference (in)equality test for null (null eq x, x eq null) @@ -1329,6 +1334,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { !areSameFinals && isMaybeBoxed(l.tpe.widenDealias.typeSymbol) && isMaybeBoxed(r.tpe.widenDealias.typeSymbol) } + def isNull(t: Tree): Boolean = t match { + case Literal(Constant(null)) => true + case _ => false + } + def isNonNullExpr(t: Tree): Boolean = t.isInstanceOf[Literal] || ((t.symbol ne null) && symHelper(t.symbol).isModule) if (mustUseAnyComparator) { val equalsMethod: Symbol = { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 77d5a60fe7e3..b913970d2c16 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -330,7 +330,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // TODO needed? for(ann <- m.annotations) { ann.symbol.initialize } val jgensig = getStaticForwarderGenericSignature(m, module) - val (throws, others) = symHelper(m).annotations partition (_.tree.symbol == defn.ThrowsAnnot) + val (throws, others) = m.annotations partition (_.tree.symbol == defn.ThrowsAnnot) val thrownExceptions: List[String] = getExceptions(throws) val jReturnType = toTypeKind(methodInfo.resultType) @@ -345,12 +345,12 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ) emitAnnotations(mirrorMethod, others) - val params = Nil // backend uses this to emit annotations on parameter lists of forwarders + val params: List[Symbol] = Nil // backend uses this to emit annotations on parameter lists of forwarders // to static methods of companion class // in Dotty this link does not exists: there is no way to get from method type // to inner symbols of DefDef // todo: somehow handle. - emitParamAnnotations(mirrorMethod, params.map(symHelper(_).annotations)) + emitParamAnnotations(mirrorMethod, params.map(_.annotations)) mirrorMethod.visitCode() @@ -494,7 +494,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val ssa = getAnnotPickle(mirrorName, symHelper(moduleClass).companionSymbol) mirrorClass.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) - emitAnnotations(mirrorClass, symHelper(moduleClass).annotations ++ ssa) + emitAnnotations(mirrorClass, moduleClass.annotations ++ ssa) addForwarders(mirrorClass, mirrorName, moduleClass) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 5ed798b47965..0613d0526016 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -106,7 +106,19 @@ trait BCodeSkelBuilder extends BCodeHelpers { } } - val optSerial: Option[Long] = symHelper(claszSymbol).serialVUID + val optSerial: Option[Long] = + claszSymbol.getAnnotation(defn.SerialVersionUIDAnnot).flatMap { annot => + if (claszSymbol.is(Flags.Trait)) { + ctx.error("@SerialVersionUID does nothing on a trait", annot.tree.sourcePos) + None + } else { + val vuid = annot.argumentConstant(0).map(_.longValue) + if (vuid.isEmpty) + ctx.error("The argument passed to @SerialVersionUID must be a constant", + annot.argument(0).getOrElse(annot.tree).sourcePos) + vuid + } + } if (optSerial.isDefined) { addSerialVUID(optSerial.get, cnode)} addClassFields() @@ -155,7 +167,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val ssa = getAnnotPickle(thisName, claszSymbol) cnode.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) - emitAnnotations(cnode, symHelper(claszSymbol).annotations ++ ssa) + emitAnnotations(cnode, claszSymbol.annotations ++ ssa) if (isCZStaticModule || isCZParcelable) { @@ -248,7 +260,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { null // no initial value ) cnode.fields.add(jfield) - emitAnnotations(jfield, symHelper(f).annotations) + emitAnnotations(jfield, f.annotations) } } // end of method addClassFields() @@ -488,7 +500,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { def initJMethod(flags: Int, paramAnnotations: List[List[Annotation]]): Unit = { val jgensig = getGenericSignature(methSymbol, claszSymbol) - val (excs, others) = symHelper(methSymbol).annotations partition (_.tree.symbol == defn.ThrowsAnnot) + val (excs, others) = methSymbol.annotations partition (_.tree.symbol == defn.ThrowsAnnot) val thrownExceptions: List[String] = getExceptions(excs) val bytecodeName = @@ -549,7 +561,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { ) // TODO needed? for(ann <- m.symbol.annotations) { ann.symbol.initialize } - initJMethod(flags, params.map(p => symHelper(p.symbol).annotations)) + initJMethod(flags, params.map(p => p.symbol.annotations)) if (!isAbstractMethod && !isNative) { diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 9b9217f3ec23..c4f5256b2b93 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -595,7 +595,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } else Nil - def annotations: List[Annotation] = toDenot(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 example) that were lifted by lambdalift. @@ -607,19 +606,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } def methodSymbols: List[Symbol] = for (f <- toDenot(sym).info.decls.toList if f.isMethod && f.isTerm && !f.isModule) yield f - def serialVUID: Option[Long] = - sym.getAnnotation(defn.SerialVersionUIDAnnot).flatMap { annot => - if (sym.is(Flags.Trait)) { - ctx.error("@SerialVersionUID does nothing on a trait", annot.tree.sourcePos) - None - } else { - val vuid = annot.argumentConstant(0).map(_.longValue) - if (vuid.isEmpty) - ctx.error("The argument passed to @SerialVersionUID must be a constant", - annot.argument(0).getOrElse(annot.tree).sourcePos) - vuid - } - } + def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = { ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos) @@ -954,11 +941,9 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // def primaryConstructor: Symbol def nestedClasses: List[Symbol] def memberClasses: List[Symbol] - def annotations: List[Annotation] def companionModuleMembers: List[Symbol] def fieldSymbols: List[Symbol] def methodSymbols: List[Symbol] - def serialVUID: Option[Long] def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol @@ -1016,17 +1001,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type] - def isNull(t: Tree): Boolean = t match { - case Literal(Constant(null)) => true - case _ => false - } - def isLiteral(t: Tree): Boolean = t match { - case Literal(_) => true - case _ => false - } - def isNonNullExpr(t: Tree): Boolean = isLiteral(t) || ((t.symbol ne null) && symHelper(t.symbol).isModule) - def ifOneIsNull(l: Tree, r: Tree): Tree = if (isNull(l)) r else if (isNull(r)) l else null - private val primitiveCompilationUnits = Set( "Unit.scala", "Boolean.scala", From c4ddb110eab788b129f6cc7254c98bbd4503d741 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 16:45:43 +0200 Subject: [PATCH 35/98] Remove flag aliases --- .../tools/backend/jvm/BCodeAsmCommon.scala | 3 +- .../tools/backend/jvm/BCodeBodyBuilder.scala | 20 ++--- .../tools/backend/jvm/BCodeHelpers.scala | 14 +-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 10 +-- .../tools/backend/jvm/BTypesFromSymbols.scala | 27 +++--- .../backend/jvm/DottyBackendInterface.scala | 85 ++++++------------- 6 files changed, 65 insertions(+), 94 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index d55d4c286df7..d1ec0d4a4a92 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -2,6 +2,7 @@ package dotty.tools package backend package jvm +import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Symbols._ /** @@ -55,7 +56,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { assert(symHelper(classSym).isClass, classSym) def enclosingMethod(sym: Symbol): Option[Symbol] = { if (symHelper(sym).isClass || sym == NoSymbol) None - else if (symHelper(sym).isMethod) Some(sym) + else if (sym.is(Flags.Method)) Some(sym) else enclosingMethod(symHelper(symHelper(sym).originalOwner).originalLexicallyEnclosingClass) } enclosingMethod(symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 6a646c052ef6..bf36d3c7a58f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -334,7 +334,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType = genApply(app, expectedType) case This(qual) => - val symIsModuleClass = symHelper(tree.symbol).isModuleClass + val symIsModuleClass = tree.symbol.is(Flags.ModuleClass) assert(tree.symbol == claszSymbol || symIsModuleClass, s"Trying to access the this of another class: tree.symbol = ${tree.symbol}, class symbol = $claszSymbol compilation unit: $cunit") if (symIsModuleClass && tree.symbol != claszSymbol) { @@ -348,7 +348,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } case SelectBI(Ident(nme.EMPTY_PACKAGE), module) => - assert(symHelper(tree.symbol).isModule, s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.span}") + assert(tree.symbol.is(Flags.Module), s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.span}") genLoadModule(tree) case SelectBI(qualifier, _) => @@ -360,7 +360,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError def receiverClass = qualifier.tpe.widenDealias.typeSymbol - if (symHelper(sym).isModule) { + if (sym.is(Flags.Module)) { genLoadQualUnlessElidable() genLoadModule(tree) } else if (symHelper(sym).isStaticMember) { @@ -380,7 +380,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { desugared match { case None => if (!symHelper(sym).hasPackageFlag) { - if (symHelper(sym).isModule) genLoadModule(sym) + if (sym.is(Flags.Module)) genLoadModule(sym) else locals.load(sym) } case Some(t) => @@ -551,8 +551,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } } else { // return from labeled - assert(symHelper(fromSym).isLabel, fromSym) - assert(!symHelper(fromSym).isMethod, fromSym) + assert(fromSym.is(Flags.Label), fromSym) + assert(!fromSym.is(Flags.Method), fromSym) /* TODO At the moment, we disregard cleanups, because by construction we don't have return-from-labels * that cross cleanup boundaries. However, in theory such crossings are valid, so we should take care @@ -756,7 +756,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } else { // normal method call val invokeStyle = if (symHelper(sym).isStaticMember) InvokeStyle.Static - else if (symHelper(sym).isPrivate || sym.isClassConstructor) InvokeStyle.Special + else if (sym.is(Flags.Private) || sym.isClassConstructor) InvokeStyle.Special else InvokeStyle.Virtual if (invokeStyle.hasInstance) genLoadQualifier(fun) @@ -1007,7 +1007,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(tree: Tree): BType = { val module = ( - if (!symHelper(tree.symbol).isPackageClass) tree.symbol + if (!tree.symbol.is(Flags.PackageClass)) tree.symbol else tree.symbol.info.member(nme.PACKAGE).symbol match { case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree") case s => abort(s"SI-5604: found package class where package object expected: $tree") @@ -1338,7 +1338,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case Literal(Constant(null)) => true case _ => false } - def isNonNullExpr(t: Tree): Boolean = t.isInstanceOf[Literal] || ((t.symbol ne null) && symHelper(t.symbol).isModule) + def isNonNullExpr(t: Tree): Boolean = t.isInstanceOf[Literal] || ((t.symbol ne null) && t.symbol.is(Flags.Module)) if (mustUseAnyComparator) { val equalsMethod: Symbol = { @@ -1409,7 +1409,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val isInterface = symHelper(lambdaTarget.owner).isEmittedInterface val invokeStyle = if (symHelper(lambdaTarget).isStaticMember) asm.Opcodes.H_INVOKESTATIC - else if (symHelper(lambdaTarget).isPrivate || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL + else if (lambdaTarget.is(Flags.Private) || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL else if (isInterface) asm.Opcodes.H_INVOKEINTERFACE else asm.Opcodes.H_INVOKEVIRTUAL diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index b913970d2c16..a61c0432ad54 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -197,7 +197,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // If the `sym` is a java module class, we use the java class instead. This ensures that we // register the class (instead of the module class) in innerClassBufferASM. // The two symbols have the same name, so the resulting internalName is the same. - val classSym = if (symHelper(sym).isJavaDefined && symHelper(sym).isModuleClass) symHelper(sym).linkedClassOfClass else sym + val classSym = if (sym.is(Flags.JavaDefined) && sym.is(Flags.ModuleClass)) symHelper(sym).linkedClassOfClass else sym getClassBTypeAndRegisterInnerClass(classSym).internalName } @@ -241,7 +241,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ final def asmMethodType(msym: Symbol): MethodBType = { - assert(symHelper(msym).isMethod, s"not a method-symbol: $msym") + assert(msym.is(Flags.Method), s"not a method-symbol: $msym") val resT: BType = if (msym.isClassConstructor || msym.isConstructor) UNIT else toTypeKind(msym.info.resultType) @@ -325,7 +325,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // TODO: evaluate the other flags we might be dropping on the floor here. // TODO: ACC_SYNTHETIC ? val flags = GenBCodeOps.PublicStatic | ( - if (symHelper(m).isVarargsMethod) asm.Opcodes.ACC_VARARGS else 0 + if (m.is(Flags.JavaVarargs)) asm.Opcodes.ACC_VARARGS else 0 ) // TODO needed? for(ann <- m.annotations) { ann.symbol.initialize } @@ -379,7 +379,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def addForwarders(jclass: asm.ClassVisitor, jclassName: String, moduleClass: Symbol): Unit = { - assert(symHelper(moduleClass).isModuleClass, moduleClass) + assert(moduleClass.is(Flags.ModuleClass), moduleClass) ctx.debuglog(s"Dumping mirror class for object: $moduleClass") val linkedClass = moduleClass.companionClass @@ -389,10 +389,10 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ctx.debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flags.Method.bits, excluded = DottyBackendInterface.ExcludedForwarderFlags.bits)) { - val m = if (symHelper(m0).isBridge) m0.nextOverriddenSymbol else m0 + val m = if (m0.is(Flags.Bridge)) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) ctx.log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") - else if (m.isType || symHelper(m).isDeferred || (m.owner eq defn.ObjectClass) || m.isConstructor || symHelper(m).isExpanded) + else if (m.isType || m.is(Flags.Deferred) || (m.owner eq defn.ObjectClass) || m.isConstructor || symHelper(m).isExpanded) ctx.debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(m.name)) ctx.log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") @@ -469,7 +469,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def genMirrorClass(moduleClass: Symbol, cunit: CompilationUnit): asm.tree.ClassNode = { - assert(symHelper(moduleClass).isModuleClass) + assert(moduleClass.is(Flags.ModuleClass)) assert(moduleClass.companionClass == NoSymbol, moduleClass) innerClassBufferASM.clear() this.cunit = cunit diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 0613d0526016..fd069beff532 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -175,7 +175,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } else { - val skipStaticForwarders = (symHelper(claszSymbol).isInterface || symHelper(claszSymbol).isModule || ctx.settings.XnoForwarders.value) + val skipStaticForwarders = (symHelper(claszSymbol).isInterface || claszSymbol.is(Flags.Module) || ctx.settings.XnoForwarders.value) if (!skipStaticForwarders) { val lmoc = claszSymbol.companionModule // add static forwarders if there are no name conflicts; see bugs #363 and #1735 @@ -249,7 +249,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val javagensig = getGenericSignature(f, claszSymbol) val flags = javaFieldFlags(f) - assert(!symHelper(f).isStaticMember || !symHelper(claszSymbol).isInterface || !symHelper(f).isMutable, + assert(!symHelper(f).isStaticMember || !symHelper(claszSymbol).isInterface || !f.is(Flags.Mutable), s"interface $claszSymbol cannot have non-final static field $f") val jfield = new asm.tree.FieldNode( @@ -296,7 +296,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ var jumpDest: immutable.Map[ /* Labeled or LabelDef */ Symbol, asm.Label ] = null def programPoint(labelSym: Symbol): asm.Label = { - assert(symHelper(labelSym).isLabel, s"trying to map a non-label symbol to an asm.Label, at: ${labelSym.span}") + assert(labelSym.is(Flags.Label), s"trying to map a non-label symbol to an asm.Label, at: ${labelSym.span}") jumpDest.getOrElse(labelSym, { val pp = new asm.Label jumpDest += (labelSym -> pp) @@ -395,7 +395,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { private def makeLocal(sym: Symbol, tk: BType): Local = { assert(nxtIdx != -1, "not a valid start index") - val loc = Local(tk, symHelper(sym).javaSimpleName.toString, nxtIdx, symHelper(sym).isSynthetic) + val loc = Local(tk, symHelper(sym).javaSimpleName.toString, nxtIdx, sym.is(Flags.Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) error(sym.span, "attempt to create duplicate local var.") @@ -552,7 +552,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } val isNative = symHelper(methSymbol).hasAnnotation(NativeAttr) - val isAbstractMethod = (symHelper(methSymbol).isDeferred || (symHelper(methSymbol.owner).isInterface && !symHelper(methSymbol).isJavaDefaultMethod)) + val isAbstractMethod = (methSymbol.is(Flags.Deferred) || (symHelper(methSymbol.owner).isInterface && !symHelper(methSymbol).isJavaDefaultMethod)) val flags = GenBCodeOps.mkFlags( javaFlags(methSymbol), if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0, diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index b8165141f7de..ad505fee02c1 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -5,6 +5,7 @@ package jvm import scala.tools.asm import scala.annotation.threadUnsafe +import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Symbols._ /** @@ -124,7 +125,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { * Here we get rid of the module class B, making sure that the class B is present. */ val nestedClassSymbolsNoJavaModuleClasses = nestedClassSymbols.filter(s => { - if (symHelper(s).isJavaDefined && symHelper(s).isModuleClass) { + if (s.is(Flags.JavaDefined) && s.is(Flags.ModuleClass)) { // We could also search in nestedClassSymbols for s.linkedClassOfClass, but sometimes that // returns NoSymbol, so it doesn't work. val nb = nestedClassSymbols.count(mc => mc.name == s.name && mc.owner == s.owner) @@ -146,7 +147,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { assert(symHelper(innerClassSym).isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") - val isNested = !symHelper(symHelper(innerClassSym).rawowner).isPackageClass + val isNested = !symHelper(innerClassSym).rawowner.is(Flags.PackageClass) if (!isNested) None else { // See comment in BTypes, when is a class marked static in the InnerClass table. @@ -206,7 +207,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { import asm.Opcodes._ GenBCodeOps.mkFlags( if (privateFlag) ACC_PRIVATE else ACC_PUBLIC, - if (symHelper(sym).isDeferred || symHelper(sym).hasAbstractFlag) ACC_ABSTRACT else 0, + if (sym.is(Flags.Deferred) || sym.isOneOf(Flags.AbstractOrTrait)) ACC_ABSTRACT else 0, if (symHelper(sym).isInterface) ACC_INTERFACE else 0, if (finalFlag && @@ -214,19 +215,19 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // without having to provide any implementations, but that is an // illegal combination of modifiers at the bytecode level so // suppress final if abstract if present. - !symHelper(sym).hasAbstractFlag && + !sym.isOneOf(Flags.AbstractOrTrait) && // Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks - !symHelper(sym).isBridge) + !sym.is(Flags.Bridge)) ACC_FINAL else 0, - if (symHelper(sym).isStaticMember) ACC_STATIC else 0, - if (symHelper(sym).isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0, - if (symHelper(sym).isArtifact) ACC_SYNTHETIC else 0, + if (sym.isStaticMember) ACC_STATIC else 0, + if (sym.is(Flags.Bridge)) ACC_BRIDGE | ACC_SYNTHETIC else 0, + if (sym.is(Flags.Artifact)) ACC_SYNTHETIC else 0, if (symHelper(sym).isClass && !symHelper(sym).isInterface) ACC_SUPER else 0, - if (symHelper(sym).hasEnumFlag) ACC_ENUM else 0, - if (symHelper(sym).isVarargsMethod) ACC_VARARGS else 0, - if (symHelper(sym).isSynchronized) ACC_SYNCHRONIZED else 0, + if (sym.isAllOf(Flags.JavaEnumTrait)) ACC_ENUM else 0, + if (sym.is(Flags.JavaVarargs)) ACC_VARARGS else 0, + if (sym.is(Flags.Synchronized)) ACC_SYNCHRONIZED else 0, if (false /*sym.isDeprecated*/) asm.Opcodes.ACC_DEPRECATED else 0, - if (symHelper(sym).isEnum) asm.Opcodes.ACC_ENUM else 0 + if (sym.is(Flags.Enum)) asm.Opcodes.ACC_ENUM else 0 ) } @@ -234,7 +235,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { javaFlags(sym) | GenBCodeOps.mkFlags( if (symHelper(sym) hasAnnotation TransientAttr) asm.Opcodes.ACC_TRANSIENT else 0, if (symHelper(sym) hasAnnotation VolatileAttr) asm.Opcodes.ACC_VOLATILE else 0, - if (symHelper(sym).isMutable) 0 else asm.Opcodes.ACC_FINAL + if (sym.is(Flags.Mutable)) 0 else asm.Opcodes.ACC_FINAL ) } } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index c4f5256b2b93..53992e90ce07 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -117,7 +117,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } def shouldEmitAnnotation(annot: Annotation): Boolean = { - annot.symbol.isJavaDefined && + annot.symbol.is(Flags.JavaDefined) && retentionPolicyOf(annot) != AnnotationRetentionSourceAttr } @@ -459,23 +459,15 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap sym.isPackageObject || (sym.isClass) } def isExpanded: Boolean = sym.name.is(ExpandedName) - def isMethod: Boolean = sym.is(Flags.Method) def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) - def isSynthetic: Boolean = sym.is(Flags.Synthetic) - def isPackageClass: Boolean = sym.is(Flags.PackageClass) - def isModuleClass: Boolean = sym.is(Flags.ModuleClass) - def isModule: Boolean = sym.is(Flags.Module) def isStrictFP: Boolean = false // todo: implement - def isLabel: Boolean = sym.is(Flags.Label) def hasPackageFlag: Boolean = sym.is(Flags.Package) def isInterface: Boolean = (sym.is(Flags.PureInterface)) || (sym.is(Flags.Trait)) 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 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)) + sym.is(Flags.Final) && !toDenot(sym).isClassConstructor && !(sym.is(Flags.Mutable)) && !(sym.enclosingClass.is(Flags.Trait)) /** Does this symbol actually correspond to an interface that will be emitted? * In the backend, this should be preferred over `isInterface` because it @@ -484,12 +476,11 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * which we represent as classes. */ def isEmittedInterface: Boolean = isInterface || - isJavaDefined && (toDenot(sym).isAnnotation || isModuleClass && symHelper(sym.companionClass).isInterface) + sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && symHelper(sym.companionClass).isInterface) def getsJavaPrivateFlag: Boolean = - isPrivate || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) + sym.is(Flags.Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) - def isFinal: Boolean = sym.is(Flags.Final) def isScalaStatic: Boolean = toDenot(sym).hasAnnotation(ctx.definitions.ScalaStaticAnnot) def isStaticMember: Boolean = (sym ne NoSymbol) && @@ -497,21 +488,13 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // 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 eq defn.NullClass) || (sym eq defn.NothingClass) - def isBridge: Boolean = sym.is(Flags.Bridge) - def isArtifact: Boolean = sym.is(Flags.Artifact) - def hasEnumFlag: Boolean = sym.isAllOf(Flags.JavaEnumTrait) + def hasAccessBoundary: Boolean = sym.accessBoundary(defn.RootClass) ne defn.RootClass - def isVarargsMethod: Boolean = sym.is(Flags.JavaVarargs) - // def isDeprecated: Boolean = false - def isMutable: Boolean = sym.is(Flags.Mutable) - def hasAbstractFlag: Boolean = sym.isOneOf(Flags.AbstractOrTrait) - 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 shouldEmitForwarders: Boolean = (sym.is(Flags.Module)) && sym.isStatic - def isEnum = sym.is(Flags.Enum) /** @@ -605,7 +588,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap toDenot(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 <- toDenot(sym).info.decls.toList if f.is(Flags.Method) && f.isTerm && !f.is(Flags.Module)) yield f def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = { @@ -633,7 +616,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * True for module classes of package level objects. The backend will generate a mirror class for * such objects. */ - def isTopLevelModuleClass: Boolean = sym.isModuleClass && + def isTopLevelModuleClass: Boolean = sym.is(Flags.ModuleClass) && ctx.atPhase(ctx.flattenPhase) { toDenot(sym).owner.is(Flags.PackageClass) } @@ -650,6 +633,18 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } + + /** + * This is basically a re-implementation of sym.isStaticOwner, but using the originalOwner chain. + * + * The problem is that we are interested in a source-level property. Various phases changed the + * symbol's properties in the meantime, mostly lambdalift modified (destructively) the owner. + * Therefore, `sym.isStatic` is not what we want. For example, in + * object T { def f { object U } } + * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. + */ + def isOriginallyStaticOwner: Boolean = + sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && symHelper(symHelper(originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner } @@ -794,7 +789,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap object ReturnBI extends DeconstructorCommon[Return] { def _1: Tree = field.expr - def _2: Symbol = if (field.from.symbol.isLabel) field.from.symbol else NoSymbol + def _2: Symbol = if (field.from.symbol.is(Flags.Label)) field.from.symbol else NoSymbol } object ArrayValueBI extends DeconstructorCommon[ArrayValue] { @@ -864,51 +859,26 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // tests def isClass: Boolean - // def isType: Boolean - // def isAnonymousClass: Boolean - // def isConstructor: Boolean def isExpanded: Boolean - // def isAnonymousFunction: Boolean - def isMethod: Boolean def isPublic: Boolean - def isSynthetic: Boolean - def isPackageClass: Boolean - def isModuleClass: Boolean - def isModule: Boolean def isStrictFP: Boolean - def isLabel: Boolean def hasPackageFlag: Boolean def isInterface: Boolean - // def isGetter: Boolean - // def isSetter: Boolean + def isGetClass: Boolean - def isJavaDefined: Boolean - def isDeferred: Boolean - def isPrivate: Boolean def getsJavaPrivateFlag: Boolean - def isFinal: Boolean def getsJavaFinalFlag: Boolean def isScalaStatic: Boolean def isStaticMember: Boolean def isBottomClass: Boolean - def isBridge: Boolean - def isArtifact: Boolean - def hasEnumFlag: Boolean + def hasAccessBoundary: Boolean - def isVarargsMethod: Boolean - // def isDeprecated: Boolean - def isMutable: Boolean - def hasAbstractFlag: Boolean - def hasModuleFlag: Boolean - def isSynchronized: Boolean def isNonBottomSubClass(sym: Symbol): Boolean def hasAnnotation(sym: Symbol): Boolean def shouldEmitForwarders: Boolean def isJavaDefaultMethod: Boolean - // def isClassConstructor: Boolean - // def isAnnotation: Boolean - // def isSerializable: Boolean - def isEnum: Boolean + + // def isEnum: Boolean /** * True for module classes of modules that are top-level or owned only by objects. Module classes @@ -971,8 +941,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * object T { def f { object U } } * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. */ - def isOriginallyStaticOwner: Boolean = - isPackageClass || isModuleClass && symHelper(symHelper(originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner + def isOriginallyStaticOwner: Boolean def samMethod(): Symbol } From 919d768fe7dfd33396b4274b1e4f8637146148c6 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 16:55:24 +0200 Subject: [PATCH 36/98] Remove methods from symbolHelper --- .../tools/backend/jvm/BCodeAsmCommon.scala | 12 +++++------ .../tools/backend/jvm/BCodeBodyBuilder.scala | 10 ++++----- .../tools/backend/jvm/BCodeHelpers.scala | 5 +++-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 10 ++++----- .../tools/backend/jvm/BTypesFromSymbols.scala | 8 +++---- .../backend/jvm/DottyBackendInterface.scala | 21 ++++--------------- 6 files changed, 27 insertions(+), 39 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index d1ec0d4a4a92..7e4a286310c5 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -24,7 +24,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { // always top-level. However, SI-8900 shows an example where the weak name-based implementation // of isDelambdafyFunction failed (for a function declared in a package named "lambda"). classSym.isAnonymousClass || { - val originalOwnerLexicallyEnclosingClass = symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass + val originalOwnerLexicallyEnclosingClass = symHelper(classSym.originalOwner).originalLexicallyEnclosingClass originalOwnerLexicallyEnclosingClass != NoSymbol && !symHelper(originalOwnerLexicallyEnclosingClass).isClass } } @@ -57,9 +57,9 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { def enclosingMethod(sym: Symbol): Option[Symbol] = { if (symHelper(sym).isClass || sym == NoSymbol) None else if (sym.is(Flags.Method)) Some(sym) - else enclosingMethod(symHelper(symHelper(sym).originalOwner).originalLexicallyEnclosingClass) + else enclosingMethod(symHelper(sym.originalOwner).originalLexicallyEnclosingClass) } - enclosingMethod(symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass) + enclosingMethod(symHelper(classSym.originalOwner).originalLexicallyEnclosingClass) } /** @@ -70,9 +70,9 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { assert(symHelper(classSym).isClass, classSym) def enclosingClass(sym: Symbol): Symbol = { if (symHelper(sym).isClass) sym - else enclosingClass(symHelper(symHelper(sym).originalOwner).originalLexicallyEnclosingClass) + else enclosingClass(symHelper(sym.originalOwner).originalLexicallyEnclosingClass) } - enclosingClass(symHelper(symHelper(classSym).originalOwner).originalLexicallyEnclosingClass) + enclosingClass(symHelper(classSym.originalOwner).originalLexicallyEnclosingClass) } /*final*/ case class EnclosingMethodEntry(owner: String, name: String, methodDescriptor: String) @@ -91,7 +91,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { ctx.debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(_.enclosingClass)})") Some(EnclosingMethodEntry( classDesc(enclosingClassForEnclosingMethodAttribute(classSym)), - methodOpt.map(symHelper(_).javaSimpleName.toString).orNull, + methodOpt.map(_.name.mangledString.toString).orNull, methodOpt.map(methodDesc).orNull)) } else { None diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index bf36d3c7a58f..ff544a09dd3b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -449,7 +449,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val useSpecificReceiver = specificReceiver != null && !symHelper(field).isScalaStatic val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner) - val fieldJName = symHelper(field).javaSimpleName.toString + val fieldJName = field.name.mangledString.toString val fieldDescr = symInfoTK(field).descriptor val isStatic = symHelper(field).isStaticMember val opc = @@ -497,7 +497,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case EnumTag => val sym = const.symbolValue val ownerName = internalName(sym.owner) - val fieldName = symHelper(sym).javaSimpleName.toString + val fieldName = sym.name.mangledString.toString val underlying = sym.info match { case t: TypeProxy => t.underlying case t => t @@ -685,7 +685,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && jMethodName == INSTANCE_CONSTRUCTOR_NAME && - symHelper(fun.symbol).javaSimpleName.toString == INSTANCE_CONSTRUCTOR_NAME && + fun.symbol.name.mangledString.toString == INSTANCE_CONSTRUCTOR_NAME && symHelper(claszSymbol).isStaticModuleClass) { isModuleInitialized = true mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) @@ -779,7 +779,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // Emitting `def f(c: C) = c.clone()` as `Object.clone()` gives a VerifyError. val target: String = tpeTK(qual).asRefBType.classOrArrayType val methodBType = asmMethodType(sym) - bc.invokevirtual(target, symHelper(sym).javaSimpleName.toString, methodBType.descriptor) + bc.invokevirtual(target, sym.name.mangledString.toString, methodBType.descriptor) generatedType = methodBType.returnType } else { val receiverClass = if (!invokeStyle.isVirtual) null else { @@ -1135,7 +1135,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { receiverClass.info // ensure types the type is up to date; erasure may add lateINTERFACE to traits val receiverName = internalName(receiverClass) - val jname = symHelper(method).javaSimpleName.toString + val jname = method.name.mangledString.toString val bmType = asmMethodType(method) val mdescr = bmType.descriptor diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index a61c0432ad54..3d10b8f4a462 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -11,6 +11,7 @@ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.NameKinds.ExpandedName /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -335,7 +336,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val jReturnType = toTypeKind(methodInfo.resultType) val mdesc = MethodBType(paramJavaTypes, jReturnType).descriptor - val mirrorMethodName = symHelper(m).javaSimpleName.toString + val mirrorMethodName = m.name.mangledString.toString val mirrorMethod: asm.MethodVisitor = jclass.visitMethod( flags, mirrorMethodName, @@ -392,7 +393,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val m = if (m0.is(Flags.Bridge)) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) ctx.log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") - else if (m.isType || m.is(Flags.Deferred) || (m.owner eq defn.ObjectClass) || m.isConstructor || symHelper(m).isExpanded) + else if (m.isType || m.is(Flags.Deferred) || (m.owner eq defn.ObjectClass) || m.isConstructor || m.name.is(ExpandedName)) ctx.debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(m.name)) ctx.log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index fd069beff532..00d801a991bf 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -254,7 +254,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val jfield = new asm.tree.FieldNode( flags, - symHelper(f).javaSimpleName.toString, + f.name.mangledString.toString, symInfoTK(f).descriptor, javagensig, null // no initial value @@ -395,7 +395,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { private def makeLocal(sym: Symbol, tk: BType): Local = { assert(nxtIdx != -1, "not a valid start index") - val loc = Local(tk, symHelper(sym).javaSimpleName.toString, nxtIdx, sym.is(Flags.Synthetic)) + val loc = Local(tk, sym.name.mangledString.toString, nxtIdx, sym.is(Flags.Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) error(sym.span, "attempt to create duplicate local var.") @@ -532,7 +532,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { assert(mnode == null, "GenBCode detected nested method.") methSymbol = dd.symbol - jMethodName = symHelper(methSymbol).javaSimpleName.toString + jMethodName = methSymbol.name.mangledString.toString returnType = asmMethodType(dd.symbol).returnType isMethSymStaticCtor = symHelper(methSymbol).isStaticConstructor @@ -644,7 +644,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { insnModA = new asm.tree.TypeInsnNode(asm.Opcodes.NEW, className) // INVOKESPECIAL val callee = methSymbol.enclosingClass.primaryConstructor - val jname = symHelper(callee).javaSimpleName.toString + val jname = callee.name.mangledString.toString val jowner = internalName(callee.owner) val jtype = asmMethodType(callee).descriptor insnModB = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESPECIAL, jowner, jname, jtype, false) @@ -666,7 +666,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // INVOKESTATIC CREATOR(): android.os.Parcelable$Creator; -- TODO where does this Android method come from? val callee = claszSymbol.companionModule.info.member(androidFieldName).symbol val jowner = internalName(callee.owner) - val jname = symHelper(callee).javaSimpleName.toString + val jname = callee.name.mangledString.toString val jtype = asmMethodType(callee).descriptor insnParcA = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESTATIC, jowner, jname, jtype, false) // PUTSTATIC `thisName`.CREATOR; diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index ad505fee02c1..a61b8491b9ba 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -147,11 +147,11 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { assert(symHelper(innerClassSym).isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") - val isNested = !symHelper(innerClassSym).rawowner.is(Flags.PackageClass) + val isNested = !innerClassSym.originalOwner.originalLexicallyEnclosingClass.is(Flags.PackageClass) if (!isNested) None else { // See comment in BTypes, when is a class marked static in the InnerClass table. - val isStaticNestedClass = symHelper(symHelper(symHelper(innerClassSym).originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner + val isStaticNestedClass = symHelper(symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner // After lambdalift (which is where we are), the rawowoner field contains the enclosing class. val enclosingClassSym = symHelper(innerClassSym).enclosingClassSym @@ -161,10 +161,10 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (isAnonymousOrLocalClass(innerClassSym)) { None } else { - val outerName = symHelper(symHelper(innerClassSym).rawowner).javaBinaryName + val outerName = symHelper(innerClassSym.originalOwner.originalLexicallyEnclosingClass).javaBinaryName // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. val outerNameModule = - if (symHelper(symHelper(innerClassSym).rawowner).isTopLevelModuleClass) dropModule(outerName) + if (symHelper(innerClassSym.originalOwner.originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) else outerName Some(outerNameModule.toString) } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 53992e90ce07..3d14c76c03c0 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -446,7 +446,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper { // names - def javaSimpleName: String = toDenot(sym).name.mangledString // addModuleSuffix(simpleName.dropLocal) + // def javaSimpleName: String = toDenot(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 rawname: String = { @@ -458,7 +458,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def isClass: Boolean = { sym.isPackageObject || (sym.isClass) } - def isExpanded: Boolean = sym.name.is(ExpandedName) def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) def isStrictFP: Boolean = false // todo: implement def hasPackageFlag: Boolean = sym.is(Flags.Package) @@ -516,10 +515,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // navigation - def rawowner: Symbol = { - originalOwner.originalLexicallyEnclosingClass - } - def originalOwner: Symbol = toDenot(sym).originalOwner def parentSymbols: List[Symbol] = toDenot(sym).info.parents.map(_.typeSymbol) def superClass: Symbol = { val t = toDenot(sym).asClass.superClass @@ -644,7 +639,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. */ def isOriginallyStaticOwner: Boolean = - sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && symHelper(symHelper(originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner + sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && symHelper(symHelper(sym.originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner } @@ -844,7 +839,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap abstract class SymbolHelper { // names - def javaSimpleName: String + // def javaSimpleName: String def javaBinaryName: String def javaClassName: String def rawname: String @@ -859,7 +854,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // tests def isClass: Boolean - def isExpanded: Boolean def isPublic: Boolean def isStrictFP: Boolean def hasPackageFlag: Boolean @@ -890,20 +884,13 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // navigation - def rawowner: Symbol // todo ??? - def originalOwner: Symbol def parentSymbols: List[Symbol] def superClass: Symbol - // def enclClass: Symbol def linkedClassOfClass: Symbol - // def linkedClass: Symbol - // def companionClass: Symbol - // def companionModule: Symbol def companionSymbol: Symbol - // def moduleClass: Symbol + def enclosingClassSym: Symbol def originalLexicallyEnclosingClass: Symbol - // def nextOverriddenSymbol: Symbol def allOverriddenSymbols: List[Symbol] From c096588410ffc346dd9a69efbd9fcab93551589f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 17:04:25 +0200 Subject: [PATCH 37/98] Remove methods fro symbolHelper --- .../tools/backend/jvm/BTypesFromSymbols.scala | 9 ++++++--- .../tools/backend/jvm/DottyBackendInterface.scala | 14 ++------------ 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index a61b8491b9ba..fced04568f6d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -55,7 +55,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { s"Cannot create ClassBType for special class symbol ${classSym.showFullName}") convertedClasses.getOrElse(classSym, { - val internalName = symHelper(classSym).javaBinaryName + val internalName = classSym.fullName.mangledString.replace('.', '/') // We first create and add the ClassBType to the hash map before computing its info. This // allows initializing cylic dependencies, see the comment on variable ClassBType._info. val classBType = new ClassBType(internalName) @@ -161,7 +161,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (isAnonymousOrLocalClass(innerClassSym)) { None } else { - val outerName = symHelper(innerClassSym.originalOwner.originalLexicallyEnclosingClass).javaBinaryName + val outerName = innerClassSym.originalOwner.originalLexicallyEnclosingClass.fullName.mangledString.replace('.', '/') // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. val outerNameModule = if (symHelper(innerClassSym.originalOwner.originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) @@ -172,7 +172,10 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val innerName: Option[String] = { if (innerClassSym.isAnonymousClass || innerClassSym.isAnonymousFunction) None - else Some(symHelper(innerClassSym).rawname) // moduleSuffix for module classes + else { + val original = innerClassSym.initial + Some(innerClassSym.name(ctx.withPhase(original.validFor.phaseId)).mangledString) // moduleSuffix for module classes + } } Some(NestedInfo(enclosingClass, outerName, innerName, isStaticNestedClass)) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 3d14c76c03c0..cb4bcaaba57d 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -445,14 +445,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper { - // names - // def javaSimpleName: String = toDenot(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 rawname: String = { - val original = toDenot(sym).initial - sym.name(ctx.withPhase(original.validFor.phaseId)).mangledString - } + // tests def isClass: Boolean = { @@ -839,10 +832,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap abstract class SymbolHelper { // names - // def javaSimpleName: String - def javaBinaryName: String - def javaClassName: String - def rawname: String + // def rawname: String /** Does this symbol actually correspond to an interface that will be emitted? * In the backend, this should be preferred over `isInterface` because it From e4d58ff09bc0cce8721f2b6fdf4dd318e1393cc1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 17:13:58 +0200 Subject: [PATCH 38/98] Inline some methods --- .../dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../tools/backend/jvm/BTypesFromSymbols.scala | 4 ++-- .../backend/jvm/DottyBackendInterface.scala | 17 ----------------- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 3d10b8f4a462..e7c28ff7b823 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -529,7 +529,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ def isAndroidParcelableClass(sym: Symbol) = (AndroidParcelableInterface != NoSymbol) && - (symHelper(sym).parentSymbols contains AndroidParcelableInterface) + (sym.info.parents.map(_.typeSymbol) contains AndroidParcelableInterface) /* * must-single-thread diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 00d801a991bf..76badbc5c2b2 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -528,7 +528,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val rhs = dd.rhs val vparamss = dd.vparamss // the only method whose implementation is not emitted: getClass() - if (symHelper(dd.symbol).isGetClass) { return } + if (dd.symbol eq defn.Any_getClass) { return } assert(mnode == null, "GenBCode detected nested method.") methSymbol = dd.symbol diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index fced04568f6d..dd335b9aaa6f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -203,9 +203,9 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { final def javaFlags(sym: Symbol): Int = { - val privateFlag = symHelper(sym).getsJavaPrivateFlag + val privateFlag = sym.is(Flags.Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) - val finalFlag = symHelper(sym).getsJavaFinalFlag + val finalFlag = sym.is(Flags.Final) && !toDenot(sym).isClassConstructor && !(sym.is(Flags.Mutable)) && !(sym.enclosingClass.is(Flags.Trait)) import asm.Opcodes._ GenBCodeOps.mkFlags( diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index cb4bcaaba57d..b9d78dfa5009 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -455,12 +455,8 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def isStrictFP: Boolean = false // todo: implement def hasPackageFlag: Boolean = sym.is(Flags.Package) def isInterface: Boolean = (sym.is(Flags.PureInterface)) || (sym.is(Flags.Trait)) - def isGetClass: Boolean = sym eq defn.Any_getClass def isJavaDefaultMethod: Boolean = !((sym.is(Flags.Deferred)) || toDenot(sym).isClassConstructor) - def getsJavaFinalFlag: Boolean = - sym.is(Flags.Final) && !toDenot(sym).isClassConstructor && !(sym.is(Flags.Mutable)) && !(sym.enclosingClass.is(Flags.Trait)) - /** Does this symbol actually correspond to an interface that will be emitted? * In the backend, this should be preferred over `isInterface` because it * also returns true for the symbols of the fake companion objects we @@ -470,9 +466,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def isEmittedInterface: Boolean = isInterface || sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && symHelper(sym.companionClass).isInterface) - def getsJavaPrivateFlag: Boolean = - sym.is(Flags.Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) - def isScalaStatic: Boolean = toDenot(sym).hasAnnotation(ctx.definitions.ScalaStaticAnnot) def isStaticMember: Boolean = (sym ne NoSymbol) && @@ -508,7 +501,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // navigation - def parentSymbols: List[Symbol] = toDenot(sym).info.parents.map(_.typeSymbol) def superClass: Symbol = { val t = toDenot(sym).asClass.superClass if (t.exists) t @@ -583,8 +575,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos) } - def throwsAnnotations: List[Symbol] = Nil - /** * All interfaces implemented by a class, except for those inherited through the superclass. * Redundant interfaces are removed unless there is a super call to them. @@ -849,9 +839,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def hasPackageFlag: Boolean def isInterface: Boolean - def isGetClass: Boolean - def getsJavaPrivateFlag: Boolean - def getsJavaFinalFlag: Boolean def isScalaStatic: Boolean def isStaticMember: Boolean def isBottomClass: Boolean @@ -874,7 +861,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // navigation - def parentSymbols: List[Symbol] def superClass: Symbol def linkedClassOfClass: Symbol def companionSymbol: Symbol @@ -885,7 +871,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // members - // def primaryConstructor: Symbol def nestedClasses: List[Symbol] def memberClasses: List[Symbol] def companionModuleMembers: List[Symbol] @@ -895,8 +880,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol - def throwsAnnotations: List[Symbol] - /** * All interfaces implemented by a class, except for those inherited through the superclass. * From d10d1d95f1ea8cfe96ab5ccb4124207186906577 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 17:17:03 +0200 Subject: [PATCH 39/98] Remove SymbolHelper abstraction --- .../backend/jvm/DottyBackendInterface.scala | 90 +------------------ 1 file changed, 2 insertions(+), 88 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index b9d78dfa5009..2eab03fa69c9 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -444,8 +444,9 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper { + implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper(sym) + class SymbolHelper(sym: Symbol) { // tests def isClass: Boolean = { @@ -819,93 +820,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - abstract class SymbolHelper { - - // names - // def rawname: String - - /** Does this symbol actually correspond to an interface that will be emitted? - * In the backend, this should be preferred over `isInterface` because it - * also returns true for the symbols of the fake companion objects we - * create for Java-defined classes as well as for Java annotations - * which we represent as classes. - */ - def isEmittedInterface: Boolean - - // tests - def isClass: Boolean - def isPublic: Boolean - def isStrictFP: Boolean - def hasPackageFlag: Boolean - def isInterface: Boolean - - def isScalaStatic: Boolean - def isStaticMember: Boolean - def isBottomClass: Boolean - - def hasAccessBoundary: Boolean - def isNonBottomSubClass(sym: Symbol): Boolean - def hasAnnotation(sym: Symbol): Boolean - def shouldEmitForwarders: Boolean - def isJavaDefaultMethod: Boolean - - // def isEnum: Boolean - - /** - * True for module classes of modules that are top-level or owned only by objects. Module classes - * for such objects will get a MODULE$ flag and a corresponding static initializer. - */ - def isStaticModuleClass: Boolean - - def isStaticConstructor: Boolean - - - // navigation - def superClass: Symbol - def linkedClassOfClass: Symbol - def companionSymbol: Symbol - - def enclosingClassSym: Symbol - def originalLexicallyEnclosingClass: Symbol - def allOverriddenSymbols: List[Symbol] - - - // members - def nestedClasses: List[Symbol] - def memberClasses: List[Symbol] - def companionModuleMembers: List[Symbol] - def fieldSymbols: List[Symbol] - def methodSymbols: List[Symbol] - - - def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol - - /** - * All interfaces implemented by a class, except for those inherited through the superclass. - * - */ - def superInterfaces: List[Symbol] - - /** - * True for module classes of package level objects. The backend will generate a mirror class for - * such objects. - */ - def isTopLevelModuleClass: Boolean - - /** - * This is basically a re-implementation of sym.isStaticOwner, but using the originalOwner chain. - * - * The problem is that we are interested in a source-level property. Various phases changed the - * symbol's properties in the meantime, mostly lambdalift modified (destructively) the owner. - * Therefore, `sym.isStatic` is not what we want. For example, in - * object T { def f { object U } } - * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. - */ - def isOriginallyStaticOwner: Boolean - - def samMethod(): Symbol - } - abstract class Caches { def recordCache[T <: Clearable](cache: T): T def newWeakMap[K, V](): collection.mutable.WeakHashMap[K, V] From 2b78cb3a208d1497c7447580b2fe1102a4d163fb Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 17:30:11 +0200 Subject: [PATCH 40/98] Remove some methods --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 4 ++-- .../tools/backend/jvm/BCodeHelpers.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 7 ++++--- .../tools/backend/jvm/BTypesFromSymbols.scala | 4 ++-- .../backend/jvm/DottyBackendInterface.scala | 19 +++---------------- 5 files changed, 12 insertions(+), 24 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index ff544a09dd3b..e45feea7ee64 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1104,7 +1104,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (specificReceiver != null) assert(style.isVirtual || specificReceiver == methodOwner, s"specificReceiver can only be specified for virtual calls. $method - $specificReceiver") - val useSpecificReceiver = specificReceiver != null && !symHelper(specificReceiver).isBottomClass && !symHelper(method).isScalaStatic + val useSpecificReceiver = specificReceiver != null && (specificReceiver ne defn.NullClass) && (specificReceiver ne defn.NothingClass) && !symHelper(method).isScalaStatic val receiver = if (useSpecificReceiver) specificReceiver else methodOwner // workaround for a JVM bug: https://bugs.openjdk.java.net/browse/JDK-8154587 @@ -1125,7 +1125,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { style.isVirtual && symHelper(receiver).isEmittedInterface && defn.ObjectType.decl(method.name).symbol.exists && { // fast path - compute overrideChain on the next line only if necessary - val syms = symHelper(method).allOverriddenSymbols + val syms = method.allOverriddenSymbols.toList !syms.isEmpty && syms.last.owner == defn.ObjectClass } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index e7c28ff7b823..fee517f32646 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -397,7 +397,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ctx.debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(m.name)) ctx.log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") - else if (symHelper(m).hasAccessBoundary) + else if (m.accessBoundary(defn.RootClass) ne defn.RootClass) ctx.log(s"No forwarder for non-public member $m") else { ctx.log(s"Adding static forwarder for '$m' from $jclassName to '$moduleClass'") diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 76badbc5c2b2..ccdb9adc6a82 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -10,6 +10,7 @@ import scala.tools.asm.util.{TraceMethodVisitor, ASMifier} import java.io.PrintWriter import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Symbols._ @@ -181,7 +182,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // add static forwarders if there are no name conflicts; see bugs #363 and #1735 if (lmoc != NoSymbol) { // it must be a top level class (name contains no $s) - val isCandidateForForwarders = symHelper(lmoc).shouldEmitForwarders + val isCandidateForForwarders = (lmoc.is(Flags.Module)) && lmoc.isStatic if (isCandidateForForwarders) { ctx.log(s"Adding static forwarders from '$claszSymbol' to implementations in '$lmoc'") addForwarders(cnode, thisName, lmoc.moduleClass) @@ -379,7 +380,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ def makeLocal(tk: BType, name: String, tpe: Type, pos: Position): Symbol = { - val locSym = symHelper(methSymbol).freshLocal(cunit, name, tpe, pos, Flags.Synthetic.bits) // setInfo tpe + val locSym = ctx.newSymbol(methSymbol, name.toTermName, Flags.Synthetic, tpe, NoSymbol, pos) makeLocal(locSym, tk) locSym } @@ -551,7 +552,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { return } - val isNative = symHelper(methSymbol).hasAnnotation(NativeAttr) + val isNative = methSymbol.hasAnnotation(NativeAttr) val isAbstractMethod = (methSymbol.is(Flags.Deferred) || (symHelper(methSymbol.owner).isInterface && !symHelper(methSymbol).isJavaDefaultMethod)) val flags = GenBCodeOps.mkFlags( javaFlags(methSymbol), diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index dd335b9aaa6f..2af9a27c8a4a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -236,8 +236,8 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { def javaFieldFlags(sym: Symbol) = { javaFlags(sym) | GenBCodeOps.mkFlags( - if (symHelper(sym) hasAnnotation TransientAttr) asm.Opcodes.ACC_TRANSIENT else 0, - if (symHelper(sym) hasAnnotation VolatileAttr) asm.Opcodes.ACC_VOLATILE else 0, + if (sym hasAnnotation TransientAttr) asm.Opcodes.ACC_TRANSIENT else 0, + if (sym hasAnnotation VolatileAttr) asm.Opcodes.ACC_VOLATILE else 0, if (sym.is(Flags.Mutable)) 0 else asm.Opcodes.ACC_FINAL ) } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 2eab03fa69c9..2279c3d591d4 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -473,16 +473,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap (sym.is(Flags.JavaStatic) || isScalaStatic) // 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 eq defn.NullClass) || (sym eq defn.NothingClass) - - def hasAccessBoundary: Boolean = sym.accessBoundary(defn.RootClass) ne defn.RootClass - - def isNonBottomSubClass(other: Symbol): Boolean = sym.derivesFrom(other) - def hasAnnotation(ann: Symbol): Boolean = toDenot(sym).hasAnnotation(ann) - def shouldEmitForwarders: Boolean = - (sym.is(Flags.Module)) && sym.isStatic - - /** * True for module classes of modules that are top-level or owned only by objects. Module classes * for such objects will get a MODULE$ flag and a corresponding static initializer. @@ -535,11 +525,8 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap val shiftedContext = ctx.withPhase(validity.phaseId) toDenot(sym)(shiftedContext).lexicallyEnclosingClass(shiftedContext) } else NoSymbol - // def nextOverriddenSymbol: Symbol = toDenot(sym).nextOverriddenSymbol - def allOverriddenSymbols: List[Symbol] = toDenot(sym).allOverriddenSymbols.toList // members - // def primaryConstructor: Symbol = toDenot(sym).primaryConstructor /** For currently compiled classes: All locally defined classes including local classes. * The empty list for classes that are not currently compiled. @@ -572,9 +559,9 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap for (f <- toDenot(sym).info.decls.toList if f.is(Flags.Method) && f.isTerm && !f.is(Flags.Module)) yield f - def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = { - ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos) - } + // def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = { + // ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos) + // } /** * All interfaces implemented by a class, except for those inherited through the superclass. From 48dd85e9888c44fd4adc8c38276dbecb6b2ab182 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 17:30:31 +0200 Subject: [PATCH 41/98] Remove custom Template and Return extractor --- .../dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 7 ++++--- .../dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 8 ++++++-- .../tools/backend/jvm/DottyBackendInterface.scala | 13 ------------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index e45feea7ee64..8b2e0a6bc551 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -292,7 +292,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t @ Labeled(_, _) => generatedType = genLabeled(t) - case r @ ReturnBI(_) => + case r: Return => genReturn(r) generatedType = expectedType @@ -523,8 +523,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { resKind } - private def genReturn(r: Return): Unit = r match { - case ReturnBI(expr, fromSym) => + private def genReturn(r: Return): Unit = { + val expr: Tree = r.expr + val fromSym: Symbol = if (r.from.symbol.is(Flags.Label)) r.from.symbol else NoSymbol if (NoSymbol == fromSym) { // return from enclosing method diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index ccdb9adc6a82..a9e16ea72f1a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -489,7 +489,11 @@ trait BCodeSkelBuilder extends BCodeHelpers { case dd: DefDef => genDefDef(dd) - case TemplateBI(_, _, body) => body foreach gen + case tree: Template => + val body = + if (tree.constr.rhs.isEmpty) tree.body + else tree.constr :: tree.body + body foreach gen case _ => abort(s"Illegal tree in gen: $tree") } @@ -572,7 +576,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { genLoad(rhs, returnType) rhs match { - case ReturnBI(_) | Block(_, ReturnBI(_)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () + case (_: Return) | Block(_, (_: Return)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () case tpd.EmptyTree => error(NoSpan, "Concrete method has no definition: " + dd + ( if (ctx.settings.Ydebug.value) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 2279c3d591d4..ee2a8db6666c 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -753,11 +753,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - object ReturnBI extends DeconstructorCommon[Return] { - def _1: Tree = field.expr - def _2: Symbol = if (field.from.symbol.is(Flags.Label)) field.from.symbol else NoSymbol - } - object ArrayValueBI extends DeconstructorCommon[ArrayValue] { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem @@ -768,14 +763,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _2: List[Tree] = field.elems } - object TemplateBI extends DeconstructorCommon[Template] { - def _1: List[Tree] = field.parents - def _2: ValDef = field.self - def _3: List[Tree] = - if (field.constr.rhs.isEmpty) field.body - else field.constr :: field.body - } - object ClosureBI extends DeconstructorCommon[Closure] { def _1: List[Tree] = field.env def _2: Tree = field.meth From c16f6e33e24005ccacca15e57bf39c88337f0ac0 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 17:39:56 +0200 Subject: [PATCH 42/98] Remove custom Closure extractor --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 17 +++++++++++++++-- .../backend/jvm/DottyBackendInterface.scala | 18 ------------------ 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 8b2e0a6bc551..b49c87fab5f7 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -10,6 +10,7 @@ import BCodeHelpers.InvokeStyle import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Constants._ +import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.StdNames.{nme, str} @@ -17,7 +18,6 @@ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.transform.Erasure import dotty.tools.dotc.util.Spans.NoSpan - /* * * @author Miguel Garcia, http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/ @@ -309,7 +309,20 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { abort(s"Unexpected New(${tpt.tpe.showSummary()}/$tpt) reached GenBCode.\n" + " Call was genLoad" + ((tree, expectedType))) - case app @ ClosureBI(env, call, functionalInterface) => + case app: Closure => + val env: List[Tree] = app.env + val call: Tree = app.meth + val functionalInterface: Symbol = { + val t = app.tpt.tpe.typeSymbol + if (t.exists) t + else { + val arity = app.meth.tpe.widenDealias.firstParamTypes.size - env.size + val returnsUnit = app.meth.tpe.widenDealias.resultType.classSymbol == defn.UnitClass + if (returnsUnit) ctx.requiredClass(("dotty.runtime.function.JProcedure" + arity)) + else if (arity <= 2) ctx.requiredClass(("dotty.runtime.function.JFunction" + arity)) + else ctx.requiredClass(("scala.Function" + arity)) + } + } val (fun, args) = call match { case Apply(fun, args) => (fun, args) case t @ SelectBI(_, _) => (t, Nil) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index ee2a8db6666c..9990a7ba5b89 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -763,24 +763,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _2: List[Tree] = field.elems } - object ClosureBI extends DeconstructorCommon[Closure] { - def _1: List[Tree] = field.env - def _2: Tree = field.meth - def _3: Symbol = { - val t = field.tpt.tpe.typeSymbol - if (t.exists) t - else { - val arity = field.meth.tpe.widenDealias.firstParamTypes.size - _1.size - val returnsUnit = field.meth.tpe.widenDealias.resultType.classSymbol == defn.UnitClass - if (returnsUnit) ctx.requiredClass(("dotty.runtime.function.JProcedure" + arity)) - else if (arity <= 2) ctx.requiredClass(("dotty.runtime.function.JFunction" + arity)) - else ctx.requiredClass(("scala.Function" + arity)) - } - } - } - - // def currentUnit: CompilationUnit = ctx.compilationUnit - abstract class DeconstructorCommon[T >: Null <: AnyRef] { From a548357df77bddf746f31eaa73f8746ebbe4bbad Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:04:12 +0200 Subject: [PATCH 43/98] Inline methods --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- .../tools/backend/jvm/BCodeHelpers.scala | 6 +-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 6 +-- .../tools/backend/jvm/BTypesFromSymbols.scala | 21 +++++++- .../backend/jvm/DottyBackendInterface.scala | 48 ++----------------- .../dotty/tools/backend/jvm/GenBCode.scala | 2 +- 6 files changed, 32 insertions(+), 53 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index b49c87fab5f7..2960fa63f708 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -392,7 +392,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val desugared = desugarIdent(t) desugared match { case None => - if (!symHelper(sym).hasPackageFlag) { + if (!sym.is(Flags.Package)) { if (sym.is(Flags.Module)) genLoadModule(sym) else locals.load(sym) } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index fee517f32646..18b2114eeafc 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -198,7 +198,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // If the `sym` is a java module class, we use the java class instead. This ensures that we // register the class (instead of the module class) in innerClassBufferASM. // The two symbols have the same name, so the resulting internalName is the same. - val classSym = if (sym.is(Flags.JavaDefined) && sym.is(Flags.ModuleClass)) symHelper(sym).linkedClassOfClass else sym + val classSym = if (sym.is(Flags.JavaDefined) && sym.is(Flags.ModuleClass)) sym.linkedClass else sym getClassBTypeAndRegisterInnerClass(classSym).internalName } @@ -489,11 +489,11 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ) if (emitSource) { - mirrorClass.visitSource("" + sourceFileFor(cunit), + mirrorClass.visitSource("" + cunit.source.file.name, null /* SourceDebugExtension */) } - val ssa = getAnnotPickle(mirrorName, symHelper(moduleClass).companionSymbol) + val ssa = getAnnotPickle(mirrorName, if (moduleClass.is(Flags.Module)) moduleClass.companionClass else moduleClass.companionModule) mirrorClass.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) emitAnnotations(mirrorClass, moduleClass.annotations ++ ssa) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index a9e16ea72f1a..28bdd1dbef50 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -157,7 +157,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { superClass, interfaceNames.toArray) if (emitSource) { - cnode.visitSource(sourceFileFor(cunit), null /* SourceDebugExtension */) + cnode.visitSource(cunit.source.file.name, null /* SourceDebugExtension */) } enclosingMethodAttribute(claszSymbol, internalName, asmMethodType(_).descriptor) match { @@ -557,11 +557,11 @@ trait BCodeSkelBuilder extends BCodeHelpers { } val isNative = methSymbol.hasAnnotation(NativeAttr) - val isAbstractMethod = (methSymbol.is(Flags.Deferred) || (symHelper(methSymbol.owner).isInterface && !symHelper(methSymbol).isJavaDefaultMethod)) + val isAbstractMethod = (methSymbol.is(Flags.Deferred) || (symHelper(methSymbol.owner).isInterface && ((methSymbol.is(Flags.Deferred)) || methSymbol.isClassConstructor))) val flags = GenBCodeOps.mkFlags( javaFlags(methSymbol), if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0, - if (symHelper(methSymbol).isStrictFP) asm.Opcodes.ACC_STRICT else 0, + if (false /*methSymbol.isStrictFP*/) asm.Opcodes.ACC_STRICT else 0, if (isNative) asm.Opcodes.ACC_NATIVE else 0 // native methods of objects are generated in mirror classes ) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 2af9a27c8a4a..6ff75fb40d3c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -65,7 +65,17 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { } private def setClassInfo(classSym: Symbol, classBType: ClassBType): ClassBType = { - val superClassSym = symHelper(classSym).superClass + val superClassSym: Symbol = { + val t = classSym.asClass.superClass + if (t.exists) t + else if (classSym.is(Flags.ModuleClass)) { + // workaround #371 + + println(s"Warning: mocking up superclass for $classSym") + defn.ObjectClass + } + else t + } assert( if (classSym == defn.ObjectClass) superClassSym == NoSymbol @@ -154,7 +164,14 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val isStaticNestedClass = symHelper(symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner // After lambdalift (which is where we are), the rawowoner field contains the enclosing class. - val enclosingClassSym = symHelper(innerClassSym).enclosingClassSym + val enclosingClassSym = { + if (symHelper(innerClassSym).isClass) { + val ct = ctx.withPhase(ctx.flattenPhase.prev) + toDenot(innerClassSym)(ct).owner.enclosingClass(ct) + } + else innerClassSym.enclosingClass(ctx.withPhase(ctx.flattenPhase.prev)) + } //todo is handled specially for JavaDefined symbols in scalac + val enclosingClass: ClassBType = classBTypeFromSymbol(enclosingClassSym) val outerName: Option[String] = { diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 9990a7ba5b89..b47ad9d6ce0a 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -426,10 +426,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } - - def sourceFileFor(cu: CompilationUnit): String = cu.source.file.name - - def assocsFromApply(tree: Tree): List[(Name, Tree)] = { tree match { case Block(_, expr) => assocsFromApply(expr) @@ -449,14 +445,9 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap class SymbolHelper(sym: Symbol) { // tests - def isClass: Boolean = { - sym.isPackageObject || (sym.isClass) - } + def isClass: Boolean = sym.isPackageObject || sym.isClass def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) - def isStrictFP: Boolean = false // todo: implement - def hasPackageFlag: Boolean = sym.is(Flags.Package) def isInterface: Boolean = (sym.is(Flags.PureInterface)) || (sym.is(Flags.Trait)) - def isJavaDefaultMethod: Boolean = !((sym.is(Flags.Deferred)) || toDenot(sym).isClassConstructor) /** Does this symbol actually correspond to an interface that will be emitted? * In the backend, this should be preferred over `isInterface` because it @@ -492,31 +483,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // navigation - def superClass: Symbol = { - val t = toDenot(sym).asClass.superClass - if (t.exists) t - else if (sym.is(Flags.ModuleClass)) { - // workaround #371 - - println(s"Warning: mocking up superclass for $sym") - defn.ObjectClass - } - else t - } - // def enclClass: Symbol = toDenot(sym).enclosingClass - def linkedClassOfClass: Symbol = sym.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 companionSymbol: Symbol = if (sym.is(Flags.Module)) sym.companionClass else sym.companionModule - // def moduleClass: Symbol = toDenot(sym).moduleClass - def enclosingClassSym: Symbol = { - if (this.isClass) { - val ct = ctx.withPhase(ctx.flattenPhase.prev) - toDenot(sym)(ct).owner.enclosingClass(ct) - } - else sym.enclosingClass(ctx.withPhase(ctx.flattenPhase.prev)) - } //todo is handled specially for JavaDefined symbols in scalac + def originalLexicallyEnclosingClass: Symbol = // used to populate the EnclosingMethod attribute. // it is very tricky in presence of classes(and annonymous classes) defined inside supper calls. @@ -558,11 +525,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def methodSymbols: List[Symbol] = for (f <- toDenot(sym).info.decls.toList if f.is(Flags.Method) && f.isTerm && !f.is(Flags.Module)) yield f - - // def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = { - // ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos) - // } - /** * All interfaces implemented by a class, except for those inherited through the superclass. * Redundant interfaces are removed unless there is a super call to them. @@ -796,7 +758,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap val ScalaSignatureATTRName: String = "ScalaSig" // Module symbols used in backend - val StringModule: Symbol = symHelper(requiredClass[java.lang.String]).linkedClassOfClass + val StringModule: Symbol = requiredClass[java.lang.String].linkedClass val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type] @@ -817,11 +779,11 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * Used only in assertions. */ def isCompilingPrimitive = { - primitiveCompilationUnits(sourceFileFor(ctx.compilationUnit)) + primitiveCompilationUnits(ctx.compilationUnit.source.file.name) } def isCompilingArray = { - sourceFileFor(ctx.compilationUnit) == "Array.scala" + ctx.compilationUnit.source.file.name == "Array.scala" } } diff --git a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala index 5e088891bcf1..5b2eb865e693 100644 --- a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala @@ -184,7 +184,7 @@ class GenBCodePipeline(val int: DottyBackendInterface)(implicit ctx: Context) ex try { /*withCurrentUnit(item.cunit)*/(visit(item)) } catch { case ex: Throwable => - println(s"Error while emitting ${int.sourceFileFor(item.cunit)}") + println(s"Error while emitting ${item.cunit.source.file.name}") throw ex } } From 2e1db2edb07474fb4b75bc4206a547695d30f8e8 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:13:15 +0200 Subject: [PATCH 44/98] Inline methods --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 4 ++-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 5 +++-- .../tools/backend/jvm/BTypesFromSymbols.scala | 7 ++++++- .../backend/jvm/DottyBackendInterface.scala | 17 +---------------- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 2960fa63f708..e42829942360 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -459,7 +459,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * must-single-thread */ private def fieldOp(field: Symbol, isLoad: Boolean, specificReceiver: Symbol): Unit = { - val useSpecificReceiver = specificReceiver != null && !symHelper(field).isScalaStatic + val useSpecificReceiver = specificReceiver != null && !field.hasAnnotation(ctx.definitions.ScalaStaticAnnot) val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner) val fieldJName = field.name.mangledString.toString @@ -1118,7 +1118,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (specificReceiver != null) assert(style.isVirtual || specificReceiver == methodOwner, s"specificReceiver can only be specified for virtual calls. $method - $specificReceiver") - val useSpecificReceiver = specificReceiver != null && (specificReceiver ne defn.NullClass) && (specificReceiver ne defn.NothingClass) && !symHelper(method).isScalaStatic + val useSpecificReceiver = specificReceiver != null && (specificReceiver ne defn.NullClass) && (specificReceiver ne defn.NothingClass) && !method.hasAnnotation(ctx.definitions.ScalaStaticAnnot) val receiver = if (useSpecificReceiver) specificReceiver else methodOwner // workaround for a JVM bug: https://bugs.openjdk.java.net/browse/JDK-8154587 diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 28bdd1dbef50..dde6d0a710a9 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -99,7 +99,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { initJClass(cnode) - val hasStaticCtor = symHelper(cd.symbol).methodSymbols exists (symHelper(_).isStaticConstructor) + val methodSymbols = for (f <- cd.symbol.info.decls.toList if f.is(Flags.Method) && f.isTerm && !f.is(Flags.Module)) yield f + val hasStaticCtor = methodSymbols exists (symHelper(_).isStaticConstructor) if (!hasStaticCtor) { // but needs one ... if (isCZStaticModule || isCZParcelable) { @@ -246,7 +247,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { * backend emits them as static). * No code is needed for this module symbol. */ - for (f <- symHelper(claszSymbol).fieldSymbols) { + for (f <- claszSymbol.info.decls.filter(p => p.isTerm && !p.is(Flags.Method))) { val javagensig = getGenericSignature(f, claszSymbol) val flags = javaFieldFlags(f) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 6ff75fb40d3c..81cc9f83e871 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -123,7 +123,12 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // For consistency, the InnerClass entry for D needs to be present in C - to Java it looks // like D is a member of C, not C$. val linkedClass = classSym.linkedClass - val companionModuleMembers = symHelper(classSym).companionModuleMembers + val companionModuleMembers = { + // phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes, + // not local classes of the companion module (E in the example) that were lifted by lambdalift. + if (classSym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ classSym.linkedClass.memberClasses + else Nil + } nestedClasses ++ companionModuleMembers } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index b47ad9d6ce0a..d4e58e715ddf 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -458,10 +458,8 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def isEmittedInterface: Boolean = isInterface || sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && symHelper(sym.companionClass).isInterface) - def isScalaStatic: Boolean = - toDenot(sym).hasAnnotation(ctx.definitions.ScalaStaticAnnot) def isStaticMember: Boolean = (sym ne NoSymbol) && - (sym.is(Flags.JavaStatic) || isScalaStatic) + (sym.is(Flags.JavaStatic) || 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 /** @@ -513,18 +511,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } else Nil - 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 example) that were lifted by lambdalift. - if (sym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ sym.linkedClass.memberClasses - else Nil - } - def fieldSymbols: List[Symbol] = { - toDenot(sym).info.decls.filter(p => p.isTerm && !p.is(Flags.Method)) - } - def methodSymbols: List[Symbol] = - for (f <- toDenot(sym).info.decls.toList if f.is(Flags.Method) && f.isTerm && !f.is(Flags.Module)) yield f - /** * All interfaces implemented by a class, except for those inherited through the superclass. * Redundant interfaces are removed unless there is a super call to them. @@ -549,7 +535,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap toDenot(sym).owner.is(Flags.PackageClass) } - def addRemoteRemoteExceptionAnnotation: Unit = () def samMethod(): Symbol = ctx.atPhase(ctx.erasurePhase) { val samMethods = toDenot(sym).info.possibleSamMethods.toList From 33f4c125caafb2f2f6e31831c97450575f37b7c0 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:16:41 +0200 Subject: [PATCH 45/98] Remove implicit conversion --- .../dotty/tools/backend/jvm/BTypesFromSymbols.scala | 12 ++++++------ .../tools/backend/jvm/DottyBackendInterface.scala | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 81cc9f83e871..e35af8922b74 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -126,7 +126,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val companionModuleMembers = { // phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes, // not local classes of the companion module (E in the example) that were lifted by lambdalift. - if (classSym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ classSym.linkedClass.memberClasses + if (symHelper(classSym.linkedClass).isTopLevelModuleClass) /*exitingPickler*/ symHelper(classSym.linkedClass).memberClasses else Nil } @@ -162,7 +162,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { assert(symHelper(innerClassSym).isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") - val isNested = !innerClassSym.originalOwner.originalLexicallyEnclosingClass.is(Flags.PackageClass) + val isNested = !symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.is(Flags.PackageClass) if (!isNested) None else { // See comment in BTypes, when is a class marked static in the InnerClass table. @@ -183,10 +183,10 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (isAnonymousOrLocalClass(innerClassSym)) { None } else { - val outerName = innerClassSym.originalOwner.originalLexicallyEnclosingClass.fullName.mangledString.replace('.', '/') + val outerName = symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.fullName.mangledString.replace('.', '/') // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. val outerNameModule = - if (symHelper(innerClassSym.originalOwner.originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) + if (symHelper(symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) else outerName Some(outerNameModule.toString) } @@ -225,7 +225,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { final def javaFlags(sym: Symbol): Int = { - val privateFlag = sym.is(Flags.Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) + val privateFlag = sym.is(Flags.Private) || (sym.isPrimaryConstructor && symHelper(sym.owner).isTopLevelModuleClass) val finalFlag = sym.is(Flags.Final) && !toDenot(sym).isClassConstructor && !(sym.is(Flags.Mutable)) && !(sym.enclosingClass.is(Flags.Trait)) @@ -244,7 +244,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks !sym.is(Flags.Bridge)) ACC_FINAL else 0, - if (sym.isStaticMember) ACC_STATIC else 0, + if (symHelper(sym).isStaticMember) ACC_STATIC else 0, if (sym.is(Flags.Bridge)) ACC_BRIDGE | ACC_SYNTHETIC else 0, if (sym.is(Flags.Artifact)) ACC_SYNTHETIC else 0, if (symHelper(sym).isClass && !symHelper(sym).isInterface) ACC_SUPER else 0, diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index d4e58e715ddf..6573f3e0cdf4 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -440,7 +440,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - implicit def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper(sym) + def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper(sym) class SymbolHelper(sym: Symbol) { From 2c83a61c9319de355eee33eab6c16d045af2d510 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:25:26 +0200 Subject: [PATCH 46/98] Remove error/warining aliases --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 9 +++++---- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 4 +--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index e42829942360..e6b62617061f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -661,7 +661,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var elemKind = arr.elementType val argsSize = args.length if (argsSize > dims) { - error(app.span, s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)") + ctx.error(s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)", sourcePos(app.span)) } if (argsSize < dims) { /* In one step: diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 18b2114eeafc..06c62accfcc2 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -48,7 +48,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { outputDirectory } catch { case ex: Throwable => - int.error(csym.span, s"Couldn't create file for class $cName\n${ex.getMessage}") + ctx.error(s"Couldn't create file for class $cName\n${ex.getMessage}", sourcePos(csym.span)) null } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index dde6d0a710a9..94d06a0ca46a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -400,7 +400,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val loc = Local(tk, sym.name.mangledString.toString, nxtIdx, sym.is(Flags.Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) - error(sym.span, "attempt to create duplicate local var.") + ctx.error("attempt to create duplicate local var.", sourcePos(sym.span)) assert(tk.size > 0, "makeLocal called for a symbol whose type is Unit.") nxtIdx += tk.size loc @@ -553,7 +553,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { if (params.size > MaximumJvmParameters) { // SI-7324 - error(methSymbol.span, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.") + ctx.error(s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", sourcePos(methSymbol.span)) return } @@ -579,9 +579,10 @@ trait BCodeSkelBuilder extends BCodeHelpers { rhs match { case (_: Return) | Block(_, (_: Return)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () case tpd.EmptyTree => - error(NoSpan, "Concrete method has no definition: " + dd + ( + ctx.error("Concrete method has no definition: " + dd + ( if (ctx.settings.Ydebug.value) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" - else "") + else ""), + sourcePos(NoSpan) ) case _ => bc emitRETURN returnType diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 6573f3e0cdf4..0ea986a6eacc 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -278,8 +278,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap ctx.requiredModule(className) } - def error(pos: Position, msg: String): Unit = ctx.error(msg, sourcePos(pos)) - def warning(pos: Position, msg: String): Unit = ctx.warning(msg, sourcePos(pos)) def abort(msg: String): Nothing = { ctx.error(msg) throw new RuntimeException(msg) @@ -704,7 +702,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => - error(field.span, s"JavaSeqArray with type ${field.tpe} reached backend: $field") + ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", sourcePos(field.span)) UnspecifiedErrorType } def _2: List[Tree] = field.elems From ea3d2820a695cbb123025a398127764110e57bd7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:35:42 +0200 Subject: [PATCH 47/98] Remove CompilationUnit type alias --- compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 1 + compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 1 + compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 1 + compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala | 1 + compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 1 - 5 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index e6b62617061f..ac97da3c8c64 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -9,6 +9,7 @@ import scala.tools.asm.{Handle, Label, Opcodes} import BCodeHelpers.InvokeStyle import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.core.Constants._ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 06c62accfcc2..748563348e93 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -7,6 +7,7 @@ import scala.tools.asm.ClassWriter import scala.collection.mutable import dotty.tools.io.AbstractFile +import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Decorators._ diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 94d06a0ca46a..4e9a1e27ced4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -10,6 +10,7 @@ import scala.tools.asm.util.{TraceMethodVisitor, ASMifier} import java.io.PrintWriter import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames.str diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index a35bc15826b4..cb927b7a772b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -5,6 +5,7 @@ package jvm import scala.collection.immutable import scala.tools.asm +import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.core.StdNames.nme import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.ast.tpd diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 0ea986a6eacc..844666486ddf 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -43,7 +43,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap type Symbol = Symbols.Symbol type Type = Types.Type type Tree = tpd.Tree - type CompilationUnit = dotc.CompilationUnit type Constant = Constants.Constant type Literal = tpd.Literal type Position = Spans.Span From 5487985634672619e85accac0d1fc115f4f307e1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:44:10 +0200 Subject: [PATCH 48/98] Remove type aliases --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 4 ++-- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 ++ .../src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 5 +++-- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 8 +++----- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index ac97da3c8c64..e48805306f13 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -17,7 +17,7 @@ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.StdNames.{nme, str} import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.transform.Erasure -import dotty.tools.dotc.util.Spans.NoSpan +import dotty.tools.dotc.util.Spans._ /* * @@ -1111,7 +1111,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * invocation instruction, otherwise `method.owner`. A specific receiver class is needed to * prevent an IllegalAccessError, (aladdin bug 455). */ - def genCallMethod(method: Symbol, style: InvokeStyle, pos: Position = NoSpan, specificReceiver: Symbol = null): BType = { + def genCallMethod(method: Symbol, style: InvokeStyle, pos: Span = NoSpan, specificReceiver: Symbol = null): BType = { val methodOwner = method.owner // the class used in the invocation's method descriptor in the classfile diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 748563348e93..9881f5d016a8 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -8,10 +8,12 @@ import scala.collection.mutable import dotty.tools.io.AbstractFile import dotty.tools.dotc.CompilationUnit +import dotty.tools.dotc.core.Annotations.Annotation import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Names.Name import dotty.tools.dotc.core.NameKinds.ExpandedName /* diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 4e9a1e27ced4..b1b176945a88 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -11,11 +11,12 @@ import java.io.PrintWriter import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.CompilationUnit +import dotty.tools.dotc.core.Annotations.Annotation import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.util.Spans.NoSpan +import dotty.tools.dotc.util.Spans._ /* * @@ -380,7 +381,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* Make a fresh local variable, ensuring a unique name. * The invoker must make sure inner classes are tracked for the sym's tpe. */ - def makeLocal(tk: BType, name: String, tpe: Type, pos: Position): Symbol = { + def makeLocal(tk: BType, name: String, tpe: Type, pos: Span): Symbol = { val locSym = ctx.newSymbol(methSymbol, name.toTermName, Flags.Synthetic, tpe, NoSymbol, pos) makeLocal(locSym, tk) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 844666486ddf..185528105631 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -31,6 +31,8 @@ import scala.tools.asm import StdNames.{nme, str} import NameKinds.{DefaultGetterName, ExpandedName} import Names.TermName +import Annotations.Annotation +import Names.Name class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit val ctx: Context) { import Symbols.{toDenot, toClassDenot} @@ -43,10 +45,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap type Symbol = Symbols.Symbol type Type = Types.Type type Tree = tpd.Tree - type Constant = Constants.Constant type Literal = tpd.Literal - type Position = Spans.Span - type Name = Names.Name type ClassDef = tpd.TypeDef type TypeDef = tpd.TypeDef type Apply = tpd.Apply @@ -72,7 +71,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap type Bind = tpd.Bind type New = tpd.New type Super = tpd.Super - type Annotation = Annotations.Annotation type ArrayValue = tpd.JavaSeqLiteral type Closure = tpd.Closure @@ -281,7 +279,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap ctx.error(msg) throw new RuntimeException(msg) } - def sourcePos(pos: Position)(implicit ctx: Context): util.SourcePosition = + def sourcePos(pos: Spans.Span)(implicit ctx: Context): util.SourcePosition = ctx.source.atSpan(pos) def dumpClasses: Option[String] = From 5ec9524161ec566edb0c33b899b1ecc65973e649 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:54:54 +0200 Subject: [PATCH 49/98] Remove tpd type aliases --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 7 +-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 5 ++- .../tools/backend/jvm/BCodeSyncAndTry.scala | 1 + .../backend/jvm/DottyBackendInterface.scala | 43 +++---------------- 4 files changed, 15 insertions(+), 41 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index e48805306f13..57a5cecffc13 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -28,6 +28,7 @@ import dotty.tools.dotc.util.Spans._ trait BCodeBodyBuilder extends BCodeSkelBuilder { // import global._ // import definitions._ + import tpd._ import int._ import bTypes._ import coreBTypes._ @@ -390,7 +391,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val tk = symInfoTK(sym) generatedType = tk - val desugared = desugarIdent(t) + val desugared = desugarIdentBI(t) desugared match { case None => if (!sym.is(Flags.Package)) { @@ -818,7 +819,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType } // end of genApply() - private def genArrayValue(av: ArrayValue): BType = av match { + private def genArrayValue(av: tpd.JavaSeqLiteral): BType = av match { case ArrayValueBI(tpt, elems) => val ArrayValueBI(tpt, elems) = av @@ -1007,7 +1008,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { tree match { case SelectBI(qualifier, _) => genLoad(qualifier) case t: Ident => // dotty specific - desugarIdent(t) match { + desugarIdentBI(t) match { case Some(sel) => genLoadQualifier(sel) case None => assert(t.symbol.owner == this.claszSymbol) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index b1b176945a88..2814d60f1045 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -26,6 +26,7 @@ import dotty.tools.dotc.util.Spans._ */ trait BCodeSkelBuilder extends BCodeHelpers { import int._ + import tpd._ import bTypes._ import coreBTypes._ import bCodeAsmCommon._ @@ -87,8 +88,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* ---------------- helper utils for generating classes and fields ---------------- */ - def genPlainClass(cd: ClassDef) = cd match { - case ClassDef(_, impl) => + def genPlainClass(cd: TypeDef) = cd match { + case TypeDef(_, impl) => assert(cnode == null, "GenBCode detected nested methods.") innerClassBufferASM.clear() diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index cb927b7a772b..0f2c1707d342 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -19,6 +19,7 @@ import dotty.tools.dotc.ast.tpd.TreeOps */ trait BCodeSyncAndTry extends BCodeBodyBuilder { import int._ + import tpd._ import bTypes._ import coreBTypes._ /* diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 185528105631..62adf27058fe 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -44,35 +44,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap type Symbol = Symbols.Symbol type Type = Types.Type - type Tree = tpd.Tree - type Literal = tpd.Literal - type ClassDef = tpd.TypeDef - type TypeDef = tpd.TypeDef - type Apply = tpd.Apply - type TypeApply = tpd.TypeApply - type Try = tpd.Try - type Assign = tpd.Assign - type Ident = tpd.Ident - type If = tpd.If - type ValDef = tpd.ValDef - type Throw = tpd.Apply - type Labeled = tpd.Labeled - type Return = tpd.Return - type WhileDo = tpd.WhileDo - type Block = tpd.Block - type Typed = tpd.Typed - type Match = tpd.Match - type This = tpd.This - type CaseDef = tpd.CaseDef - type Alternative = tpd.Alternative - type DefDef = tpd.DefDef - type Template = tpd.Template - type Select = tpd.Tree // Actually tpd.Select || tpd.Ident - type Bind = tpd.Bind - type New = tpd.New - type Super = tpd.Super - type ArrayValue = tpd.JavaSeqLiteral - type Closure = tpd.Closure // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") @@ -302,7 +273,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] - def desugarIdent(i: Ident): Option[tpd.Select] = { + def desugarIdentBI(i: Ident): Option[tpd.Select] = { var found = desugared.get(i.tpe) if (found == null) { tpd.desugarIdent(i) match { @@ -654,7 +625,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - object SelectBI extends DeconstructorCommon[Select] { + object SelectBI extends DeconstructorCommon[tpd.Tree] { var desugared: tpd.Select = null @@ -665,11 +636,11 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _2: Name = desugared.name - override def unapply(s: Select): this.type = { + override def unapply(s: tpd.Tree): this.type = { s match { case t: tpd.Select => desugared = t case t: Ident => - desugarIdent(t) match { + desugarIdentBI(t) match { case Some(t) => desugared = t case None => desugared = null } @@ -681,11 +652,11 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } object ThrowBI { - var field: Throw = _ + var field: tpd.Apply = _ def isEmpty: Boolean = field eq null def isDefined = !isEmpty def get: Tree = field.args.head - def unapply(s: Throw): ThrowBI.type = { + def unapply(s: tpd.Apply): ThrowBI.type = { if (s.fun.symbol eq defn.throwMethod) { field = s } else { @@ -695,7 +666,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - object ArrayValueBI extends DeconstructorCommon[ArrayValue] { + object ArrayValueBI extends DeconstructorCommon[tpd.JavaSeqLiteral] { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => From 62d89170b9600e66baf75b9a36a0f3270991b1bf Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 18:58:52 +0200 Subject: [PATCH 50/98] Remove Flags type alias --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 9881f5d016a8..beea1a57fefe 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -392,7 +392,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } ctx.debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") - for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flags.Method.bits, excluded = DottyBackendInterface.ExcludedForwarderFlags.bits)) { + for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flags.Method, excluded = DottyBackendInterface.ExcludedForwarderFlags)) { val m = if (m0.is(Flags.Bridge)) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) ctx.log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 62adf27058fe..b18110086c4b 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -39,8 +39,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // Dotty deviation: Need to (re-)import implicit decorators here because otherwise // they would be shadowed by the more deeply nested `symHelper` decorator. - type Flags = Long - type ConstantTag = Int type Symbol = Symbols.Symbol type Type = Types.Type @@ -530,14 +528,12 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap /** The members of this type that have all of `required` flags but none of `excluded` flags set. * The members are sorted by name and signature to guarantee a stable ordering. */ - def sortedMembersBasedOnFlags(tp: Type, required: Flags, excluded: Flags): List[Symbol] = { - val requiredFlagSet = termFlagSet(required) - val excludedFlagSet = termFlagSet(excluded) + def sortedMembersBasedOnFlags(tp: Type, required: Flags.Flag, excluded: Flags.FlagSet): List[Symbol] = { // The output of `memberNames` is a Set, sort it to guarantee a stable ordering. val names = tp.memberNames(takeAllFilter).toSeq.sorted val buffer = mutable.ListBuffer[Symbol]() names.foreach { name => - buffer ++= tp.memberBasedOnFlags(name, requiredFlagSet, excludedFlagSet) + buffer ++= tp.memberBasedOnFlags(name, required, excluded) .alternatives.sortBy(_.signature)(Signature.lexicographicOrdering).map(_.symbol) } buffer.toList From 89d1e67ae3a3e51209fad988d06a9ab835d2fc3d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 19:06:31 +0200 Subject: [PATCH 51/98] Inline method --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 57a5cecffc13..71d344bb0a39 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -686,7 +686,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var generatedType = expectedType lineNumber(app) app match { - case Apply(_, args) if isSyntheticArrayConstructor(app.symbol) => + case Apply(_, args) if app.symbol eq defn.newArrayMethod => val List(elemClaz, Literal(c: Constant), ArrayValueBI(_, dims)) = args generatedType = toTypeKind(c.typeValue) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index b18110086c4b..a21fffc0ba41 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -66,10 +66,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def unboxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap - def isSyntheticArrayConstructor(s: Symbol): Boolean = { - s eq defn.newArrayMethod - } - val primitives = new DottyPrimitives(ctx) def isRuntimeVisible(annot: Annotation): Boolean = @@ -411,7 +407,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // tests def isClass: Boolean = sym.isPackageObject || sym.isClass def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) - def isInterface: Boolean = (sym.is(Flags.PureInterface)) || (sym.is(Flags.Trait)) + def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) /** Does this symbol actually correspond to an interface that will be emitted? * In the backend, this should be preferred over `isInterface` because it @@ -420,7 +416,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * which we represent as classes. */ def isEmittedInterface: Boolean = isInterface || - sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && symHelper(sym.companionClass).isInterface) + sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait)) def isStaticMember: Boolean = (sym ne NoSymbol) && (sym.is(Flags.JavaStatic) || sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)) From 14f05151c4a1f49e964330cb32813a050a682c4c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 19:16:42 +0200 Subject: [PATCH 52/98] Inline some methods --- .../dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 6 +++++- compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala | 6 ++++++ .../tools/backend/jvm/DottyBackendInterface.scala | 11 ----------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 71d344bb0a39..f538497c5abd 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -779,7 +779,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { genLoadArguments(args, paramTKs(app)) val SelectBI(qual, _) = fun // fun is a Select, also checked in genLoadQualifier - if (isArrayClone(fun)) { + val isArrayClone = fun match { + case SelectBI(qual, nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true + case _ => false + } + if (isArrayClone) { // Special-case Array.clone, introduced in 36ef60e. The goal is to generate this call // as "[I.clone" instead of "java/lang/Object.clone". This is consistent with javac. // Arrays have a public method `clone` (jls 10.7). diff --git a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala index aa53a4935157..c8b879feaef7 100644 --- a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala @@ -5,6 +5,7 @@ package jvm import scala.annotation.switch import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.transform.Erasure /** * Core BTypes and some other definitions. The initialization of these definitions requies access @@ -86,6 +87,9 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp * method symbol for `Byte.box()` is mapped to the ClassBType `java/lang/Byte`. */ lazy val boxResultType: Map[Symbol, ClassBType] = { + val boxMethods = defn.ScalaValueClasses().map{x => // @darkdimius Are you sure this should be a def? + (x, Erasure.Boxing.boxMethod(x.asClass)) + }.toMap for ((valueClassSym, boxMethodSym) <- boxMethods) yield boxMethodSym -> boxedClassOfPrimitive(primitiveTypeMap(valueClassSym)) } @@ -94,6 +98,8 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp * Maps the method symbol for an unbox method to the primitive type of the result. * For example, the method symbol for `Byte.unbox()`) is mapped to the PrimitiveBType BYTE. */ lazy val unboxResultType: Map[Symbol, PrimitiveBType] = { + val unboxMethods: Map[Symbol, Symbol] = + defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap for ((valueClassSym, unboxMethodSym) <- unboxMethods) yield unboxMethodSym -> primitiveTypeMap(valueClassSym) } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index a21fffc0ba41..bc82690fc98a 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -47,11 +47,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") - def isArrayClone(tree: Tree): Boolean = tree match { - case SelectBI(qual, StdNames.nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true - case _ => false - } - val externalEquals: Symbol = defn.BoxesRunTimeModule.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol @threadUnsafe lazy val AnnotationRetentionAttr: ClassSymbol = ctx.requiredClass("java.lang.annotation.Retention") @@ -60,12 +55,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap @threadUnsafe lazy val AnnotationRetentionRuntimeAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") @threadUnsafe lazy val JavaAnnotationClass: ClassSymbol = ctx.requiredClass("java.lang.annotation.Annotation") - def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map{x => // @darkdimius Are you sure this should be a def? - (x, Erasure.Boxing.boxMethod(x.asClass)) - }.toMap - def unboxMethods: Map[Symbol, Symbol] = - defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap - val primitives = new DottyPrimitives(ctx) def isRuntimeVisible(annot: Annotation): Boolean = From 38defd11ca4db597090d94d82a9b832c709791be Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 19:16:59 +0200 Subject: [PATCH 53/98] Remove condition from isClass --- .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index bc82690fc98a..880742e147a1 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -394,7 +394,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap class SymbolHelper(sym: Symbol) { // tests - def isClass: Boolean = sym.isPackageObject || sym.isClass + def isClass: Boolean = sym.isClass def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) From 1610aeab1060dc7fd3394efee81a5bc4b56b9eb8 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 21:06:17 +0200 Subject: [PATCH 54/98] Fix inlining of isInterface --- .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 880742e147a1..0fa52ac5272b 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -405,7 +405,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * which we represent as classes. */ def isEmittedInterface: Boolean = isInterface || - sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait)) + sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.companionClass.is(Flags.PureInterface)) || sym.companionClass.is(Flags.Trait)) def isStaticMember: Boolean = (sym ne NoSymbol) && (sym.is(Flags.JavaStatic) || sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)) From ef05863c1ddc843a5ae09fbff9983580bd279d62 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 3 Jun 2020 21:11:06 +0200 Subject: [PATCH 55/98] Inline isClass --- .../src/dotty/tools/backend/jvm/BCodeAsmCommon.scala | 12 ++++++------ .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../dotty/tools/backend/jvm/BTypesFromSymbols.scala | 8 ++++---- .../tools/backend/jvm/DottyBackendInterface.scala | 1 - 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 7e4a286310c5..82a0cfe803bd 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -19,13 +19,13 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { * null. */ def isAnonymousOrLocalClass(classSym: Symbol): Boolean = { - assert(symHelper(classSym).isClass, s"not a class: $classSym") + assert(classSym.isClass, s"not a class: $classSym") // Here used to be an `assert(!classSym.isDelambdafyFunction)`: delambdafy lambda classes are // always top-level. However, SI-8900 shows an example where the weak name-based implementation // of isDelambdafyFunction failed (for a function declared in a package named "lambda"). classSym.isAnonymousClass || { val originalOwnerLexicallyEnclosingClass = symHelper(classSym.originalOwner).originalLexicallyEnclosingClass - originalOwnerLexicallyEnclosingClass != NoSymbol && !symHelper(originalOwnerLexicallyEnclosingClass).isClass + originalOwnerLexicallyEnclosingClass != NoSymbol && !originalOwnerLexicallyEnclosingClass.isClass } } @@ -53,9 +53,9 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { * This is a source-level property, so we need to use the originalOwner chain to reconstruct it. */ private def enclosingMethodForEnclosingMethodAttribute(classSym: Symbol): Option[Symbol] = { - assert(symHelper(classSym).isClass, classSym) + assert(classSym.isClass, classSym) def enclosingMethod(sym: Symbol): Option[Symbol] = { - if (symHelper(sym).isClass || sym == NoSymbol) None + if (sym.isClass || sym == NoSymbol) None else if (sym.is(Flags.Method)) Some(sym) else enclosingMethod(symHelper(sym.originalOwner).originalLexicallyEnclosingClass) } @@ -67,9 +67,9 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { * property, this method looks at the originalOwner chain. See doc in BTypes. */ private def enclosingClassForEnclosingMethodAttribute(classSym: Symbol): Symbol = { - assert(symHelper(classSym).isClass, classSym) + assert(classSym.isClass, classSym) def enclosingClass(sym: Symbol): Symbol = { - if (symHelper(sym).isClass) sym + if (sym.isClass) sym else enclosingClass(symHelper(sym.originalOwner).originalLexicallyEnclosingClass) } enclosingClass(symHelper(classSym.originalOwner).originalLexicallyEnclosingClass) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index beea1a57fefe..3b218a70bc0d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -206,7 +206,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } private def assertClassNotArray(sym: Symbol): Unit = { - assert(symHelper(sym).isClass, sym) + assert(sym.isClass, sym) assert(sym != defn.ArrayClass || isCompilingArray, sym) } diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index e35af8922b74..f5ca00ea7aa0 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -48,7 +48,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { */ final def classBTypeFromSymbol(classSym: Symbol): ClassBType = { assert(classSym != NoSymbol, "Cannot create ClassBType from NoSymbol") - assert(symHelper(classSym).isClass, s"Cannot create ClassBType from non-class symbol $classSym") + assert(classSym.isClass, s"Cannot create ClassBType from non-class symbol $classSym") assert( (!primitiveTypeMap.contains(classSym) || isCompilingPrimitive) && (classSym != defn.NothingClass && classSym != defn.NullClass), @@ -160,7 +160,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { - assert(symHelper(innerClassSym).isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") + assert(innerClassSym.isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") val isNested = !symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.is(Flags.PackageClass) if (!isNested) None @@ -170,7 +170,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // After lambdalift (which is where we are), the rawowoner field contains the enclosing class. val enclosingClassSym = { - if (symHelper(innerClassSym).isClass) { + if (innerClassSym.isClass) { val ct = ctx.withPhase(ctx.flattenPhase.prev) toDenot(innerClassSym)(ct).owner.enclosingClass(ct) } @@ -247,7 +247,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (symHelper(sym).isStaticMember) ACC_STATIC else 0, if (sym.is(Flags.Bridge)) ACC_BRIDGE | ACC_SYNTHETIC else 0, if (sym.is(Flags.Artifact)) ACC_SYNTHETIC else 0, - if (symHelper(sym).isClass && !symHelper(sym).isInterface) ACC_SUPER else 0, + if (sym.isClass && !symHelper(sym).isInterface) ACC_SUPER else 0, if (sym.isAllOf(Flags.JavaEnumTrait)) ACC_ENUM else 0, if (sym.is(Flags.JavaVarargs)) ACC_VARARGS else 0, if (sym.is(Flags.Synchronized)) ACC_SYNCHRONIZED else 0, diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 0fa52ac5272b..d39885e314ca 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -394,7 +394,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap class SymbolHelper(sym: Symbol) { // tests - def isClass: Boolean = sym.isClass def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) From 7334e947b73aa2ec1badf68e3fec7824c56e642d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 08:41:28 +0200 Subject: [PATCH 56/98] Inline emitAnnotations --- .../tools/backend/jvm/BCodeHelpers.scala | 135 ++++++++++++++++-- .../backend/jvm/DottyBackendInterface.scala | 126 ---------------- 2 files changed, 126 insertions(+), 135 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 3b218a70bc0d..581cf7dbf5eb 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -3,14 +3,18 @@ package backend package jvm import scala.tools.asm +import scala.tools.asm.AnnotationVisitor import scala.tools.asm.ClassWriter import scala.collection.mutable import dotty.tools.io.AbstractFile import dotty.tools.dotc.CompilationUnit +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.ast.Trees import dotty.tools.dotc.core.Annotations.Annotation +import dotty.tools.dotc.core.Constants._ import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.core.StdNames.str +import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Names.Name @@ -30,6 +34,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { //import bTypes._ //import coreBTypes._ import bTypes._ + import tpd._ import coreBTypes._ import int._ @@ -273,26 +278,138 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { /* * must-single-thread */ - def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation]) = - int.emitAnnotations(cw, annotations, BCodeHelpers.this)(this) + def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation]): Unit = + for(annot <- annotations; if shouldEmitAnnotation(annot)) { + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) + val av = cw.visitAnnotation(typeDescriptor(typ.asInstanceOf[Type]), isRuntimeVisible(annot)) + emitAssocs(av, assocs, BCodeHelpers.this)(this) + } /* * must-single-thread */ - def emitAnnotations(mw: asm.MethodVisitor, annotations: List[Annotation]) = - int.emitAnnotations(mw, annotations, BCodeHelpers.this)(this) + def emitAnnotations(mw: asm.MethodVisitor, annotations: List[Annotation]): Unit = + for(annot <- annotations; if shouldEmitAnnotation(annot)) { + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) + val av = mw.visitAnnotation(typeDescriptor(typ.asInstanceOf[Type]), isRuntimeVisible(annot)) + emitAssocs(av, assocs, BCodeHelpers.this)(this) + } /* * must-single-thread */ - def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation]) = - int.emitAnnotations(fw, annotations, BCodeHelpers.this)(this) + def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation]): Unit = + for(annot <- annotations; if shouldEmitAnnotation(annot)) { + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) + val av = fw.visitAnnotation(typeDescriptor(typ.asInstanceOf[Type]), isRuntimeVisible(annot)) + emitAssocs(av, assocs, BCodeHelpers.this)(this) + } /* * must-single-thread */ - def emitParamAnnotations(jmethod: asm.MethodVisitor, pannotss: List[List[Annotation]]) = - int.emitParamAnnotations(jmethod, pannotss, BCodeHelpers.this)(this) + def emitParamAnnotations(jmethod: asm.MethodVisitor, pannotss: List[List[Annotation]]): Unit = + val annotationss = pannotss map (_ filter shouldEmitAnnotation) + if (annotationss forall (_.isEmpty)) return + for ((annots, idx) <- annotationss.zipWithIndex; + annot <- annots) { + val typ = annot.tree.tpe + val assocs = assocsFromApply(annot.tree) + val pannVisitor: asm.AnnotationVisitor = jmethod.visitParameterAnnotation(idx, typeDescriptor(typ.asInstanceOf[Type]), isRuntimeVisible(annot)) + emitAssocs(pannVisitor, assocs, BCodeHelpers.this)(this) + } + + private def emitAssocs(av: asm.AnnotationVisitor, assocs: List[(Name, Object)], bcodeStore: BCodeHelpers) + (innerClasesStore: bcodeStore.BCInnerClassGen) = { + for ((name, value) <- assocs) + emitArgument(av, name.mangledString, value.asInstanceOf[Tree], bcodeStore)(innerClasesStore) + av.visitEnd() + } + + private def emitArgument(av: AnnotationVisitor, + name: String, + arg: Tree, bcodeStore: BCodeHelpers)(innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { + val narg = normalizeArgument(arg) + // Transformation phases are not run on annotation trees, so we need to run + // `constToLiteral` at this point. + val t = constToLiteral(narg)(ctx.withPhase(ctx.erasurePhase)) + t match { + case Literal(const @ Constant(_)) => + const.tag match { + case BooleanTag | ByteTag | ShortTag | CharTag | IntTag | LongTag | FloatTag | DoubleTag => av.visit(name, const.value) + case StringTag => + assert(const.value != null, const) // TODO this invariant isn't documented in `case class Constant` + av.visit(name, const.stringValue) // `stringValue` special-cases null, but that execution path isn't exercised for a const with StringTag + case ClazzTag => av.visit(name, typeToTypeKind(const.typeValue)(bcodeStore)(innerClasesStore).toASMType) + case EnumTag => + val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. + val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. + av.visitEnum(name, edesc, evalue) + } + case t: TypeApply if (t.fun.symbol == defn.Predef_classOf) => + av.visit(name, typeToTypeKind(t.args.head.tpe.classSymbol.denot.info)(bcodeStore)(innerClasesStore).toASMType) + case Ident(nme.WILDCARD) => + // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything + case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => + 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) + 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 => + val arrAnnotV: AnnotationVisitor = av.visitArray(name) + + var actualArgs = if (fun.tpe.isImplicitMethod) { + // generic array method, need to get implicit argument out of the way + fun.asInstanceOf[Apply].args + } else args + + val flatArgs = actualArgs.flatMap { arg => + normalizeArgument(arg) match { + case t: tpd.SeqLiteral => t.elems + case e => List(e) + } + } + for(arg <- flatArgs) { + emitArgument(arrAnnotV, null, arg, bcodeStore)(innerClasesStore) + } + arrAnnotV.visitEnd() + /* + case sb @ ScalaSigBytes(bytes) => + // see http://www.scala-lang.org/sid/10 (Storage of pickled Scala signatures in class files) + // also JVMS Sec. 4.7.16.1 The element_value structure and JVMS Sec. 4.4.7 The CONSTANT_Utf8_info Structure. + if (sb.fitsInOneString) { + av.visit(name, BCodeAsmCommon.strEncode(sb)) + } else { + val arrAnnotV: asm.AnnotationVisitor = av.visitArray(name) + for(arg <- BCodeAsmCommon.arrEncode(sb)) { arrAnnotV.visit(name, arg) } + arrAnnotV.visitEnd() + } // 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 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) + emitAssocs(nestedVisitor, assocs, bcodeStore)(innerClasesStore) + + case t => + ctx.error(ex"Annotation argument is not a constant", t.sourcePos) + } + } + + private def normalizeArgument(arg: Tree): Tree = arg match { + case Trees.NamedArg(_, arg1) => normalizeArgument(arg1) + case Trees.Typed(arg1, _) => normalizeArgument(arg1) + case _ => arg + } } // end of trait BCAnnotGen diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index d39885e314ca..2ae7ad42f4cd 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -82,132 +82,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap case _ => arg } - private def emitArgument(av: AnnotationVisitor, - name: String, - arg: Tree, bcodeStore: BCodeHelpers)(innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { - val narg = normalizeArgument(arg) - // Transformation phases are not run on annotation trees, so we need to run - // `constToLiteral` at this point. - val t = constToLiteral(narg)(ctx.withPhase(ctx.erasurePhase)) - t match { - case Literal(const @ Constant(_)) => - const.tag match { - case BooleanTag | ByteTag | ShortTag | CharTag | IntTag | LongTag | FloatTag | DoubleTag => av.visit(name, const.value) - case StringTag => - assert(const.value != null, const) // TODO this invariant isn't documented in `case class Constant` - av.visit(name, const.stringValue) // `stringValue` special-cases null, but that execution path isn't exercised for a const with StringTag - case ClazzTag => av.visit(name, typeToTypeKind(const.typeValue)(bcodeStore)(innerClasesStore).toASMType) - case EnumTag => - val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. - val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. - av.visitEnum(name, edesc, evalue) - } - case t: TypeApply if (t.fun.symbol == defn.Predef_classOf) => - av.visit(name, typeToTypeKind(t.args.head.tpe.classSymbol.denot.info)(bcodeStore)(innerClasesStore).toASMType) - case Ident(nme.WILDCARD) => - // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything - case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => - 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) - 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 => - val arrAnnotV: AnnotationVisitor = av.visitArray(name) - - var actualArgs = if (fun.tpe.isImplicitMethod) { - // generic array method, need to get implicit argument out of the way - fun.asInstanceOf[Apply].args - } else args - - val flatArgs = actualArgs.flatMap { arg => - normalizeArgument(arg) match { - case t: tpd.SeqLiteral => t.elems - case e => List(e) - } - } - for(arg <- flatArgs) { - emitArgument(arrAnnotV, null, arg, bcodeStore)(innerClasesStore) - } - arrAnnotV.visitEnd() -/* - case sb @ ScalaSigBytes(bytes) => - // see http://www.scala-lang.org/sid/10 (Storage of pickled Scala signatures in class files) - // also JVMS Sec. 4.7.16.1 The element_value structure and JVMS Sec. 4.4.7 The CONSTANT_Utf8_info Structure. - if (sb.fitsInOneString) { - av.visit(name, BCodeAsmCommon.strEncode(sb)) - } else { - val arrAnnotV: asm.AnnotationVisitor = av.visitArray(name) - for(arg <- BCodeAsmCommon.arrEncode(sb)) { arrAnnotV.visit(name, arg) } - arrAnnotV.visitEnd() - } // 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 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) - emitAssocs(nestedVisitor, assocs, bcodeStore)(innerClasesStore) - - case t => - ctx.error(ex"Annotation argument is not a constant", t.sourcePos) - } - } - - def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) - (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { - for(annot <- annotations; if shouldEmitAnnotation(annot)) { - val typ = annot.tree.tpe - val assocs = assocsFromApply(annot.tree) - val av = cw.visitAnnotation(innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) - emitAssocs(av, assocs, bcodeStore)(innerClasesStore) - } - } - - private def emitAssocs(av: asm.AnnotationVisitor, assocs: List[(Name, Object)], bcodeStore: BCodeHelpers) - (innerClasesStore: bcodeStore.BCInnerClassGen) = { - for ((name, value) <- assocs) - emitArgument(av, name.mangledString, value.asInstanceOf[Tree], bcodeStore)(innerClasesStore) - av.visitEnd() - } - - def emitAnnotations(mw: asm.MethodVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) - (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { - for(annot <- annotations; if shouldEmitAnnotation(annot)) { - val typ = annot.tree.tpe - val assocs = assocsFromApply(annot.tree) - val av = mw.visitAnnotation(innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) - emitAssocs(av, assocs, bcodeStore)(innerClasesStore) - } - } - - def emitAnnotations(fw: asm.FieldVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers) - (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { - for(annot <- annotations; if shouldEmitAnnotation(annot)) { - val typ = annot.tree.tpe - val assocs = assocsFromApply(annot.tree) - val av = fw.visitAnnotation(innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) - emitAssocs(av, assocs, bcodeStore)(innerClasesStore) - } - } - - def emitParamAnnotations(jmethod: asm.MethodVisitor, pannotss: List[List[Annotation]], bcodeStore: BCodeHelpers) - (innerClasesStore: bcodeStore.BCInnerClassGen): Unit = { - val annotationss = pannotss map (_ filter shouldEmitAnnotation) - if (annotationss forall (_.isEmpty)) return - for ((annots, idx) <- annotationss.zipWithIndex; - annot <- annots) { - val typ = annot.tree.tpe - val assocs = assocsFromApply(annot.tree) - val pannVisitor: asm.AnnotationVisitor = jmethod.visitParameterAnnotation(idx, innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]), isRuntimeVisible(annot)) - emitAssocs(pannVisitor, assocs, bcodeStore)(innerClasesStore) - } - } - def getAnnotPickle(jclassName: String, sym: Symbol): Option[Annotation] = None From 91de509e4c3394c683069946308e82d6b331c5bb Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 08:49:31 +0200 Subject: [PATCH 57/98] Inline some methods --- .../tools/backend/jvm/BCodeHelpers.scala | 10 ++++----- .../tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../dotty/tools/backend/jvm/CoreBTypes.scala | 5 +++-- .../backend/jvm/DottyBackendInterface.scala | 22 ++----------------- 4 files changed, 11 insertions(+), 28 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 581cf7dbf5eb..27325e6caa6c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -93,7 +93,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def initBytecodeWriter(): BytecodeWriter = { - getSingleOutput match { + (None: Option[AbstractFile] /*getSingleOutput*/) match { // todo: implement case Some(f) if f.hasExtension("jar") => new DirectToJarfileWriter(f.file) case _ => @@ -212,7 +212,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { private def assertClassNotArray(sym: Symbol): Unit = { assert(sym.isClass, sym) - assert(sym != defn.ArrayClass || isCompilingArray, sym) + assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) } private def assertClassNotArrayNotPrimitive(sym: Symbol): Unit = { @@ -613,7 +613,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { null /* SourceDebugExtension */) } - val ssa = getAnnotPickle(mirrorName, if (moduleClass.is(Flags.Module)) moduleClass.companionClass else moduleClass.companionModule) + val ssa = None // getAnnotPickle(mirrorName, if (moduleClass.is(Flags.Module)) moduleClass.companionClass else moduleClass.companionModule) mirrorClass.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) emitAnnotations(mirrorClass, moduleClass.annotations ++ ssa) @@ -641,8 +641,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ val androidFieldName = "CREATOR".toTermName - lazy val AndroidParcelableInterface : Symbol = getClassIfDefined("android.os.Parcelable") - lazy val AndroidCreatorClass : Symbol = getClassIfDefined("android.os.Parcelable$Creator") + lazy val AndroidParcelableInterface : Symbol = NoSymbol // getClassIfDefined("android.os.Parcelable") + lazy val AndroidCreatorClass : Symbol = NoSymbol // getClassIfDefined("android.os.Parcelable$Creator") /* * must-single-thread diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 2814d60f1045..91d3c9bee3ad 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -170,7 +170,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { case _ => () } - val ssa = getAnnotPickle(thisName, claszSymbol) + val ssa = None // getAnnotPickle(thisName, claszSymbol) cnode.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) emitAnnotations(cnode, claszSymbol.annotations ++ ssa) diff --git a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala index c8b879feaef7..9fbcdaa2a7c6 100644 --- a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala @@ -4,6 +4,7 @@ package jvm import scala.annotation.switch +import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.transform.Erasure @@ -112,8 +113,8 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp * names of NothingClass and NullClass can't be emitted as-is. * TODO @lry Once there's a 2.11.3 starr, use the commented argument list. The current starr crashes on the type literal `scala.runtime.Nothing$` */ - lazy val RT_NOTHING : ClassBType = classBTypeFromSymbol(getRequiredClass("scala.runtime.Nothing$")) // (requiredClass[scala.runtime.Nothing$]) - lazy val RT_NULL : ClassBType = classBTypeFromSymbol(getRequiredClass("scala.runtime.Null$")) // (requiredClass[scala.runtime.Null$]) + lazy val RT_NOTHING : ClassBType = classBTypeFromSymbol(ctx.requiredClass("scala.runtime.Nothing$")) // (requiredClass[scala.runtime.Nothing$]) + lazy val RT_NULL : ClassBType = classBTypeFromSymbol(ctx.requiredClass("scala.runtime.Null$")) // (requiredClass[scala.runtime.Null$]) lazy val ObjectReference : ClassBType = classBTypeFromSymbol(defn.ObjectClass) lazy val objArrayReference : ArrayBType = ArrayBType(ObjectReference) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 2ae7ad42f4cd..50bffa7aacfe 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -76,19 +76,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap annot.tree.tpe.typeSymbol.getAnnotation(AnnotationRetentionAttr). flatMap(_.argumentConstant(0).map(_.symbolValue)).getOrElse(AnnotationRetentionClassAttr) - private def normalizeArgument(arg: Tree): Tree = arg match { - case Trees.NamedArg(_, arg1) => normalizeArgument(arg1) - case Trees.Typed(arg1, _) => normalizeArgument(arg1) - case _ => arg - } - - def getAnnotPickle(jclassName: String, sym: Symbol): Option[Annotation] = None - - - def getRequiredClass(fullname: String): Symbol = ctx.requiredClass(fullname) - - def getClassIfDefined(fullname: String): Symbol = NoSymbol // used only for android. todo: implement - private def erasureString(clazz: Class[_]): String = { if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" else clazz.getName @@ -153,8 +140,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap (sym derivesFrom defn.BoxedBooleanClass) } - def getSingleOutput: Option[AbstractFile] = None // todo: implement - // @M don't generate java generics sigs for (members of) implementation // classes, as they are monomorphic (TODO: ok?) private final def needsGenericSignature(sym: Symbol): Boolean = !( @@ -417,7 +402,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap */ def primitiveOrClassToBType(sym: Symbol): BType = { assert(sym.isClass, sym) - assert(sym != defn.ArrayClass || isCompilingArray, sym) + assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] } @@ -427,7 +412,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap * signatures, e.g. `def apply(i: Int): T`. A TyperRef to T is replaced by ObjectReference. */ def nonClassTypeRefToBType(sym: Symbol): ClassBType = { - assert(sym.isType && isCompilingArray, sym) + assert(sym.isType && ctx.compilationUnit.source.file.name == "Array.scala", sym) ObjectReference.asInstanceOf[ct.bTypes.ClassBType] } @@ -587,9 +572,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap primitiveCompilationUnits(ctx.compilationUnit.source.file.name) } - def isCompilingArray = { - ctx.compilationUnit.source.file.name == "Array.scala" - } } object DottyBackendInterface { From 1a7dc1e084b5042af42be18b6c1288e62079e48a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 08:53:43 +0200 Subject: [PATCH 58/98] Move typeToTypeKind --- .../tools/backend/jvm/BCodeHelpers.scala | 87 ++++++++++++++++++- .../backend/jvm/DottyBackendInterface.scala | 82 ----------------- 2 files changed, 85 insertions(+), 84 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 27325e6caa6c..d7b708487e11 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -13,12 +13,13 @@ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.ast.Trees import dotty.tools.dotc.core.Annotations.Annotation import dotty.tools.dotc.core.Constants._ -import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Names.Name import dotty.tools.dotc.core.NameKinds.ExpandedName +import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.StdNames._ +import dotty.tools.dotc.core.Types /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -697,6 +698,88 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } } // end of trait JAndroidBuilder + + /** + * This method returns the BType for a type reference, for example a parameter type. + * + * If the result is a ClassBType for a nested class, it is added to the innerClassBufferASM. + * + * If `t` references a class, toTypeKind ensures that the class is not an implementation class. + * See also comment on getClassBTypeAndRegisterInnerClass, which is invoked for implementation + * classes. + */ + private def typeToTypeKind(tp: Type)(ct: BCodeHelpers)(storage: ct.BCInnerClassGen): ct.bTypes.BType = { + import ct.bTypes._ + val defn = ctx.definitions + import coreBTypes._ + import Types._ + /** + * Primitive types are represented as TypeRefs to the class symbol of, for example, scala.Int. + * The `primitiveTypeMap` maps those class symbols to the corresponding PrimitiveBType. + */ + def primitiveOrClassToBType(sym: Symbol): BType = { + assert(sym.isClass, sym) + assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) + primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], + storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] + } + + /** + * When compiling Array.scala, the type parameter T is not erased and shows up in method + * signatures, e.g. `def apply(i: Int): T`. A TyperRef to T is replaced by ObjectReference. + */ + def nonClassTypeRefToBType(sym: Symbol): ClassBType = { + assert(sym.isType && ctx.compilationUnit.source.file.name == "Array.scala", sym) + ObjectReference.asInstanceOf[ct.bTypes.ClassBType] + } + + tp.widenDealias match { + case JavaArrayType(el) =>ArrayBType(typeToTypeKind(el)(ct)(storage)) // Array type such as Array[Int] (kept by erasure) + case t: TypeRef => + t.info match { + + case _ => + if (!t.symbol.isClass) nonClassTypeRefToBType(t.symbol) // See comment on nonClassTypeRefToBType + else primitiveOrClassToBType(t.symbol) // Common reference to a type such as scala.Int or java.lang.String + } + case Types.ClassInfo(_, sym, _, _, _) => primitiveOrClassToBType(sym) // We get here, for example, for genLoadModule, which invokes toTypeKind(moduleClassSymbol.info) + + /* AnnotatedType should (probably) be eliminated by erasure. However we know it happens for + * meta-annotated annotations (@(ann @getter) val x = 0), so we don't emit a warning. + * The type in the AnnotationInfo is an AnnotatedTpe. Tested in jvm/annotations.scala. + */ + case a @ AnnotatedType(t, _) => + ctx.debuglog(s"typeKind of annotated type $a") + typeToTypeKind(t)(ct)(storage) + + /* ExistentialType should (probably) be eliminated by erasure. We know they get here for + * classOf constants: + * class C[T] + * class T { final val k = classOf[C[_]] } + */ + /* case e @ ExistentialType(_, t) => + debuglog(s"typeKind of existential type $e") + t.toTypeKind(ctx)(storage)*/ + + /* The cases below should probably never occur. They are kept for now to avoid introducing + * new compiler crashes, but we added a warning. The compiler / library bootstrap and the + * test suite don't produce any warning. + */ + + case tp => + ctx.warning( + s"an unexpected type representation reached the compiler backend while compiling ${ctx.compilationUnit}: $tp. " + + "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") + + tp match { + case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test + case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) + // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) + case t: SingletonType => typeToTypeKind(t.underlying)(ct)(storage) + case t: RefinedType => typeToTypeKind(t.parent)(ct)(storage) //parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b)) + } + } + } } object BCodeHelpers { diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 50bffa7aacfe..c34c61375c25 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -382,88 +382,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap buffer.toList } - /** - * This method returns the BType for a type reference, for example a parameter type. - * - * If the result is a ClassBType for a nested class, it is added to the innerClassBufferASM. - * - * If `t` references a class, toTypeKind ensures that the class is not an implementation class. - * See also comment on getClassBTypeAndRegisterInnerClass, which is invoked for implementation - * classes. - */ - def typeToTypeKind(tp: Type)(ct: BCodeHelpers)(storage: ct.BCInnerClassGen): ct.bTypes.BType = { - import ct.bTypes._ - val defn = ctx.definitions - import coreBTypes._ - import Types._ - /** - * Primitive types are represented as TypeRefs to the class symbol of, for example, scala.Int. - * The `primitiveTypeMap` maps those class symbols to the corresponding PrimitiveBType. - */ - def primitiveOrClassToBType(sym: Symbol): BType = { - assert(sym.isClass, sym) - assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) - primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], - storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] - } - - /** - * When compiling Array.scala, the type parameter T is not erased and shows up in method - * signatures, e.g. `def apply(i: Int): T`. A TyperRef to T is replaced by ObjectReference. - */ - def nonClassTypeRefToBType(sym: Symbol): ClassBType = { - assert(sym.isType && ctx.compilationUnit.source.file.name == "Array.scala", sym) - ObjectReference.asInstanceOf[ct.bTypes.ClassBType] - } - - tp.widenDealias match { - case JavaArrayType(el) =>ArrayBType(typeToTypeKind(el)(ct)(storage)) // Array type such as Array[Int] (kept by erasure) - case t: TypeRef => - t.info match { - - case _ => - if (!t.symbol.isClass) nonClassTypeRefToBType(t.symbol) // See comment on nonClassTypeRefToBType - else primitiveOrClassToBType(t.symbol) // Common reference to a type such as scala.Int or java.lang.String - } - case Types.ClassInfo(_, sym, _, _, _) => primitiveOrClassToBType(sym) // We get here, for example, for genLoadModule, which invokes toTypeKind(moduleClassSymbol.info) - - /* AnnotatedType should (probably) be eliminated by erasure. However we know it happens for - * meta-annotated annotations (@(ann @getter) val x = 0), so we don't emit a warning. - * The type in the AnnotationInfo is an AnnotatedTpe. Tested in jvm/annotations.scala. - */ - case a @ AnnotatedType(t, _) => - ctx.debuglog(s"typeKind of annotated type $a") - typeToTypeKind(t)(ct)(storage) - - /* ExistentialType should (probably) be eliminated by erasure. We know they get here for - * classOf constants: - * class C[T] - * class T { final val k = classOf[C[_]] } - */ - /* case e @ ExistentialType(_, t) => - debuglog(s"typeKind of existential type $e") - t.toTypeKind(ctx)(storage)*/ - - /* The cases below should probably never occur. They are kept for now to avoid introducing - * new compiler crashes, but we added a warning. The compiler / library bootstrap and the - * test suite don't produce any warning. - */ - - case tp => - ctx.warning( - s"an unexpected type representation reached the compiler backend while compiling ${ctx.compilationUnit}: $tp. " + - "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") - - tp match { - case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test - case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) - // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) - case t: SingletonType => typeToTypeKind(t.underlying)(ct)(storage) - case t: RefinedType => typeToTypeKind(t.parent)(ct)(storage) //parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b)) - } - } - } - object SelectBI extends DeconstructorCommon[tpd.Tree] { var desugared: tpd.Select = null From 1e4439af19010d96a17e30dddb45265f86832bbb Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 09:12:45 +0200 Subject: [PATCH 59/98] Move methods --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 10 ++- .../tools/backend/jvm/BCodeHelpers.scala | 40 +++++++++- .../tools/backend/jvm/BTypesFromSymbols.scala | 34 +++++++- .../tools/backend/jvm/BytecodeWriters.scala | 8 +- .../backend/jvm/DottyBackendInterface.scala | 80 ------------------- 5 files changed, 85 insertions(+), 87 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index f538497c5abd..f9eb123c155f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1351,7 +1351,15 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { */ val mustUseAnyComparator: Boolean = { val areSameFinals = l.tpe.typeSymbol.is(Flags.Final) && r.tpe.typeSymbol.is(Flags.Final) && (l.tpe =:= r.tpe) - + // todo: remove + def isMaybeBoxed(sym: Symbol): Boolean = { + (sym == defn.ObjectClass) || + (sym == defn.JavaSerializableClass) || + (sym == defn.ComparableClass) || + (sym derivesFrom defn.BoxedNumberClass) || + (sym derivesFrom defn.BoxedCharClass) || + (sym derivesFrom defn.BoxedBooleanClass) + } !areSameFinals && isMaybeBoxed(l.tpe.widenDealias.typeSymbol) && isMaybeBoxed(r.tpe.widenDealias.typeSymbol) } def isNull(t: Tree): Boolean = t match { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index d7b708487e11..a99295a9607c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -17,9 +17,11 @@ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Names.Name import dotty.tools.dotc.core.NameKinds.ExpandedName -import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Signature import dotty.tools.dotc.core.StdNames._ +import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types +import dotty.tools.dotc.core.Types._ /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -183,7 +185,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { trait BCInnerClassGen { - def debugLevel = int.debuglevel + def debugLevel = 3 // 0 -> no debug info; 1-> filename; 2-> lines; 3-> varnames final val emitSource = debugLevel >= 1 final val emitLines = debugLevel >= 2 @@ -323,6 +325,12 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { emitAssocs(pannVisitor, assocs, BCodeHelpers.this)(this) } + + private def shouldEmitAnnotation(annot: Annotation): Boolean = { + annot.symbol.is(Flags.JavaDefined) && + retentionPolicyOf(annot) != AnnotationRetentionSourceAttr + } + private def emitAssocs(av: asm.AnnotationVisitor, assocs: List[(Name, Object)], bcodeStore: BCodeHelpers) (innerClasesStore: bcodeStore.BCInnerClassGen) = { for ((name, value) <- assocs) @@ -412,6 +420,20 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case _ => arg } + private def isRuntimeVisible(annot: Annotation): Boolean = + if (toDenot(annot.tree.tpe.typeSymbol).hasAnnotation(AnnotationRetentionAttr)) + retentionPolicyOf(annot) == AnnotationRetentionRuntimeAttr + else { + // SI-8926: if the annotation class symbol doesn't have a @RetentionPolicy annotation, the + // annotation is emitted with visibility `RUNTIME` + // dotty bug: #389 + true + } + + private def retentionPolicyOf(annot: Annotation): Symbol = + annot.tree.tpe.typeSymbol.getAnnotation(AnnotationRetentionAttr). + flatMap(_.argumentConstant(0).map(_.symbolValue)).getOrElse(AnnotationRetentionClassAttr) + } // end of trait BCAnnotGen trait BCJGenSigGen { @@ -527,6 +549,20 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } } + /** The members of this type that have all of `required` flags but none of `excluded` flags set. + * The members are sorted by name and signature to guarantee a stable ordering. + */ + private def sortedMembersBasedOnFlags(tp: Type, required: Flags.Flag, excluded: Flags.FlagSet): List[Symbol] = { + // The output of `memberNames` is a Set, sort it to guarantee a stable ordering. + val names = tp.memberNames(takeAllFilter).toSeq.sorted + val buffer = mutable.ListBuffer[Symbol]() + names.foreach { name => + buffer ++= tp.memberBasedOnFlags(name, required, excluded) + .alternatives.sortBy(_.signature)(Signature.lexicographicOrdering).map(_.symbol) + } + buffer.toList + } + /* * Quoting from JVMS 4.7.5 The Exceptions Attribute * "The Exceptions attribute indicates which checked exceptions a method may throw. diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index f5ca00ea7aa0..ec8e6b15c7cd 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -7,6 +7,7 @@ import scala.annotation.threadUnsafe import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.transform.SymUtils._ /** * This class mainly contains the method classBTypeFromSymbol, which extracts the necessary @@ -89,7 +90,22 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val superClass = if (superClassSym == NoSymbol) None else Some(classBTypeFromSymbol(superClassSym)) - val interfaces = symHelper(classSym).superInterfaces.map(classBTypeFromSymbol) + /** + * All interfaces implemented by a class, except for those inherited through the superclass. + * Redundant interfaces are removed unless there is a super call to them. + */ + def (sym: Symbol).superInterfaces: List[Symbol] = { + val directlyInheritedTraits = sym.directlyInheritedTraits + val directlyInheritedTraitsSet = directlyInheritedTraits.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) +// println(s"$fullName: adding supertraits $additional") + directlyInheritedTraits.filter(t => !allBaseClasses(t) || superCalls(t)) ++ additional + } + + val interfaces = classSym.superInterfaces.map(classBTypeFromSymbol) val flags = javaFlags(classSym) @@ -166,7 +182,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (!isNested) None else { // See comment in BTypes, when is a class marked static in the InnerClass table. - val isStaticNestedClass = symHelper(symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner + val isStaticNestedClass = symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.isOriginallyStaticOwner // After lambdalift (which is where we are), the rawowoner field contains the enclosing class. val enclosingClassSym = { @@ -184,6 +200,8 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { None } else { val outerName = symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.fullName.mangledString.replace('.', '/') + def dropModule(str: String): String = + if (!str.isEmpty && str.last == '$') str.take(str.length - 1) else str // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. val outerNameModule = if (symHelper(symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) @@ -204,6 +222,18 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { } } + /** + * This is basically a re-implementation of sym.isStaticOwner, but using the originalOwner chain. + * + * The problem is that we are interested in a source-level property. Various phases changed the + * symbol's properties in the meantime, mostly lambdalift modified (destructively) the owner. + * Therefore, `sym.isStatic` is not what we want. For example, in + * object T { def f { object U } } + * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. + */ + private def (sym: Symbol).isOriginallyStaticOwner: Boolean = + sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && symHelper(sym.originalOwner).originalLexicallyEnclosingClass.isOriginallyStaticOwner + /** * Return the Java modifiers for the given symbol. * Java modifiers for classes: diff --git a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala index c95f4a77389c..513e2d7f127e 100644 --- a/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala +++ b/compiler/src/dotty/tools/backend/jvm/BytecodeWriters.scala @@ -35,7 +35,7 @@ trait BytecodeWriters { def factoryNonJarBytecodeWriter(): BytecodeWriter = { val emitAsmp = None - val doDump = int.dumpClasses + val doDump = dumpClasses (emitAsmp.isDefined, doDump.isDefined) match { case (false, false) => new ClassBytecodeWriter { } case (false, true ) => new ClassBytecodeWriter with DumpBytecodeWriter { } @@ -116,7 +116,7 @@ trait BytecodeWriters { } trait DumpBytecodeWriter extends BytecodeWriter { - val baseDir = Directory(int.dumpClasses.get).createDirectory() + val baseDir = Directory(dumpClasses.get).createDirectory() abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], outfile: AbstractFile): Unit = { super.writeClass(label, jclassName, jclassBytes, outfile) @@ -130,4 +130,8 @@ trait BytecodeWriters { finally outstream.close() } } + + private def dumpClasses: Option[String] = + if (ctx.settings.Ydumpclasses.isDefault) None + else Some(ctx.settings.Ydumpclasses.value) } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index c34c61375c25..7cda076434b9 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -57,25 +57,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap val primitives = new DottyPrimitives(ctx) - def isRuntimeVisible(annot: Annotation): Boolean = - if (toDenot(annot.tree.tpe.typeSymbol).hasAnnotation(AnnotationRetentionAttr)) - retentionPolicyOf(annot) == AnnotationRetentionRuntimeAttr - else { - // SI-8926: if the annotation class symbol doesn't have a @RetentionPolicy annotation, the - // annotation is emitted with visibility `RUNTIME` - // dotty bug: #389 - true - } - - def shouldEmitAnnotation(annot: Annotation): Boolean = { - annot.symbol.is(Flags.JavaDefined) && - retentionPolicyOf(annot) != AnnotationRetentionSourceAttr - } - - private def retentionPolicyOf(annot: Annotation): Symbol = - annot.tree.tpe.typeSymbol.getAnnotation(AnnotationRetentionAttr). - flatMap(_.argumentConstant(0).map(_.symbolValue)).getOrElse(AnnotationRetentionClassAttr) - private def erasureString(clazz: Class[_]): String = { if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" else clazz.getName @@ -97,12 +78,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def sourcePos(pos: Spans.Span)(implicit ctx: Context): util.SourcePosition = ctx.source.atSpan(pos) - def dumpClasses: Option[String] = - if (ctx.settings.Ydumpclasses.isDefault) None - else Some(ctx.settings.Ydumpclasses.value) - - def debuglevel: Int = 3 // 0 -> no debug info; 1-> filename; 2-> lines; 3-> varnames - val perRunCaches: Caches = new Caches { def newAnyRefMap[K <: AnyRef, V](): mutable.AnyRefMap[K, V] = new mutable.AnyRefMap[K, V]() def newWeakMap[K, V](): mutable.WeakHashMap[K, V] = new mutable.WeakHashMap[K, V]() @@ -112,9 +87,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def newSet[K](): mutable.Set[K] = new mutable.HashSet[K] } - def dropModule(str: String): String = - if (!str.isEmpty && str.last == '$') str.take(str.length - 1) else str - private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] def desugarIdentBI(i: Ident): Option[tpd.Select] = { @@ -130,16 +102,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap if (found == null) None else Some(found) } - // todo: remove - def isMaybeBoxed(sym: Symbol): Boolean = { - (sym == defn.ObjectClass) || - (sym == defn.JavaSerializableClass) || - (sym == defn.ComparableClass) || - (sym derivesFrom defn.BoxedNumberClass) || - (sym derivesFrom defn.BoxedCharClass) || - (sym derivesFrom defn.BoxedBooleanClass) - } - // @M don't generate java generics sigs for (members of) implementation // classes, as they are monomorphic (TODO: ok?) private final def needsGenericSignature(sym: Symbol): Boolean = !( @@ -318,21 +280,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } else Nil - /** - * All interfaces implemented by a class, except for those inherited through the superclass. - * Redundant interfaces are removed unless there is a super call to them. - */ - def superInterfaces: List[Symbol] = { - val directlyInheritedTraits = decorateSymbol(sym).directlyInheritedTraits - val directlyInheritedTraitsSet = directlyInheritedTraits.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) -// println(s"$fullName: adding supertraits $additional") - directlyInheritedTraits.filter(t => !allBaseClasses(t) || superCalls(t)) ++ additional - } - /** * True for module classes of package level objects. The backend will generate a mirror class for * such objects. @@ -353,33 +300,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - - /** - * This is basically a re-implementation of sym.isStaticOwner, but using the originalOwner chain. - * - * The problem is that we are interested in a source-level property. Various phases changed the - * symbol's properties in the meantime, mostly lambdalift modified (destructively) the owner. - * Therefore, `sym.isStatic` is not what we want. For example, in - * object T { def f { object U } } - * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. - */ - def isOriginallyStaticOwner: Boolean = - sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && symHelper(symHelper(sym.originalOwner).originalLexicallyEnclosingClass).isOriginallyStaticOwner - } - - - /** The members of this type that have all of `required` flags but none of `excluded` flags set. - * The members are sorted by name and signature to guarantee a stable ordering. - */ - def sortedMembersBasedOnFlags(tp: Type, required: Flags.Flag, excluded: Flags.FlagSet): List[Symbol] = { - // The output of `memberNames` is a Set, sort it to guarantee a stable ordering. - val names = tp.memberNames(takeAllFilter).toSeq.sorted - val buffer = mutable.ListBuffer[Symbol]() - names.foreach { name => - buffer ++= tp.memberBasedOnFlags(name, required, excluded) - .alternatives.sortBy(_.signature)(Signature.lexicographicOrdering).map(_.symbol) - } - buffer.toList } object SelectBI extends DeconstructorCommon[tpd.Tree] { From c0e01e9c1b859658df2452a6774703a374e34cfd Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 09:34:43 +0200 Subject: [PATCH 60/98] Remove DottyBackendInterface.sourcePos --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 8 ++++---- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 4 +--- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index f9eb123c155f..38b88583e746 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -663,7 +663,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var elemKind = arr.elementType val argsSize = args.length if (argsSize > dims) { - ctx.error(s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)", sourcePos(app.span)) + ctx.error(s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)", app.sourcePos) } if (argsSize < dims) { /* In one step: diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index a99295a9607c..ce995bbee73c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -59,7 +59,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { outputDirectory } catch { case ex: Throwable => - ctx.error(s"Couldn't create file for class $cName\n${ex.getMessage}", sourcePos(csym.span)) + ctx.error(s"Couldn't create file for class $cName\n${ex.getMessage}", csym.sourcePos) null } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 91d3c9bee3ad..8439a7de038c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -403,7 +403,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val loc = Local(tk, sym.name.mangledString.toString, nxtIdx, sym.is(Flags.Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) - ctx.error("attempt to create duplicate local var.", sourcePos(sym.span)) + ctx.error("attempt to create duplicate local var.", sym.sourcePos) assert(tk.size > 0, "makeLocal called for a symbol whose type is Unit.") nxtIdx += tk.size loc @@ -453,7 +453,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } def lineNumber(tree: Tree): Unit = { if (!emitLines || !tree.span.exists) return; - val nr = sourcePos(tree.span).line + 1 + val nr = tree.sourcePos.line + 1 if (nr != lastEmittedLineNr) { lastEmittedLineNr = nr lastInsn match { @@ -556,7 +556,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { if (params.size > MaximumJvmParameters) { // SI-7324 - ctx.error(s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", sourcePos(methSymbol.span)) + ctx.error(s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", methSymbol.sourcePos) return } @@ -585,7 +585,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { ctx.error("Concrete method has no definition: " + dd + ( if (ctx.settings.Ydebug.value) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" else ""), - sourcePos(NoSpan) + ctx.source.atSpan(NoSpan) ) case _ => bc emitRETURN returnType diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 7cda076434b9..67680d67320b 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -75,8 +75,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap ctx.error(msg) throw new RuntimeException(msg) } - def sourcePos(pos: Spans.Span)(implicit ctx: Context): util.SourcePosition = - ctx.source.atSpan(pos) val perRunCaches: Caches = new Caches { def newAnyRefMap[K <: AnyRef, V](): mutable.AnyRefMap[K, V] = new mutable.AnyRefMap[K, V]() @@ -347,7 +345,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => - ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", sourcePos(field.span)) + ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", field.sourcePos) UnspecifiedErrorType } def _2: List[Tree] = field.elems From 60b220ead7941f3027f3ea6bc0415bd7e9d73c91 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 09:53:55 +0200 Subject: [PATCH 61/98] Remove DottyBackendInterface Symbol and type --- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 12 ++++++------ .../dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 1 + .../tools/backend/jvm/DottyBackendInterface.scala | 3 --- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index ce995bbee73c..1c0db4faeaa3 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -354,7 +354,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { av.visit(name, const.stringValue) // `stringValue` special-cases null, but that execution path isn't exercised for a const with StringTag case ClazzTag => av.visit(name, typeToTypeKind(const.typeValue)(bcodeStore)(innerClasesStore).toASMType) case EnumTag => - val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. + val edesc = innerClasesStore.typeDescriptor(const.tpe) // the class descriptor of the enumeration class. val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) } @@ -363,7 +363,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case Ident(nme.WILDCARD) => // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => - val edesc = innerClasesStore.typeDescriptor(t.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. + val edesc = innerClasesStore.typeDescriptor(t.tpe) // the class descriptor of the enumeration class. val evalue = t.symbol.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) case t: SeqLiteral => @@ -405,7 +405,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case t @ Apply(constr, args) if t.tpe.derivesFrom(JavaAnnotationClass) => val typ = t.tpe.classSymbol.denot.info val assocs = assocsFromApply(t) - val desc = innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the nested annotation class + val desc = innerClasesStore.typeDescriptor(typ) // the class descriptor of the nested annotation class val nestedVisitor = av.visitAnnotation(name, desc) emitAssocs(nestedVisitor, assocs, bcodeStore)(innerClasesStore) @@ -756,8 +756,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { def primitiveOrClassToBType(sym: Symbol): BType = { assert(sym.isClass, sym) assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) - primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], - storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] + primitiveTypeMap.getOrElse(sym, + storage.getClassBTypeAndRegisterInnerClass(sym)).asInstanceOf[BType] } /** @@ -809,7 +809,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { tp match { case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test - case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) + case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls) // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) case t: SingletonType => typeToTypeKind(t.underlying)(ct)(storage) case t: RefinedType => typeToTypeKind(t.parent)(ct)(storage) //parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b)) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 8439a7de038c..64faa3d71a77 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -16,6 +16,7 @@ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Types.Type import dotty.tools.dotc.util.Spans._ /* diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 67680d67320b..ceb12d96a56d 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -40,9 +40,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // they would be shadowed by the more deeply nested `symHelper` decorator. - type Symbol = Symbols.Symbol - type Type = Types.Type - // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") From 3d7dc450a6b3b68c9d3460d5d13a72868b74152b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 09:56:44 +0200 Subject: [PATCH 62/98] Inline method --- .../dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 12 +++++++++++- .../tools/backend/jvm/DottyBackendInterface.scala | 11 ----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 38b88583e746..f90ce8688b9c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1459,7 +1459,17 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc // TODO specialization val constrainedType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(lambdaTarget.info.resultType)).toASMType - val abstractMethod = symHelper(functionalInterface).samMethod() + + val abstractMethod = ctx.atPhase(ctx.erasurePhase) { + val samMethods = toDenot(functionalInterface).info.possibleSamMethods.toList + samMethods match { + case x :: Nil => x.symbol + case Nil => abort(s"${functionalInterface.show} is not a functional interface. It doesn't have abstract methods") + case xs => abort(s"${functionalInterface.show} is not a functional interface. " + + s"It has the following abstract methods: ${xs.map(_.name).mkString(", ")}") + } + } + val methodName = abstractMethod.name.mangledString val applyN = { val mt = asmMethodType(abstractMethod) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index ceb12d96a56d..64e56ccde6fc 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -284,17 +284,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap toDenot(sym).owner.is(Flags.PackageClass) } - - def samMethod(): Symbol = ctx.atPhase(ctx.erasurePhase) { - val samMethods = toDenot(sym).info.possibleSamMethods.toList - samMethods match { - case x :: Nil => x.symbol - case Nil => abort(s"${sym.show} is not a functional interface. It doesn't have abstract methods") - case xs => abort(s"${sym.show} is not a functional interface. " + - s"It has the following abstract methods: ${xs.map(_.name).mkString(", ")}") - } - } - } object SelectBI extends DeconstructorCommon[tpd.Tree] { From 579571631af4563264158174dfa74510f5eca40c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 10:30:54 +0200 Subject: [PATCH 63/98] Create symExtensions --- .../tools/backend/jvm/BCodeAsmCommon.scala | 11 +++--- .../tools/backend/jvm/BCodeBodyBuilder.scala | 17 ++++---- .../tools/backend/jvm/BCodeSkelBuilder.scala | 15 +++---- .../tools/backend/jvm/BTypesFromSymbols.scala | 21 +++++----- .../backend/jvm/DottyBackendInterface.scala | 39 +++++++++++-------- 5 files changed, 57 insertions(+), 46 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 82a0cfe803bd..cc5c96e67f5f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -11,6 +11,7 @@ import dotty.tools.dotc.core.Symbols._ */ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { import interface._ + import interface.symExtensions /** * True if `classSym` is an anonymous class or a local class. I.e., false if `classSym` is a @@ -24,7 +25,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { // always top-level. However, SI-8900 shows an example where the weak name-based implementation // of isDelambdafyFunction failed (for a function declared in a package named "lambda"). classSym.isAnonymousClass || { - val originalOwnerLexicallyEnclosingClass = symHelper(classSym.originalOwner).originalLexicallyEnclosingClass + val originalOwnerLexicallyEnclosingClass = classSym.originalOwner.originalLexicallyEnclosingClass originalOwnerLexicallyEnclosingClass != NoSymbol && !originalOwnerLexicallyEnclosingClass.isClass } } @@ -57,9 +58,9 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { def enclosingMethod(sym: Symbol): Option[Symbol] = { if (sym.isClass || sym == NoSymbol) None else if (sym.is(Flags.Method)) Some(sym) - else enclosingMethod(symHelper(sym.originalOwner).originalLexicallyEnclosingClass) + else enclosingMethod(sym.originalOwner.originalLexicallyEnclosingClass) } - enclosingMethod(symHelper(classSym.originalOwner).originalLexicallyEnclosingClass) + enclosingMethod(classSym.originalOwner.originalLexicallyEnclosingClass) } /** @@ -70,9 +71,9 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { assert(classSym.isClass, classSym) def enclosingClass(sym: Symbol): Symbol = { if (sym.isClass) sym - else enclosingClass(symHelper(sym.originalOwner).originalLexicallyEnclosingClass) + else enclosingClass(sym.originalOwner.originalLexicallyEnclosingClass) } - enclosingClass(symHelper(classSym.originalOwner).originalLexicallyEnclosingClass) + enclosingClass(classSym.originalOwner.originalLexicallyEnclosingClass) } /*final*/ case class EnclosingMethodEntry(owner: String, name: String, methodDescriptor: String) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index f90ce8688b9c..8aa0ae0da0a1 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -30,6 +30,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // import definitions._ import tpd._ import int._ + import int.symExtensions import bTypes._ import coreBTypes._ import BCodeBodyBuilder._ @@ -70,7 +71,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { tree match { case Assign(lhs @ SelectBI(qual, _), rhs) => - val isStatic = symHelper(lhs.symbol).isStaticMember + val isStatic = lhs.symbol.isStaticMember if (!isStatic) { genLoadQualifier(lhs) } genLoad(rhs, symInfoTK(lhs.symbol)) lineNumber(tree) @@ -331,7 +332,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t @ Ident(_) => (t, Nil) } - if (!symHelper(fun.symbol).isStaticMember) { + if (!fun.symbol.isStaticMember) { // load receiver of non-static implementation of lambda // darkdimius: I haven't found in spec `this` reference should go @@ -378,7 +379,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (sym.is(Flags.Module)) { genLoadQualUnlessElidable() genLoadModule(tree) - } else if (symHelper(sym).isStaticMember) { + } else if (sym.isStaticMember) { genLoadQualUnlessElidable() fieldLoad(sym, receiverClass) } else { @@ -466,7 +467,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner) val fieldJName = field.name.mangledString.toString val fieldDescr = symInfoTK(field).descriptor - val isStatic = symHelper(field).isStaticMember + val isStatic = field.isStaticMember val opc = if (isLoad) { if (isStatic) asm.Opcodes.GETSTATIC else asm.Opcodes.GETFIELD } else { if (isStatic) asm.Opcodes.PUTSTATIC else asm.Opcodes.PUTFIELD } @@ -702,7 +703,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (!isModuleInitialized && jMethodName == INSTANCE_CONSTRUCTOR_NAME && fun.symbol.name.mangledString.toString == INSTANCE_CONSTRUCTOR_NAME && - symHelper(claszSymbol).isStaticModuleClass) { + claszSymbol.isStaticModuleClass) { isModuleInitialized = true mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) mnode.visitFieldInsn( @@ -771,7 +772,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType = genPrimitiveOp(app, expectedType) } else { // normal method call val invokeStyle = - if (symHelper(sym).isStaticMember) InvokeStyle.Static + if (sym.isStaticMember) InvokeStyle.Static else if (sym.is(Flags.Private) || sym.isClassConstructor) InvokeStyle.Special else InvokeStyle.Virtual @@ -1039,7 +1040,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genLoadModule(module: Symbol): Unit = { - def inStaticMethod = methSymbol != null && symHelper(methSymbol).isStaticMember + def inStaticMethod = methSymbol != null && methSymbol.isStaticMember if (claszSymbol == module.moduleClass && jMethodName != "readResolve" && !inStaticMethod) { mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) } else { @@ -1436,7 +1437,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val isSerializable = functionalInterface.isSerializable || defn.isFunctionClass(functionalInterface) val isInterface = symHelper(lambdaTarget.owner).isEmittedInterface val invokeStyle = - if (symHelper(lambdaTarget).isStaticMember) asm.Opcodes.H_INVOKESTATIC + if (lambdaTarget.isStaticMember) asm.Opcodes.H_INVOKESTATIC else if (lambdaTarget.is(Flags.Private) || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL else if (isInterface) asm.Opcodes.H_INVOKEINTERFACE else asm.Opcodes.H_INVOKEVIRTUAL diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 64faa3d71a77..779888222909 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -27,6 +27,7 @@ import dotty.tools.dotc.util.Spans._ */ trait BCodeSkelBuilder extends BCodeHelpers { import int._ + import int.symExtensions import tpd._ import bTypes._ import coreBTypes._ @@ -96,7 +97,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { claszSymbol = cd.symbol isCZParcelable = isAndroidParcelableClass(claszSymbol) - isCZStaticModule = symHelper(claszSymbol).isStaticModuleClass + isCZStaticModule = claszSymbol.isStaticModuleClass thisName = internalName(claszSymbol) cnode = new ClassNode1() @@ -104,7 +105,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { initJClass(cnode) val methodSymbols = for (f <- cd.symbol.info.decls.toList if f.is(Flags.Method) && f.isTerm && !f.is(Flags.Module)) yield f - val hasStaticCtor = methodSymbols exists (symHelper(_).isStaticConstructor) + val hasStaticCtor = methodSymbols exists (_.isStaticConstructor) if (!hasStaticCtor) { // but needs one ... if (isCZStaticModule || isCZParcelable) { @@ -181,7 +182,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } else { - val skipStaticForwarders = (symHelper(claszSymbol).isInterface || claszSymbol.is(Flags.Module) || ctx.settings.XnoForwarders.value) + val skipStaticForwarders = (claszSymbol.isInterface || claszSymbol.is(Flags.Module) || ctx.settings.XnoForwarders.value) if (!skipStaticForwarders) { val lmoc = claszSymbol.companionModule // add static forwarders if there are no name conflicts; see bugs #363 and #1735 @@ -255,7 +256,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val javagensig = getGenericSignature(f, claszSymbol) val flags = javaFieldFlags(f) - assert(!symHelper(f).isStaticMember || !symHelper(claszSymbol).isInterface || !f.is(Flags.Mutable), + assert(!f.isStaticMember || !claszSymbol.isInterface || !f.is(Flags.Mutable), s"interface $claszSymbol cannot have non-final static field $f") val jfield = new asm.tree.FieldNode( @@ -470,7 +471,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // on entering a method def resetMethodBookkeeping(dd: DefDef) = { val rhs = dd.rhs - locals.reset(isStaticMethod = symHelper(methSymbol).isStaticMember) + locals.reset(isStaticMethod = methSymbol.isStaticMember) jumpDest = immutable.Map.empty[ /* LabelDef */ Symbol, asm.Label ] // check previous invocation of genDefDef exited as many varsInScope as it entered. @@ -544,7 +545,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { methSymbol = dd.symbol jMethodName = methSymbol.name.mangledString.toString returnType = asmMethodType(dd.symbol).returnType - isMethSymStaticCtor = symHelper(methSymbol).isStaticConstructor + isMethSymStaticCtor = methSymbol.isStaticConstructor resetMethodBookkeeping(dd) @@ -562,7 +563,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } val isNative = methSymbol.hasAnnotation(NativeAttr) - val isAbstractMethod = (methSymbol.is(Flags.Deferred) || (symHelper(methSymbol.owner).isInterface && ((methSymbol.is(Flags.Deferred)) || methSymbol.isClassConstructor))) + val isAbstractMethod = (methSymbol.is(Flags.Deferred) || (methSymbol.owner.isInterface && ((methSymbol.is(Flags.Deferred)) || methSymbol.isClassConstructor))) val flags = GenBCodeOps.mkFlags( javaFlags(methSymbol), if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0, diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index ec8e6b15c7cd..09eb0e8c48b2 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -23,6 +23,7 @@ import dotty.tools.dotc.transform.SymUtils._ */ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { import int._ + import int.symExtensions val bCodeAsmCommon: BCodeAsmCommon[int.type ] = new BCodeAsmCommon(int) import bCodeAsmCommon._ @@ -80,11 +81,11 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { assert( if (classSym == defn.ObjectClass) superClassSym == NoSymbol - else if (symHelper(classSym).isInterface) + else if (classSym.isInterface) superClassSym == defn.ObjectClass else // A ClassBType for a primitive class (scala.Boolean et al) is only created when compiling these classes. - ((superClassSym != NoSymbol) && !symHelper(superClassSym).isInterface) || (isCompilingPrimitive && primitiveTypeMap.contains(classSym)), + ((superClassSym != NoSymbol) && !superClassSym.isInterface) || (isCompilingPrimitive && primitiveTypeMap.contains(classSym)), s"Bad superClass for $classSym: $superClassSym" ) val superClass = if (superClassSym == NoSymbol) None @@ -178,11 +179,11 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { assert(innerClassSym.isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") - val isNested = !symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.is(Flags.PackageClass) + val isNested = !innerClassSym.originalOwner.originalLexicallyEnclosingClass.is(Flags.PackageClass) if (!isNested) None else { // See comment in BTypes, when is a class marked static in the InnerClass table. - val isStaticNestedClass = symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.isOriginallyStaticOwner + val isStaticNestedClass = innerClassSym.originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner // After lambdalift (which is where we are), the rawowoner field contains the enclosing class. val enclosingClassSym = { @@ -199,12 +200,12 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (isAnonymousOrLocalClass(innerClassSym)) { None } else { - val outerName = symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass.fullName.mangledString.replace('.', '/') + val outerName = innerClassSym.originalOwner.originalLexicallyEnclosingClass.fullName.mangledString.replace('.', '/') def dropModule(str: String): String = if (!str.isEmpty && str.last == '$') str.take(str.length - 1) else str // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. val outerNameModule = - if (symHelper(symHelper(innerClassSym.originalOwner).originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) + if (symHelper(innerClassSym.originalOwner.originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) else outerName Some(outerNameModule.toString) } @@ -232,7 +233,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. */ private def (sym: Symbol).isOriginallyStaticOwner: Boolean = - sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && symHelper(sym.originalOwner).originalLexicallyEnclosingClass.isOriginallyStaticOwner + sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && sym.originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner /** * Return the Java modifiers for the given symbol. @@ -263,7 +264,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { GenBCodeOps.mkFlags( if (privateFlag) ACC_PRIVATE else ACC_PUBLIC, if (sym.is(Flags.Deferred) || sym.isOneOf(Flags.AbstractOrTrait)) ACC_ABSTRACT else 0, - if (symHelper(sym).isInterface) ACC_INTERFACE else 0, + if (sym.isInterface) ACC_INTERFACE else 0, if (finalFlag && // Primitives are "abstract final" to prohibit instantiation @@ -274,10 +275,10 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks !sym.is(Flags.Bridge)) ACC_FINAL else 0, - if (symHelper(sym).isStaticMember) ACC_STATIC else 0, + if (sym.isStaticMember) ACC_STATIC else 0, if (sym.is(Flags.Bridge)) ACC_BRIDGE | ACC_SYNTHETIC else 0, if (sym.is(Flags.Artifact)) ACC_SYNTHETIC else 0, - if (sym.isClass && !symHelper(sym).isInterface) ACC_SUPER else 0, + if (sym.isClass && !sym.isInterface) ACC_SUPER else 0, if (sym.isAllOf(Flags.JavaEnumTrait)) ACC_ENUM else 0, if (sym.is(Flags.JavaVarargs)) ACC_VARARGS else 0, if (sym.is(Flags.Synchronized)) ACC_SYNCHRONIZED else 0, diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 64e56ccde6fc..c76da8459a91 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -205,22 +205,11 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper(sym) - - class SymbolHelper(sym: Symbol) { + extension symExtensions on (sym: Symbol) { - // tests - def isPublic: Boolean = !sym.flags.isOneOf(Flags.Private | Flags.Protected) def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) - /** Does this symbol actually correspond to an interface that will be emitted? - * In the backend, this should be preferred over `isInterface` because it - * also returns true for the symbols of the fake companion objects we - * create for Java-defined classes as well as for Java annotations - * which we represent as classes. - */ - def isEmittedInterface: Boolean = isInterface || - sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.companionClass.is(Flags.PureInterface)) || sym.companionClass.is(Flags.Trait)) + def isStaticConstructor: Boolean = (sym.isStaticMember && sym.isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) def isStaticMember: Boolean = (sym ne NoSymbol) && (sym.is(Flags.JavaStatic) || sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)) @@ -241,11 +230,8 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap toDenot(sym)(shiftedContext).isStatic(shiftedContext) } - def isStaticConstructor: Boolean = (isStaticMember && sym.isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) - // navigation - def originalLexicallyEnclosingClass: Symbol = // used to populate the EnclosingMethod attribute. // it is very tricky in presence of classes(and annonymous classes) defined inside supper calls. @@ -255,6 +241,27 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap toDenot(sym)(shiftedContext).lexicallyEnclosingClass(shiftedContext) } else NoSymbol + } + + def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper(sym) + + class SymbolHelper(sym: Symbol) { + + // tests + + /** Does this symbol actually correspond to an interface that will be emitted? + * In the backend, this should be preferred over `isInterface` because it + * also returns true for the symbols of the fake companion objects we + * create for Java-defined classes as well as for Java annotations + * which we represent as classes. + */ + def isEmittedInterface: Boolean = sym.isInterface || + sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.companionClass.is(Flags.PureInterface)) || sym.companionClass.is(Flags.Trait)) + + + + // navigation + // members /** For currently compiled classes: All locally defined classes including local classes. From 266a7c50d71cbd81a69da91a2662fc39f4e8dcee Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 10:33:49 +0200 Subject: [PATCH 64/98] Move method --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 16 +++++++++++++--- .../backend/jvm/DottyBackendInterface.scala | 10 ---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 8aa0ae0da0a1..fd947010ed9d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1144,7 +1144,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val isTraitMethodOverridingObjectMember = { receiver != methodOwner && // fast path - the boolean is used to pick either of these two, if they are the same it does not matter style.isVirtual && - symHelper(receiver).isEmittedInterface && + isEmittedInterface(receiver) && defn.ObjectType.decl(method.name).symbol.exists && { // fast path - compute overrideChain on the next line only if necessary val syms = method.allOverriddenSymbols.toList !syms.isEmpty && syms.last.owner == defn.ObjectClass @@ -1160,7 +1160,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val bmType = asmMethodType(method) val mdescr = bmType.descriptor - val isInterface = symHelper(receiverClass).isEmittedInterface + val isInterface = isEmittedInterface(receiverClass) import InvokeStyle._ if (style == Super) { // DOTTY: this differ from how super-calls in traits are handled in the scalac backend, @@ -1435,7 +1435,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // Lambdas should be serializable if they implement a SAM that extends Serializable or if they // implement a scala.Function* class. val isSerializable = functionalInterface.isSerializable || defn.isFunctionClass(functionalInterface) - val isInterface = symHelper(lambdaTarget.owner).isEmittedInterface + val isInterface = isEmittedInterface(lambdaTarget.owner) val invokeStyle = if (lambdaTarget.isStaticMember) asm.Opcodes.H_INVOKESTATIC else if (lambdaTarget.is(Flags.Private) || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL @@ -1494,6 +1494,16 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType } } + + /** Does this symbol actually correspond to an interface that will be emitted? + * In the backend, this should be preferred over `isInterface` because it + * also returns true for the symbols of the fake companion objects we + * create for Java-defined classes as well as for Java annotations + * which we represent as classes. + */ + private def isEmittedInterface(sym: Symbol): Boolean = sym.isInterface || + sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.companionClass.is(Flags.PureInterface)) || sym.companionClass.is(Flags.Trait)) + } object BCodeBodyBuilder { diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index c76da8459a91..d55e880a7de5 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -249,16 +249,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // tests - /** Does this symbol actually correspond to an interface that will be emitted? - * In the backend, this should be preferred over `isInterface` because it - * also returns true for the symbols of the fake companion objects we - * create for Java-defined classes as well as for Java annotations - * which we represent as classes. - */ - def isEmittedInterface: Boolean = sym.isInterface || - sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.companionClass.is(Flags.PureInterface)) || sym.companionClass.is(Flags.Trait)) - - // navigation From 504adde925e5ab64d45d56c3a4eb62c2f448aab9 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 10:40:08 +0200 Subject: [PATCH 65/98] Make method an extension --- .../tools/backend/jvm/BTypesFromSymbols.scala | 6 ++--- .../backend/jvm/DottyBackendInterface.scala | 26 +++++++------------ .../dotty/tools/backend/jvm/GenBCode.scala | 3 ++- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 09eb0e8c48b2..a35179b8d110 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -143,7 +143,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val companionModuleMembers = { // phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes, // not local classes of the companion module (E in the example) that were lifted by lambdalift. - if (symHelper(classSym.linkedClass).isTopLevelModuleClass) /*exitingPickler*/ symHelper(classSym.linkedClass).memberClasses + if (classSym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ symHelper(classSym.linkedClass).memberClasses else Nil } @@ -205,7 +205,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (!str.isEmpty && str.last == '$') str.take(str.length - 1) else str // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. val outerNameModule = - if (symHelper(innerClassSym.originalOwner.originalLexicallyEnclosingClass).isTopLevelModuleClass) dropModule(outerName) + if (innerClassSym.originalOwner.originalLexicallyEnclosingClass.isTopLevelModuleClass) dropModule(outerName) else outerName Some(outerNameModule.toString) } @@ -256,7 +256,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { final def javaFlags(sym: Symbol): Int = { - val privateFlag = sym.is(Flags.Private) || (sym.isPrimaryConstructor && symHelper(sym.owner).isTopLevelModuleClass) + val privateFlag = sym.is(Flags.Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) val finalFlag = sym.is(Flags.Final) && !toDenot(sym).isClassConstructor && !(sym.is(Flags.Mutable)) && !(sym.enclosingClass.is(Flags.Trait)) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index d55e880a7de5..b3d18e2fb534 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -241,19 +241,22 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap toDenot(sym)(shiftedContext).lexicallyEnclosingClass(shiftedContext) } else NoSymbol + /** + * True for module classes of package level objects. The backend will generate a mirror class for + * such objects. + */ + def isTopLevelModuleClass: Boolean = + sym.is(Flags.ModuleClass) && + ctx.atPhase(ctx.flattenPhase) { + toDenot(sym).owner.is(Flags.PackageClass) + } + } def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper(sym) class SymbolHelper(sym: Symbol) { - // tests - - - // navigation - - // members - /** For currently compiled classes: All locally defined classes including local classes. * The empty list for classes that are not currently compiled. @@ -272,15 +275,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } else Nil - /** - * True for module classes of package level objects. The backend will generate a mirror class for - * such objects. - */ - def isTopLevelModuleClass: Boolean = sym.is(Flags.ModuleClass) && - ctx.atPhase(ctx.flattenPhase) { - toDenot(sym).owner.is(Flags.PackageClass) - } - } object SelectBI extends DeconstructorCommon[tpd.Tree] { diff --git a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala index 5b2eb865e693..f46ccc41861d 100644 --- a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala @@ -70,6 +70,7 @@ object GenBCode { } class GenBCodePipeline(val int: DottyBackendInterface)(implicit ctx: Context) extends BCodeSyncAndTry { + import int.symExtensions private var tree: Tree = _ @@ -203,7 +204,7 @@ class GenBCodePipeline(val int: DottyBackendInterface)(implicit ctx: Context) ex // -------------- mirror class, if needed -------------- val mirrorC = - if (int.symHelper(claszSymbol).isTopLevelModuleClass) { + if (claszSymbol.isTopLevelModuleClass) { if (claszSymbol.companionClass == NoSymbol) { mirrorCodeGen.genMirrorClass(claszSymbol, cunit) } else { From 3a0dbdab1b21ef7af05831b11b4677ed33eb97bf Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 10:40:45 +0200 Subject: [PATCH 66/98] Revert "Remove DottyBackendInterface Symbol and type" This reverts commit 60b220ead7941f3027f3ea6bc0415bd7e9d73c91. --- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 12 ++++++------ .../dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 1 - .../tools/backend/jvm/DottyBackendInterface.scala | 3 +++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 1c0db4faeaa3..ce995bbee73c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -354,7 +354,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { av.visit(name, const.stringValue) // `stringValue` special-cases null, but that execution path isn't exercised for a const with StringTag case ClazzTag => av.visit(name, typeToTypeKind(const.typeValue)(bcodeStore)(innerClasesStore).toASMType) case EnumTag => - val edesc = innerClasesStore.typeDescriptor(const.tpe) // the class descriptor of the enumeration class. + val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) } @@ -363,7 +363,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case Ident(nme.WILDCARD) => // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => - val edesc = innerClasesStore.typeDescriptor(t.tpe) // the class descriptor of the enumeration class. + 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) case t: SeqLiteral => @@ -405,7 +405,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case t @ Apply(constr, args) if t.tpe.derivesFrom(JavaAnnotationClass) => val typ = t.tpe.classSymbol.denot.info val assocs = assocsFromApply(t) - val desc = innerClasesStore.typeDescriptor(typ) // the class descriptor of the nested annotation class + val desc = innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the nested annotation class val nestedVisitor = av.visitAnnotation(name, desc) emitAssocs(nestedVisitor, assocs, bcodeStore)(innerClasesStore) @@ -756,8 +756,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { def primitiveOrClassToBType(sym: Symbol): BType = { assert(sym.isClass, sym) assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) - primitiveTypeMap.getOrElse(sym, - storage.getClassBTypeAndRegisterInnerClass(sym)).asInstanceOf[BType] + primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], + storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] } /** @@ -809,7 +809,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { tp match { case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test - case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls) + case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) case t: SingletonType => typeToTypeKind(t.underlying)(ct)(storage) case t: RefinedType => typeToTypeKind(t.parent)(ct)(storage) //parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b)) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 779888222909..6e15c07a14ac 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -16,7 +16,6 @@ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.core.Types.Type import dotty.tools.dotc.util.Spans._ /* diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index b3d18e2fb534..86f245a09e66 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -40,6 +40,9 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // they would be shadowed by the more deeply nested `symHelper` decorator. + type Symbol = Symbols.Symbol + type Type = Types.Type + // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") From 1c4af733b6e05708e186b5907995e2023e6ea4c7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 10:43:22 +0200 Subject: [PATCH 67/98] Revert "Remove DottyBackendInterface.sourcePos" This reverts commit c0e01e9c1b859658df2452a6774703a374e34cfd. --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 8 ++++---- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 4 +++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index fd947010ed9d..2d01f3c4d73b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -664,7 +664,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var elemKind = arr.elementType val argsSize = args.length if (argsSize > dims) { - ctx.error(s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)", app.sourcePos) + ctx.error(s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)", sourcePos(app.span)) } if (argsSize < dims) { /* In one step: diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index ce995bbee73c..a99295a9607c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -59,7 +59,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { outputDirectory } catch { case ex: Throwable => - ctx.error(s"Couldn't create file for class $cName\n${ex.getMessage}", csym.sourcePos) + ctx.error(s"Couldn't create file for class $cName\n${ex.getMessage}", sourcePos(csym.span)) null } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 6e15c07a14ac..c87e90b25872 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -404,7 +404,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val loc = Local(tk, sym.name.mangledString.toString, nxtIdx, sym.is(Flags.Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) - ctx.error("attempt to create duplicate local var.", sym.sourcePos) + ctx.error("attempt to create duplicate local var.", sourcePos(sym.span)) assert(tk.size > 0, "makeLocal called for a symbol whose type is Unit.") nxtIdx += tk.size loc @@ -454,7 +454,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } def lineNumber(tree: Tree): Unit = { if (!emitLines || !tree.span.exists) return; - val nr = tree.sourcePos.line + 1 + val nr = sourcePos(tree.span).line + 1 if (nr != lastEmittedLineNr) { lastEmittedLineNr = nr lastInsn match { @@ -557,7 +557,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { if (params.size > MaximumJvmParameters) { // SI-7324 - ctx.error(s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", methSymbol.sourcePos) + ctx.error(s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", sourcePos(methSymbol.span)) return } @@ -586,7 +586,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { ctx.error("Concrete method has no definition: " + dd + ( if (ctx.settings.Ydebug.value) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" else ""), - ctx.source.atSpan(NoSpan) + sourcePos(NoSpan) ) case _ => bc emitRETURN returnType diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 86f245a09e66..e0ad0cea8f1a 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -75,6 +75,8 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap ctx.error(msg) throw new RuntimeException(msg) } + def sourcePos(pos: Spans.Span)(implicit ctx: Context): util.SourcePosition = + ctx.source.atSpan(pos) val perRunCaches: Caches = new Caches { def newAnyRefMap[K <: AnyRef, V](): mutable.AnyRefMap[K, V] = new mutable.AnyRefMap[K, V]() @@ -325,7 +327,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => - ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", field.sourcePos) + ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", sourcePos(field.span)) UnspecifiedErrorType } def _2: List[Tree] = field.elems From c1c8e45eda012bcecaee85a829f2faf21a65537f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 10:44:22 +0200 Subject: [PATCH 68/98] Revert "Revert "Remove DottyBackendInterface Symbol and type"" This reverts commit 3a0dbdab1b21ef7af05831b11b4677ed33eb97bf. --- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 12 ++++++------ .../dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 1 + .../tools/backend/jvm/DottyBackendInterface.scala | 3 --- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index a99295a9607c..b61ab9f54180 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -354,7 +354,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { av.visit(name, const.stringValue) // `stringValue` special-cases null, but that execution path isn't exercised for a const with StringTag case ClazzTag => av.visit(name, typeToTypeKind(const.typeValue)(bcodeStore)(innerClasesStore).toASMType) case EnumTag => - val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. + val edesc = innerClasesStore.typeDescriptor(const.tpe) // the class descriptor of the enumeration class. val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) } @@ -363,7 +363,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case Ident(nme.WILDCARD) => // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => - val edesc = innerClasesStore.typeDescriptor(t.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. + val edesc = innerClasesStore.typeDescriptor(t.tpe) // the class descriptor of the enumeration class. val evalue = t.symbol.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) case t: SeqLiteral => @@ -405,7 +405,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case t @ Apply(constr, args) if t.tpe.derivesFrom(JavaAnnotationClass) => val typ = t.tpe.classSymbol.denot.info val assocs = assocsFromApply(t) - val desc = innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the nested annotation class + val desc = innerClasesStore.typeDescriptor(typ) // the class descriptor of the nested annotation class val nestedVisitor = av.visitAnnotation(name, desc) emitAssocs(nestedVisitor, assocs, bcodeStore)(innerClasesStore) @@ -756,8 +756,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { def primitiveOrClassToBType(sym: Symbol): BType = { assert(sym.isClass, sym) assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) - primitiveTypeMap.getOrElse(sym.asInstanceOf[ct.bTypes.coreBTypes.bTypes.int.Symbol], - storage.getClassBTypeAndRegisterInnerClass(sym.asInstanceOf[ct.int.Symbol])).asInstanceOf[BType] + primitiveTypeMap.getOrElse(sym, + storage.getClassBTypeAndRegisterInnerClass(sym)).asInstanceOf[BType] } /** @@ -809,7 +809,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { tp match { case tp: ThisType if tp.cls == defn.ArrayClass => ObjectReference.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test - case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls.asInstanceOf[ct.int.Symbol]) + case tp: ThisType => storage.getClassBTypeAndRegisterInnerClass(tp.cls) // case t: SingletonType => primitiveOrClassToBType(t.classSymbol) case t: SingletonType => typeToTypeKind(t.underlying)(ct)(storage) case t: RefinedType => typeToTypeKind(t.parent)(ct)(storage) //parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b)) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index c87e90b25872..774adc03996c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -16,6 +16,7 @@ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Types.Type import dotty.tools.dotc.util.Spans._ /* diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index e0ad0cea8f1a..319dde2d9167 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -40,9 +40,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // they would be shadowed by the more deeply nested `symHelper` decorator. - type Symbol = Symbols.Symbol - type Type = Types.Type - // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") From 1b196c9f9183523285715b305c1959a9bc0cdf3e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 10:54:17 +0200 Subject: [PATCH 69/98] Move methods --- .../tools/backend/jvm/BCodeHelpers.scala | 13 +++++++ .../tools/backend/jvm/BTypesFromSymbols.scala | 21 +++++++++- .../backend/jvm/DottyBackendInterface.scala | 39 ------------------- 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index b61ab9f54180..6a7d84474067 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -434,6 +434,19 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { annot.tree.tpe.typeSymbol.getAnnotation(AnnotationRetentionAttr). flatMap(_.argumentConstant(0).map(_.symbolValue)).getOrElse(AnnotationRetentionClassAttr) + private def assocsFromApply(tree: Tree): List[(Name, Tree)] = { + tree match { + case Block(_, expr) => assocsFromApply(expr) + case Apply(fun, args) => + fun.tpe.widen match { + case MethodType(names) => + (names zip args).filter { + case (_, t: tpd.Ident) if (t.tpe.normalizedPrefix eq NoPrefix) => false + case _ => true + } + } + } + } } // end of trait BCAnnotGen trait BCJGenSigGen { diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index a35179b8d110..b2eda326a857 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -7,6 +7,7 @@ import scala.annotation.threadUnsafe import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Phases.Phase import dotty.tools.dotc.transform.SymUtils._ /** @@ -125,7 +126,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // The lambdalift phase lifts all nested classes to the enclosing class, so if we collect // member classes right after lambdalift, we obtain all nested classes, including local and // anonymous ones. - val nestedClasses = symHelper(classSym).nestedClasses + val nestedClasses = getNestedClasses(classSym) // If this is a top-level class, and it has a companion object, the member classes of the // companion are added as members of the class. For example: @@ -143,7 +144,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val companionModuleMembers = { // phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes, // not local classes of the companion module (E in the example) that were lifted by lambdalift. - if (classSym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ symHelper(classSym.linkedClass).memberClasses + if (classSym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ getMemberClasses(classSym.linkedClass) else Nil } @@ -175,6 +176,22 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { classBType } + /** For currently compiled classes: All locally defined classes including local classes. + * The empty list for classes that are not currently compiled. + */ + private def getNestedClasses(sym: Symbol): List[Symbol] = definedClasses(sym, ctx.flattenPhase) + + /** For currently compiled classes: All classes that are declared as members of this class + * (but not inherited ones). The empty list for classes that are not currently compiled. + */ + private def getMemberClasses(sym: Symbol): List[Symbol] = definedClasses(sym, ctx.lambdaLiftPhase) + + private def definedClasses(sym: Symbol, phase: Phase) = + if (sym.isDefinedInCurrentRun) + ctx.atPhase(phase) { + toDenot(sym).info.decls.filter(_.isClass) + } + else Nil private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { assert(innerClassSym.isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 319dde2d9167..c0e1c728fc02 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -192,21 +192,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap None } - - def assocsFromApply(tree: Tree): List[(Name, Tree)] = { - tree match { - case Block(_, expr) => assocsFromApply(expr) - case Apply(fun, args) => - fun.tpe.widen match { - case MethodType(names) => - (names zip args).filter { - case (_, t: tpd.Ident) if (t.tpe.normalizedPrefix eq NoPrefix) => false - case _ => true - } - } - } - } - extension symExtensions on (sym: Symbol) { def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) @@ -255,30 +240,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } - def symHelper(sym: Symbol): SymbolHelper = new SymbolHelper(sym) - - class SymbolHelper(sym: Symbol) { - - /** For currently compiled classes: All locally defined classes including local classes. - * The empty list for classes that are not currently compiled. - - */ - def nestedClasses: List[Symbol] = definedClasses(ctx.flattenPhase) - - /** For currently compiled classes: All classes that are declared as members of this class - * (but not inherited ones). The empty list for classes that are not currently compiled. - */ - def memberClasses: List[Symbol] = definedClasses(ctx.lambdaLiftPhase) - - private def definedClasses(phase: Phase) = - if (sym.isDefinedInCurrentRun) - ctx.atPhase(phase) { - toDenot(sym).info.decls.filter(_.isClass) - } - else Nil - - } - object SelectBI extends DeconstructorCommon[tpd.Tree] { var desugared: tpd.Select = null From 043e390007706fcf08c3067355f32b5acb0754c9 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 11:10:54 +0200 Subject: [PATCH 70/98] Move code --- .../tools/backend/jvm/BCodeHelpers.scala | 100 +++++++++++++++++- .../backend/jvm/DottyBackendInterface.scala | 93 ---------------- 2 files changed, 95 insertions(+), 98 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 6a7d84474067..6c958dfc3161 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -13,6 +13,7 @@ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.ast.Trees import dotty.tools.dotc.core.Annotations.Annotation import dotty.tools.dotc.core.Constants._ +import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Names.Name @@ -22,6 +23,8 @@ import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types import dotty.tools.dotc.core.Types._ +import dotty.tools.dotc.core.TypeErasure +import dotty.tools.dotc.transform.GenericSignatures /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -450,16 +453,27 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } // end of trait BCAnnotGen trait BCJGenSigGen { + import int._ def getCurrentCUnit(): CompilationUnit - /* @return - * - `null` if no Java signature is to be added (`null` is what ASM expects in these cases). - * - otherwise the signature in question + /** + * Generates the generic signature for `sym` before erasure. * - * must-single-thread + * @param sym The symbol for which to generate a signature. + * @param owner The owner of `sym`. + * @return The generic signature of `sym` before erasure, as specified in the Java Virtual + * Machine Specification, §4.3.4, or `null` if `sym` doesn't need a generic signature. + * @see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.4 */ - def getGenericSignature(sym: Symbol, owner: Symbol): String = int.getGenericSignature(sym, owner) + def getGenericSignature(sym: Symbol, owner: Symbol): String = { + ctx.atPhase(ctx.erasurePhase) { + val memberTpe = + if (sym.is(Flags.Method)) sym.denot.info + else owner.denot.thisType.memberInfo(sym) + getGenericSignatureHelper(sym, owner, memberTpe).orNull + } + } } // end of trait BCJGenSigGen @@ -829,6 +843,82 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } } } + + private def getGenericSignatureHelper(sym: Symbol, owner: Symbol, memberTpe: Type)(implicit ctx: Context): Option[String] = { + if (needsGenericSignature(sym)) { + val erasedTypeSym = TypeErasure.fullErasure(sym.denot.info).typeSymbol + if (erasedTypeSym.isPrimitiveValueClass) { + // Suppress signatures for symbols whose types erase in the end to primitive + // value types. This is needed to fix #7416. + None + } else { + val jsOpt = GenericSignatures.javaSig(sym, memberTpe) + if (ctx.settings.XverifySignatures.value) { + jsOpt.foreach(verifySignature(sym, _)) + } + + jsOpt + } + } else { + None + } + } + + private def verifySignature(sym: Symbol, sig: String)(implicit ctx: Context): Unit = { + import scala.tools.asm.util.CheckClassAdapter + def wrap(body: => Unit): Unit = { + try body + catch { + case ex: Throwable => + ctx.error(i"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName} + |signature: $sig + |if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues + """.trim, sym.sourcePos) + throw ex + } + } + + wrap { + if (sym.is(Flags.Method)) { + CheckClassAdapter.checkMethodSignature(sig) + } + else if (sym.isTerm) { + CheckClassAdapter.checkFieldSignature(sig) + } + else { + CheckClassAdapter.checkClassSignature(sig) + } + } + } + + // @M don't generate java generics sigs for (members of) implementation + // classes, as they are monomorphic (TODO: ok?) + private final def needsGenericSignature(sym: Symbol): Boolean = !( + // pp: this condition used to include sym.hasexpandedname, but this leads + // to the total loss of generic information if a private member is + // accessed from a closure: both the field and the accessor were generated + // without it. This is particularly bad because the availability of + // generic information could disappear as a consequence of a seemingly + // unrelated change. + ctx.base.settings.YnoGenericSig.value + || sym.is(Flags.Artifact) + || sym.isAllOf(Flags.LiftedMethod) + || sym.is(Flags.Bridge) + ) + + private def getStaticForwarderGenericSignature(sym: Symbol, moduleClass: Symbol): String = { + // scala/bug#3452 Static forwarder generation uses the same erased signature as the method if forwards to. + // By rights, it should use the signature as-seen-from the module class, and add suitable + // primitive and value-class boxing/unboxing. + // But for now, just like we did in mixin, we just avoid writing a wrong generic signature + // (one that doesn't erase to the actual signature). See run/t3452b for a test case. + + val memberTpe = ctx.atPhase(ctx.erasurePhase) { moduleClass.denot.thisType.memberInfo(sym) } + val erasedMemberType = TypeErasure.erasure(memberTpe) + if (erasedMemberType =:= sym.denot.info) + getGenericSignatureHelper(sym, moduleClass, memberTpe).orNull + else null + } } object BCodeHelpers { diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index c0e1c728fc02..8dd2c2b0073c 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -99,99 +99,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap if (found == null) None else Some(found) } - // @M don't generate java generics sigs for (members of) implementation - // classes, as they are monomorphic (TODO: ok?) - private final def needsGenericSignature(sym: Symbol): Boolean = !( - // pp: this condition used to include sym.hasexpandedname, but this leads - // to the total loss of generic information if a private member is - // accessed from a closure: both the field and the accessor were generated - // without it. This is particularly bad because the availability of - // generic information could disappear as a consequence of a seemingly - // unrelated change. - ctx.base.settings.YnoGenericSig.value - || sym.is(Flags.Artifact) - || sym.isAllOf(Flags.LiftedMethod) - || sym.is(Flags.Bridge) - ) - - private def verifySignature(sym: Symbol, sig: String)(implicit ctx: Context): Unit = { - import scala.tools.asm.util.CheckClassAdapter - def wrap(body: => Unit): Unit = { - try body - catch { - case ex: Throwable => - ctx.error(i"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName} - |signature: $sig - |if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues - """.trim, sym.sourcePos) - throw ex - } - } - - wrap { - if (sym.is(Flags.Method)) { - CheckClassAdapter.checkMethodSignature(sig) - } - else if (sym.isTerm) { - CheckClassAdapter.checkFieldSignature(sig) - } - else { - CheckClassAdapter.checkClassSignature(sig) - } - } - } - - /** - * Generates the generic signature for `sym` before erasure. - * - * @param sym The symbol for which to generate a signature. - * @param owner The owner of `sym`. - * @return The generic signature of `sym` before erasure, as specified in the Java Virtual - * Machine Specification, §4.3.4, or `null` if `sym` doesn't need a generic signature. - * @see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.4 - */ - def getGenericSignature(sym: Symbol, owner: Symbol): String = { - ctx.atPhase(ctx.erasurePhase) { - val memberTpe = - if (sym.is(Flags.Method)) sym.denot.info - else owner.denot.thisType.memberInfo(sym) - getGenericSignature(sym, owner, memberTpe).orNull - } - } - - def getStaticForwarderGenericSignature(sym: Symbol, moduleClass: Symbol): String = { - // scala/bug#3452 Static forwarder generation uses the same erased signature as the method if forwards to. - // By rights, it should use the signature as-seen-from the module class, and add suitable - // primitive and value-class boxing/unboxing. - // But for now, just like we did in mixin, we just avoid writing a wrong generic signature - // (one that doesn't erase to the actual signature). See run/t3452b for a test case. - - val memberTpe = ctx.atPhase(ctx.erasurePhase) { moduleClass.denot.thisType.memberInfo(sym) } - val erasedMemberType = TypeErasure.erasure(memberTpe) - if (erasedMemberType =:= sym.denot.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 = TypeErasure.fullErasure(sym.denot.info).typeSymbol - if (erasedTypeSym.isPrimitiveValueClass) { - // Suppress signatures for symbols whose types erase in the end to primitive - // value types. This is needed to fix #7416. - None - } else { - val jsOpt = GenericSignatures.javaSig(sym, memberTpe) - if (ctx.settings.XverifySignatures.value) { - jsOpt.foreach(verifySignature(sym, _)) - } - - jsOpt - } - } else { - None - } - extension symExtensions on (sym: Symbol) { def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) From c49972c6231a17c0f524cc69027af3cfee4918e4 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 11:32:18 +0200 Subject: [PATCH 71/98] Move perRunCaches --- .../tools/backend/jvm/BTypesFromSymbols.scala | 22 +++++++++++++++++++ .../backend/jvm/DottyBackendInterface.scala | 18 --------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index b2eda326a857..3d12a1740209 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -4,11 +4,14 @@ package jvm import scala.tools.asm import scala.annotation.threadUnsafe +import scala.collection.mutable +import scala.collection.generic.Clearable import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Phases.Phase import dotty.tools.dotc.transform.SymUtils._ +import dotty.tools.dotc.util.WeakHashSet /** * This class mainly contains the method classBTypeFromSymbol, which extracts the necessary @@ -37,6 +40,25 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { coreBTypes.setBTypes(new CoreBTypes[this.type](this)) } + private[this] val perRunCaches: Caches = new Caches { + def newAnyRefMap[K <: AnyRef, V](): mutable.AnyRefMap[K, V] = new mutable.AnyRefMap[K, V]() + def newWeakMap[K, V](): mutable.WeakHashMap[K, V] = new mutable.WeakHashMap[K, V]() + def recordCache[T <: Clearable](cache: T): T = cache + def newWeakSet[K >: Null <: AnyRef](): WeakHashSet[K] = new WeakHashSet[K]() + def newMap[K, V](): mutable.HashMap[K, V] = new mutable.HashMap[K, V]() + def newSet[K](): mutable.Set[K] = new mutable.HashSet[K] + } + + // TODO remove abstraction + private abstract class Caches { + def recordCache[T <: Clearable](cache: T): T + def newWeakMap[K, V](): collection.mutable.WeakHashMap[K, V] + def newMap[K, V](): collection.mutable.HashMap[K, V] + def newSet[K](): collection.mutable.Set[K] + def newWeakSet[K >: Null <: AnyRef](): dotty.tools.dotc.util.WeakHashSet[K] + def newAnyRefMap[K <: AnyRef, V](): collection.mutable.AnyRefMap[K, V] + } + @threadUnsafe protected lazy val classBTypeFromInternalNameMap = { perRunCaches.recordCache(collection.concurrent.TrieMap.empty[String, ClassBType]) } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 8dd2c2b0073c..fb47bdb7d693 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -75,15 +75,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def sourcePos(pos: Spans.Span)(implicit ctx: Context): util.SourcePosition = ctx.source.atSpan(pos) - val perRunCaches: Caches = new Caches { - def newAnyRefMap[K <: AnyRef, V](): mutable.AnyRefMap[K, V] = new mutable.AnyRefMap[K, V]() - def newWeakMap[K, V](): mutable.WeakHashMap[K, V] = new mutable.WeakHashMap[K, V]() - def recordCache[T <: Clearable](cache: T): T = cache - def newWeakSet[K >: Null <: AnyRef](): WeakHashSet[K] = new WeakHashSet[K]() - def newMap[K, V](): mutable.HashMap[K, V] = new mutable.HashMap[K, V]() - def newSet[K](): mutable.Set[K] = new mutable.HashSet[K] - } - private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] def desugarIdentBI(i: Ident): Option[tpd.Select] = { @@ -211,15 +202,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - abstract class Caches { - def recordCache[T <: Clearable](cache: T): T - def newWeakMap[K, V](): collection.mutable.WeakHashMap[K, V] - def newMap[K, V](): collection.mutable.HashMap[K, V] - def newSet[K](): collection.mutable.Set[K] - def newWeakSet[K >: Null <: AnyRef](): dotty.tools.dotc.util.WeakHashSet[K] - def newAnyRefMap[K <: AnyRef, V](): collection.mutable.AnyRefMap[K, V] - } - // Class symbols used in backend. // Vals because they are to frequent in scala programs so that they are already loaded by backend From e3d1d96b3a9881898cc636c2cc0aa353ba5b037b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 11:34:07 +0200 Subject: [PATCH 72/98] Move primitives --- compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 ++ .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 2d01f3c4d73b..ff711bbcae4d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -35,6 +35,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { import coreBTypes._ import BCodeBodyBuilder._ + private val primitives = new DottyPrimitives(ctx) + /* * Functionality to build the body of ASM MethodNode, except for `synchronized` and `try` expressions. */ diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index fb47bdb7d693..2f6e6a1ccbe6 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -52,8 +52,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap @threadUnsafe lazy val AnnotationRetentionRuntimeAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") @threadUnsafe lazy val JavaAnnotationClass: ClassSymbol = ctx.requiredClass("java.lang.annotation.Annotation") - val primitives = new DottyPrimitives(ctx) - private def erasureString(clazz: Class[_]): String = { if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" else clazz.getName From 0cabe6fca9f9246d0828d4d339ea0b2c7a0a5970 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 12:53:54 +0200 Subject: [PATCH 73/98] Move fields --- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 4 ++++ .../dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 2 ++ .../dotty/tools/backend/jvm/BTypesFromSymbols.scala | 3 +++ .../tools/backend/jvm/DottyBackendInterface.scala | 13 ------------- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 6c958dfc3161..dc913c7d69c8 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -44,6 +44,10 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { import coreBTypes._ import int._ + def ScalaATTRName: String = "Scala" + def ScalaSignatureATTRName: String = "ScalaSig" + + val bCodeAsmCommon: BCodeAsmCommon[int.type] = new BCodeAsmCommon(int) import bCodeAsmCommon._ diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 774adc03996c..1f04e50bb37b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -33,6 +33,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { import coreBTypes._ import bCodeAsmCommon._ + lazy val NativeAttr: Symbol = requiredClass[scala.native] + /* * There's a dedicated PlainClassBuilder for each CompilationUnit, * which simplifies the initialization of per-class data structures in `genPlainClass()` which in turn delegates to `initJClass()` diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 3d12a1740209..765e04d1a97e 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -29,6 +29,9 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { import int._ import int.symExtensions + lazy val TransientAttr = requiredClass[scala.transient] + lazy val VolatileAttr = requiredClass[scala.volatile] + val bCodeAsmCommon: BCodeAsmCommon[int.type ] = new BCodeAsmCommon(int) import bCodeAsmCommon._ diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 2f6e6a1ccbe6..2183ea52124f 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -200,19 +200,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - // Class symbols used in backend. - // Vals because they are to frequent in scala programs so that they are already loaded by backend - - lazy val NativeAttr: Symbol = requiredClass[scala.native] - lazy val TransientAttr = requiredClass[scala.transient] - lazy val VolatileAttr = requiredClass[scala.volatile] - - val ScalaATTRName: String = "Scala" - val ScalaSignatureATTRName: String = "ScalaSig" - - // Module symbols used in backend - val StringModule: Symbol = requiredClass[java.lang.String].linkedClass - val ScalaRunTimeModule: Symbol = requiredModule[scala.runtime.ScalaRunTime.type] private val primitiveCompilationUnits = Set( From a03fa036ba927d29aeb77a8dfe86fe6ba30e8ccc Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 12:57:18 +0200 Subject: [PATCH 74/98] Inline sourcePos --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 8 ++++---- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 4 +--- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index ff711bbcae4d..88ca5c9c6488 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -666,7 +666,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { var elemKind = arr.elementType val argsSize = args.length if (argsSize > dims) { - ctx.error(s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)", sourcePos(app.span)) + ctx.error(s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)", ctx.source.atSpan(app.span)) } if (argsSize < dims) { /* In one step: diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index dc913c7d69c8..22a7e4a8e257 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -66,7 +66,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { outputDirectory } catch { case ex: Throwable => - ctx.error(s"Couldn't create file for class $cName\n${ex.getMessage}", sourcePos(csym.span)) + ctx.error(s"Couldn't create file for class $cName\n${ex.getMessage}", ctx.source.atSpan(csym.span)) null } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 1f04e50bb37b..f57a05a776c4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -407,7 +407,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val loc = Local(tk, sym.name.mangledString.toString, nxtIdx, sym.is(Flags.Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) - ctx.error("attempt to create duplicate local var.", sourcePos(sym.span)) + ctx.error("attempt to create duplicate local var.", ctx.source.atSpan(sym.span)) assert(tk.size > 0, "makeLocal called for a symbol whose type is Unit.") nxtIdx += tk.size loc @@ -457,7 +457,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } def lineNumber(tree: Tree): Unit = { if (!emitLines || !tree.span.exists) return; - val nr = sourcePos(tree.span).line + 1 + val nr = ctx.source.atSpan(tree.span).line + 1 if (nr != lastEmittedLineNr) { lastEmittedLineNr = nr lastInsn match { @@ -560,7 +560,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { if (params.size > MaximumJvmParameters) { // SI-7324 - ctx.error(s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", sourcePos(methSymbol.span)) + ctx.error(s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", ctx.source.atSpan(methSymbol.span)) return } @@ -589,7 +589,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { ctx.error("Concrete method has no definition: " + dd + ( if (ctx.settings.Ydebug.value) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" else ""), - sourcePos(NoSpan) + ctx.source.atSpan(NoSpan) ) case _ => bc emitRETURN returnType diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 2183ea52124f..1ab380edd49d 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -70,8 +70,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap ctx.error(msg) throw new RuntimeException(msg) } - def sourcePos(pos: Spans.Span)(implicit ctx: Context): util.SourcePosition = - ctx.source.atSpan(pos) private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] @@ -181,7 +179,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => - ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", sourcePos(field.span)) + ctx.error(s"JavaSeqArray with type ${field.tpe} reached backend: $field", ctx.source.atSpan(field.span)) UnspecifiedErrorType } def _2: List[Tree] = field.elems From 405104d41ba5a352cb32a80d12f3025b8296ff00 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 13:06:46 +0200 Subject: [PATCH 75/98] Move ExcludedForwarderFlags to Flags --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- .../dotty/tools/backend/jvm/DottyBackendInterface.scala | 9 +-------- compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala | 3 +-- compiler/src/dotty/tools/dotc/core/Flags.scala | 1 + 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 22a7e4a8e257..6f1087b7dac3 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -563,7 +563,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } ctx.debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") - for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flags.Method, excluded = DottyBackendInterface.ExcludedForwarderFlags)) { + for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flags.Method, excluded = Flags.ExcludedForwarder)) { val m = if (m0.is(Flags.Bridge)) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) ctx.log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 1ab380edd49d..9d256b4da0e1 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -41,7 +41,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. - @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") + // @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") val externalEquals: Symbol = defn.BoxesRunTimeModule.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol @@ -221,10 +221,3 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - -object DottyBackendInterface { - val ExcludedForwarderFlags: Flags.FlagSet = { - Flags.Specialized | Flags.Lifted | Flags.Protected | Flags.JavaStatic | - Flags.Private | Flags.Macro - } -} diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 89915e44eb16..c17e7b881bf2 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -548,9 +548,8 @@ class JSCodeGen()(implicit ctx: Context) { }.toSet val members = { - import dotty.tools.backend.jvm.DottyBackendInterface.ExcludedForwarderFlags moduleClass.info.membersBasedOnFlags(required = Flags.Method, - excluded = ExcludedForwarderFlags).map(_.symbol) + excluded = Flags.ExcludedForwarder).map(_.symbol) } def isExcluded(m: Symbol): Boolean = { diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 0b2aa4133983..b1ddc12b2ed4 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -536,6 +536,7 @@ object Flags { val FinalOrInline: FlagSet = Final | Inline val FinalOrModuleClass: FlagSet = Final | ModuleClass // A module class or a final class val EffectivelyFinalFlags: FlagSet = Final | Private + val ExcludedForwarder: Flags.FlagSet = Specialized | Lifted | Protected | JavaStatic | Private | Macro val FinalOrSealed: FlagSet = Final | Sealed val GivenOrImplicit: FlagSet = Given | Implicit val GivenOrImplicitVal: FlagSet = GivenOrImplicit.toTermFlags From 885035d8388283928beec077ebed14c78867b45d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 13:53:53 +0200 Subject: [PATCH 76/98] Move fields --- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 8 +++++++- .../tools/backend/jvm/DottyBackendInterface.scala | 14 -------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 6f1087b7dac3..9bbb22ee486c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -2,11 +2,11 @@ package dotty.tools package backend package jvm +import scala.annotation.threadUnsafe import scala.tools.asm import scala.tools.asm.AnnotationVisitor import scala.tools.asm.ClassWriter import scala.collection.mutable -import dotty.tools.io.AbstractFile import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.ast.tpd @@ -25,6 +25,7 @@ import dotty.tools.dotc.core.Types import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.TypeErasure import dotty.tools.dotc.transform.GenericSignatures +import dotty.tools.io.AbstractFile /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -47,6 +48,11 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { def ScalaATTRName: String = "Scala" def ScalaSignatureATTRName: String = "ScalaSig" + @threadUnsafe lazy val AnnotationRetentionAttr: ClassSymbol = ctx.requiredClass("java.lang.annotation.Retention") + @threadUnsafe lazy val AnnotationRetentionSourceAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE") + @threadUnsafe lazy val AnnotationRetentionClassAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS") + @threadUnsafe lazy val AnnotationRetentionRuntimeAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") + @threadUnsafe lazy val JavaAnnotationClass: ClassSymbol = ctx.requiredClass("java.lang.annotation.Annotation") val bCodeAsmCommon: BCodeAsmCommon[int.type] = new BCodeAsmCommon(int) import bCodeAsmCommon._ diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 9d256b4da0e1..574b0047de70 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -35,23 +35,9 @@ import Annotations.Annotation import Names.Name class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit val ctx: Context) { - 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. - - - // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. - // @threadUnsafe lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") - @threadUnsafe lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") val externalEquals: Symbol = defn.BoxesRunTimeModule.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol - @threadUnsafe lazy val AnnotationRetentionAttr: ClassSymbol = ctx.requiredClass("java.lang.annotation.Retention") - @threadUnsafe lazy val AnnotationRetentionSourceAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE") - @threadUnsafe lazy val AnnotationRetentionClassAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS") - @threadUnsafe lazy val AnnotationRetentionRuntimeAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") - @threadUnsafe lazy val JavaAnnotationClass: ClassSymbol = ctx.requiredClass("java.lang.annotation.Annotation") - private def erasureString(clazz: Class[_]): String = { if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" else clazz.getName From b86829106a564bc6836660d96e14eae2725d6a33 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 13:56:41 +0200 Subject: [PATCH 77/98] Move field --- compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 2 -- compiler/src/dotty/tools/dotc/core/Definitions.scala | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 88ca5c9c6488..4b5ff17d0522 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1377,7 +1377,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (r.tpe <:< defn.BoxedNumberClass.info) defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumNum) else if (r.tpe <:< defn.BoxedCharClass.info) NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private else defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject) - } else externalEquals + } else defn.BoxesRunTimeModule_externalEquals } genLoad(l, ObjectReference) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 574b0047de70..231a8127f0e8 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -36,8 +36,6 @@ import Names.Name class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit val ctx: Context) { - val externalEquals: Symbol = defn.BoxesRunTimeModule.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol - private def erasureString(clazz: Class[_]): String = { if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" else clazz.getName diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 6dba2ed925c4..325638fe5094 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -399,6 +399,7 @@ class Definitions { @tu lazy val ScalaRuntime__hashCode: Symbol = ScalaRuntimeModule.requiredMethod(nme._hashCode_) @tu lazy val BoxesRunTimeModule: Symbol = ctx.requiredModule("scala.runtime.BoxesRunTime") + @tu lazy val BoxesRunTimeModule_externalEquals: Symbol = BoxesRunTimeModule.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol @tu lazy val ScalaStaticsModule: Symbol = ctx.requiredModule("scala.runtime.Statics") def staticsMethodRef(name: PreName): TermRef = ScalaStaticsModule.requiredMethodRef(name) def staticsMethod(name: PreName): TermSymbol = ScalaStaticsModule.requiredMethod(name) From ac0a0c1108f94979d98d2c1bdd74edfdfea435ec Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 14:05:40 +0200 Subject: [PATCH 78/98] Move abort --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 5 +++++ compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala | 5 +++++ .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 5 ----- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 9bbb22ee486c..54657979d0f9 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -929,6 +929,11 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { getGenericSignatureHelper(sym, moduleClass, memberTpe).orNull else null } + + def abort(msg: String): Nothing = { + ctx.error(msg) + throw new RuntimeException(msg) + } } object BCodeHelpers { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala b/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala index 90519a5d105f..a68f9f4bc14a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala @@ -584,6 +584,11 @@ trait BCodeIdiomatic { jmethod.visitTypeInsn(Opcodes.CHECKCAST, tk.classOrArrayType) } + def abort(msg: String): Nothing = { + ctx.error(msg) + throw new RuntimeException(msg) + } + } // end of class JCodeMethodN /* Constant-valued val-members of JCodeMethodN at the companion object, so as to avoid re-initializing them multiple times. */ diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 231a8127f0e8..c0dbcd55a5a7 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -50,11 +50,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap ctx.requiredModule(className) } - def abort(msg: String): Nothing = { - ctx.error(msg) - throw new RuntimeException(msg) - } - private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] def desugarIdentBI(i: Ident): Option[tpd.Select] = { From 95c247d8eec551afb506849fe722d533271a941e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 14:09:21 +0200 Subject: [PATCH 79/98] Remove Throw custom extractor --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 4 ++-- .../tools/backend/jvm/BCodeSkelBuilder.scala | 3 ++- .../tools/backend/jvm/DottyBackendInterface.scala | 15 --------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 4b5ff17d0522..7665015674fb 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -307,8 +307,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case t @ Try(_, _, _) => generatedType = genLoadTry(t) - case ThrowBI(expr) => - generatedType = genThrow(expr) + case t: Apply if t.fun.symbol eq defn.throwMethod => + generatedType = genThrow(t.args.head) case New(tpt) => abort(s"Unexpected New(${tpt.tpe.showSummary()}/$tpt) reached GenBCode.\n" + diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index f57a05a776c4..f4188920dd54 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -584,7 +584,8 @@ trait BCodeSkelBuilder extends BCodeHelpers { genLoad(rhs, returnType) rhs match { - case (_: Return) | Block(_, (_: Return)) | ThrowBI(_) | Block(_, ThrowBI(_)) => () + case (_: Return) | Block(_, (_: Return)) => () + case (_: Apply) | Block(_, (_: Apply)) if rhs.symbol eq defn.throwMethod => () case tpd.EmptyTree => ctx.error("Concrete method has no definition: " + dd + ( if (ctx.settings.Ydebug.value) "(found: " + methSymbol.owner.info.decls.toList.mkString(", ") + ")" diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index c0dbcd55a5a7..f7b4af10f8c1 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -139,21 +139,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - object ThrowBI { - var field: tpd.Apply = _ - def isEmpty: Boolean = field eq null - def isDefined = !isEmpty - def get: Tree = field.args.head - def unapply(s: tpd.Apply): ThrowBI.type = { - if (s.fun.symbol eq defn.throwMethod) { - field = s - } else { - field = null - } - this - } - } - object ArrayValueBI extends DeconstructorCommon[tpd.JavaSeqLiteral] { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem From b5168aab2ba026b02d812b9eadca115f8ab41913 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 14:25:19 +0200 Subject: [PATCH 80/98] Do not capture Context in symExtension --- .../tools/backend/jvm/BCodeAsmCommon.scala | 2 +- .../tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../tools/backend/jvm/BTypesFromSymbols.scala | 2 +- .../backend/jvm/DottyBackendInterface.scala | 97 ++++++++++--------- .../dotty/tools/backend/jvm/GenBCode.scala | 2 +- 6 files changed, 56 insertions(+), 51 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index cc5c96e67f5f..9a7ae6fce6ae 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -11,7 +11,7 @@ import dotty.tools.dotc.core.Symbols._ */ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { import interface._ - import interface.symExtensions + import DottyBackendInterface.symExtensions /** * True if `classSym` is an anonymous class or a local class. I.e., false if `classSym` is a diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 7665015674fb..0a82f0be6910 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -30,7 +30,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // import definitions._ import tpd._ import int._ - import int.symExtensions + import DottyBackendInterface.symExtensions import bTypes._ import coreBTypes._ import BCodeBodyBuilder._ diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index f4188920dd54..78a085f3488b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -27,7 +27,7 @@ import dotty.tools.dotc.util.Spans._ */ trait BCodeSkelBuilder extends BCodeHelpers { import int._ - import int.symExtensions + import DottyBackendInterface.symExtensions import tpd._ import bTypes._ import coreBTypes._ diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 765e04d1a97e..b727b5c5c318 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -27,7 +27,7 @@ import dotty.tools.dotc.util.WeakHashSet */ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { import int._ - import int.symExtensions + import DottyBackendInterface.symExtensions lazy val TransientAttr = requiredClass[scala.transient] lazy val VolatileAttr = requiredClass[scala.volatile] diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index f7b4af10f8c1..821a49e3a503 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -65,54 +65,8 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap if (found == null) None else Some(found) } - extension symExtensions on (sym: Symbol) { - - def isInterface: Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) - - def isStaticConstructor: Boolean = (sym.isStaticMember && sym.isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) - - def isStaticMember: Boolean = (sym ne NoSymbol) && - (sym.is(Flags.JavaStatic) || 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 - - /** - * True for module classes of modules that are top-level or owned only by objects. Module classes - * for such objects will get a MODULE$ flag and a corresponding static initializer. - */ - def isStaticModuleClass: Boolean = - (sym.is(Flags.Module)) && { - // scalac uses atPickling here - // this would not work if modules are created after pickling - // for example by specialization - val original = toDenot(sym).initial - val validity = original.validFor - val shiftedContext = ctx.withPhase(validity.phaseId) - toDenot(sym)(shiftedContext).isStatic(shiftedContext) - } - - def originalLexicallyEnclosingClass: 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 validity = toDenot(sym).initial.validFor - val shiftedContext = ctx.withPhase(validity.phaseId) - toDenot(sym)(shiftedContext).lexicallyEnclosingClass(shiftedContext) - } else NoSymbol - - /** - * True for module classes of package level objects. The backend will generate a mirror class for - * such objects. - */ - def isTopLevelModuleClass: Boolean = - sym.is(Flags.ModuleClass) && - ctx.atPhase(ctx.flattenPhase) { - toDenot(sym).owner.is(Flags.PackageClass) - } - - } - object SelectBI extends DeconstructorCommon[tpd.Tree] { var desugared: tpd.Select = null @@ -185,3 +139,54 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } + +object DottyBackendInterface { + + extension symExtensions on (sym: Symbol) { + + def isInterface(using Context): Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) + + def isStaticConstructor(using Context): Boolean = (sym.isStaticMember && sym.isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) + + def isStaticMember(using Context): Boolean = (sym ne NoSymbol) && + (sym.is(Flags.JavaStatic) || 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 + + /** + * True for module classes of modules that are top-level or owned only by objects. Module classes + * for such objects will get a MODULE$ flag and a corresponding static initializer. + */ + def isStaticModuleClass(using Context): Boolean = + (sym.is(Flags.Module)) && { + // scalac uses atPickling here + // this would not work if modules are created after pickling + // for example by specialization + val original = toDenot(sym).initial + val validity = original.validFor + val shiftedContext = ctx.withPhase(validity.phaseId) + toDenot(sym)(shiftedContext).isStatic(shiftedContext) + } + + + + def originalLexicallyEnclosingClass(using Context): 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 validity = toDenot(sym).initial.validFor + val shiftedContext = ctx.withPhase(validity.phaseId) + toDenot(sym)(shiftedContext).lexicallyEnclosingClass(shiftedContext) + } else NoSymbol + + /** + * True for module classes of package level objects. The backend will generate a mirror class for + * such objects. + */ + def isTopLevelModuleClass(using Context): Boolean = + sym.is(Flags.ModuleClass) && + ctx.atPhase(ctx.flattenPhase) { + toDenot(sym).owner.is(Flags.PackageClass) + } + + } +} diff --git a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala index f46ccc41861d..49fd86aef855 100644 --- a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala @@ -70,7 +70,7 @@ object GenBCode { } class GenBCodePipeline(val int: DottyBackendInterface)(implicit ctx: Context) extends BCodeSyncAndTry { - import int.symExtensions + import DottyBackendInterface.symExtensions private var tree: Tree = _ From 0485885ac4ea54b725b32b741a2ba77e033e5943 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 14:33:50 +0200 Subject: [PATCH 81/98] Add explicit Context --- .../tools/backend/jvm/BCodeHelpers.scala | 1 + .../tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../src/dotty/tools/backend/jvm/BTypes.scala | 2 +- .../tools/backend/jvm/BTypesFromSymbols.scala | 2 +- .../dotty/tools/backend/jvm/CoreBTypes.scala | 1 + .../backend/jvm/DottyBackendInterface.scala | 69 +++++++++---------- 6 files changed, 38 insertions(+), 39 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 54657979d0f9..a10d7bd263ef 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -44,6 +44,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { import tpd._ import coreBTypes._ import int._ + import DottyBackendInterface._ def ScalaATTRName: String = "Scala" def ScalaSignatureATTRName: String = "ScalaSig" diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 78a085f3488b..d29eb717fbb7 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -27,7 +27,7 @@ import dotty.tools.dotc.util.Spans._ */ trait BCodeSkelBuilder extends BCodeHelpers { import int._ - import DottyBackendInterface.symExtensions + import DottyBackendInterface.{symExtensions, _} import tpd._ import bTypes._ import coreBTypes._ diff --git a/compiler/src/dotty/tools/backend/jvm/BTypes.scala b/compiler/src/dotty/tools/backend/jvm/BTypes.scala index 7d19b57a7bd6..7df2e674f3a5 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypes.scala @@ -610,7 +610,7 @@ abstract class BTypes { assert(!ClassBType.isInternalPhantomType(internalName), s"Cannot create ClassBType for phantom type $this") assert( - if (info.superClass.isEmpty) { isJLO(this) || (int.isCompilingPrimitive && ClassBType.hasNoSuper(internalName)) } + if (info.superClass.isEmpty) { isJLO(this) || (DottyBackendInterface.isCompilingPrimitive && ClassBType.hasNoSuper(internalName)) } else if (isInterface) isJLO(info.superClass.get) else !isJLO(this) && ifInit(info.superClass.get)(!_.isInterface), s"Invalid superClass in $this: ${info.superClass}" diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index b727b5c5c318..c2def00d0176 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -27,7 +27,7 @@ import dotty.tools.dotc.util.WeakHashSet */ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { import int._ - import DottyBackendInterface.symExtensions + import DottyBackendInterface.{symExtensions, _} lazy val TransientAttr = requiredClass[scala.transient] lazy val VolatileAttr = requiredClass[scala.volatile] diff --git a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala index 9fbcdaa2a7c6..2d4aec72d0b1 100644 --- a/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala +++ b/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala @@ -34,6 +34,7 @@ import dotty.tools.dotc.transform.Erasure class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTypes: BTFS) { import bTypes._ import int._ + import DottyBackendInterface._ //import global._ //import rootMirror.{requiredClass, getClassIfDefined} diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 821a49e3a503..668eedc333d2 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -36,20 +36,6 @@ import Names.Name class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(implicit val ctx: Context) { - private def erasureString(clazz: Class[_]): String = { - if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" - else clazz.getName - } - - def requiredClass[T](implicit evidence: ClassTag[T]): Symbol = - ctx.requiredClass(erasureString(evidence.runtimeClass)) - - def requiredModule[T](implicit evidence: ClassTag[T]): Symbol = { - val moduleName = erasureString(evidence.runtimeClass) - val className = if (moduleName.endsWith("$")) moduleName.dropRight(1) else moduleName - ctx.requiredModule(className) - } - private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] def desugarIdentBI(i: Ident): Option[tpd.Select] = { @@ -103,8 +89,6 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap def _2: List[Tree] = field.elems } - - abstract class DeconstructorCommon[T >: Null <: AnyRef] { var field: T = null def get: this.type = this @@ -116,31 +100,23 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } +} +object DottyBackendInterface { - private val primitiveCompilationUnits = Set( - "Unit.scala", - "Boolean.scala", - "Char.scala", - "Byte.scala", - "Short.scala", - "Int.scala", - "Float.scala", - "Long.scala", - "Double.scala" - ) - - /** - * True if the current compilation unit is of a primitive class (scala.Boolean et al). - * Used only in assertions. - */ - def isCompilingPrimitive = { - primitiveCompilationUnits(ctx.compilationUnit.source.file.name) + private def erasureString(clazz: Class[_]): String = { + if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" + else clazz.getName } -} + def requiredClass[T](implicit evidence: ClassTag[T], ctx: Context): Symbol = + ctx.requiredClass(erasureString(evidence.runtimeClass)) -object DottyBackendInterface { + def requiredModule[T](implicit evidence: ClassTag[T], ctx: Context): Symbol = { + val moduleName = erasureString(evidence.runtimeClass) + val className = if (moduleName.endsWith("$")) moduleName.dropRight(1) else moduleName + ctx.requiredModule(className) + } extension symExtensions on (sym: Symbol) { @@ -189,4 +165,25 @@ object DottyBackendInterface { } } + + private val primitiveCompilationUnits = Set( + "Unit.scala", + "Boolean.scala", + "Char.scala", + "Byte.scala", + "Short.scala", + "Int.scala", + "Float.scala", + "Long.scala", + "Double.scala" + ) + + /** + * True if the current compilation unit is of a primitive class (scala.Boolean et al). + * Used only in assertions. + */ + def isCompilingPrimitive(using ctx: Context) = { + primitiveCompilationUnits(ctx.compilationUnit.source.file.name) + } + } From b6cdabe5a371b972820e6a628add297f1e11dba1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 14:42:09 +0200 Subject: [PATCH 82/98] Rename extractors --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 41 +++++++++---------- .../backend/jvm/DottyBackendInterface.scala | 6 +-- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 0a82f0be6910..71cdfc96819a 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -72,7 +72,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(tree) tree match { - case Assign(lhs @ SelectBI(qual, _), rhs) => + case Assign(lhs @ DesugaredSelect(qual, _), rhs) => val isStatic = lhs.symbol.isStaticMember if (!isStatic) { genLoadQualifier(lhs) } genLoad(rhs, symInfoTK(lhs.symbol)) @@ -107,7 +107,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* Generate code for primitive arithmetic operations. */ def genArithmeticOp(tree: Tree, code: Int): BType = tree match{ - case Apply(fun @ SelectBI(larg, _), args) => + case Apply(fun @ DesugaredSelect(larg, _), args) => var resKind = tpeTK(larg) assert(resKind.isNumericType || (resKind == BOOL), @@ -163,7 +163,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { /* Generate primitive array operations. */ def genArrayOp(tree: Tree, code: Int, expectedType: BType): BType = tree match{ - case Apply(SelectBI(arrayObj, _), args) => + case Apply(DesugaredSelect(arrayObj, _), args) => import ScalaPrimitivesOps._ val k = tpeTK(arrayObj) genLoad(arrayObj, k) @@ -225,7 +225,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genPrimitiveOp(tree: Apply, expectedType: BType): BType = tree match { - case Apply(fun @ SelectBI(receiver, _), _) => + case Apply(fun @ DesugaredSelect(receiver, _), _) => val sym = tree.symbol val code = primitives.getPrimitive(tree, receiver.tpe) @@ -330,7 +330,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } val (fun, args) = call match { case Apply(fun, args) => (fun, args) - case t @ SelectBI(_, _) => (t, Nil) + case t @ DesugaredSelect(_, _) => (t, Nil) case t @ Ident(_) => (t, Nil) } @@ -341,7 +341,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // but I was able to derrive it by reading // AbstractValidatingLambdaMetafactory.validateMetafactoryArgs - val SelectBI(prefix, _) = fun + val DesugaredSelect(prefix, _) = fun genLoad(prefix) } @@ -365,11 +365,11 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { else classBTypeFromSymbol(claszSymbol) } - case SelectBI(Ident(nme.EMPTY_PACKAGE), module) => + case DesugaredSelect(Ident(nme.EMPTY_PACKAGE), module) => assert(tree.symbol.is(Flags.Module), s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.span}") genLoadModule(tree) - case SelectBI(qualifier, _) => + case DesugaredSelect(qualifier, _) => val sym = tree.symbol generatedType = symInfoTK(sym) val qualSafeToElide = tpd.isIdempotentExpr(qualifier) @@ -426,7 +426,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType = UNIT genStat(tree) - case av @ ArrayValueBI(_, _) => + case av @ ArrayValue(_, _) => generatedType = genArrayValue(av) case mtch @ Match(_, _) => @@ -622,7 +622,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } def genTypeApply(t: TypeApply): BType = t match { - case TypeApply(fun@SelectBI(obj, _), targs) => + case TypeApply(fun@DesugaredSelect(obj, _), targs) => val sym = fun.symbol val cast = @@ -690,7 +690,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(app) app match { case Apply(_, args) if app.symbol eq defn.newArrayMethod => - val List(elemClaz, Literal(c: Constant), ArrayValueBI(_, dims)) = args + val List(elemClaz, Literal(c: Constant), ArrayValue(_, dims)) = args generatedType = toTypeKind(c.typeValue) mkArrayConstructorCall(generatedType.asArrayBType, app, dims) @@ -699,7 +699,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (t.symbol ne defn.Object_synchronized) genTypeApply(t) else genSynchronized(app, expectedType) - case Apply(fun @ SelectBI(Super(_, _), _), args) => + case Apply(fun @ DesugaredSelect(Super(_, _), _), args) => def initModule(): Unit = { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && @@ -731,7 +731,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // thought to return an instance of what they construct, // we have to 'simulate' it by DUPlicating the freshly created // instance (on JVM, methods return VOID). - case Apply(fun @ SelectBI(New(tpt), nme.CONSTRUCTOR), args) => + case Apply(fun @ DesugaredSelect(New(tpt), nme.CONSTRUCTOR), args) => val ctor = fun.symbol assert(ctor.isClassConstructor, s"'new' call to non-constructor: ${ctor.name}") @@ -781,9 +781,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (invokeStyle.hasInstance) genLoadQualifier(fun) genLoadArguments(args, paramTKs(app)) - val SelectBI(qual, _) = fun // fun is a Select, also checked in genLoadQualifier + val DesugaredSelect(qual, _) = fun // fun is a Select, also checked in genLoadQualifier val isArrayClone = fun match { - case SelectBI(qual, nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true + case DesugaredSelect(qual, nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true case _ => false } if (isArrayClone) { @@ -826,9 +826,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType } // end of genApply() - private def genArrayValue(av: tpd.JavaSeqLiteral): BType = av match { - case ArrayValueBI(tpt, elems) => - val ArrayValueBI(tpt, elems) = av + private def genArrayValue(av: tpd.JavaSeqLiteral): BType = { + val ArrayValue(tpt, elems) = av lineNumber(av) genArray(elems, tpt) @@ -1013,7 +1012,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadQualifier(tree: Tree): Unit = { lineNumber(tree) tree match { - case SelectBI(qualifier, _) => genLoad(qualifier) + case DesugaredSelect(qualifier, _) => genLoad(qualifier) case t: Ident => // dotty specific desugarIdentBI(t) match { case Some(sel) => genLoadQualifier(sel) @@ -1191,7 +1190,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * It turns a chained call like "a".+("b").+("c") into a list of arguments. */ def liftStringConcat(tree: Tree): List[Tree] = tree match { - case tree @ Apply(fun @ SelectBI(larg, method), rarg) => + case tree @ Apply(fun @ DesugaredSelect(larg, method), rarg) => if (isPrimitive(fun) && primitives.getPrimitive(tree, larg.tpe) == ScalaPrimitivesOps.CONCAT) liftStringConcat(larg) ::: rarg @@ -1303,7 +1302,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { import ScalaPrimitivesOps.{ ZNOT, ZAND, ZOR, EQ } // lhs and rhs of test - lazy val SelectBI(lhs, _) = fun + lazy val DesugaredSelect(lhs, _) = fun val rhs = if (args.isEmpty) tpd.EmptyTree else args.head // args.isEmpty only for ZNOT def genZandOrZor(and: Boolean): Unit = { diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 668eedc333d2..7cefab0aed58 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -51,9 +51,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap if (found == null) None else Some(found) } - - - object SelectBI extends DeconstructorCommon[tpd.Tree] { + object DesugaredSelect extends DeconstructorCommon[tpd.Tree] { var desugared: tpd.Select = null @@ -79,7 +77,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap } } - object ArrayValueBI extends DeconstructorCommon[tpd.JavaSeqLiteral] { + object ArrayValue extends DeconstructorCommon[tpd.JavaSeqLiteral] { def _1: Type = field.tpe match { case JavaArrayType(elem) => elem case _ => From 2caf4bf504559bfef3fc467c9c7c6d7d57bd6cee Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 5 Jun 2020 14:51:41 +0200 Subject: [PATCH 83/98] Rename desugarIdentBI --- compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 4 ++-- .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 71cdfc96819a..214b81f0075d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -394,7 +394,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val tk = symInfoTK(sym) generatedType = tk - val desugared = desugarIdentBI(t) + val desugared = cachedDesugarIdent(t) desugared match { case None => if (!sym.is(Flags.Package)) { @@ -1014,7 +1014,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { tree match { case DesugaredSelect(qualifier, _) => genLoad(qualifier) case t: Ident => // dotty specific - desugarIdentBI(t) match { + cachedDesugarIdent(t) match { case Some(sel) => genLoadQualifier(sel) case None => assert(t.symbol.owner == this.claszSymbol) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 7cefab0aed58..6daac69e27df 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -38,7 +38,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] - def desugarIdentBI(i: Ident): Option[tpd.Select] = { + def cachedDesugarIdent(i: Ident): Option[tpd.Select] = { var found = desugared.get(i.tpe) if (found == null) { tpd.desugarIdent(i) match { @@ -66,7 +66,7 @@ class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap s match { case t: tpd.Select => desugared = t case t: Ident => - desugarIdentBI(t) match { + cachedDesugarIdent(t) match { case Some(t) => desugared = t case None => desugared = null } From 1513eb6ee863d374188835c74f5efbf3728fd6e8 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 09:16:17 +0200 Subject: [PATCH 84/98] Add isScalaStatic to SymUtils --- compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 5 +++-- .../src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 2 +- compiler/src/dotty/tools/dotc/transform/CheckStatic.scala | 4 +++- compiler/src/dotty/tools/dotc/transform/SelectStatic.scala | 3 ++- compiler/src/dotty/tools/dotc/transform/SymUtils.scala | 4 ++++ 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 214b81f0075d..de9013cbfcbf 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -17,6 +17,7 @@ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.StdNames.{nme, str} import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.transform.Erasure +import dotty.tools.dotc.transform.SymUtils._ import dotty.tools.dotc.util.Spans._ /* @@ -464,7 +465,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * must-single-thread */ private def fieldOp(field: Symbol, isLoad: Boolean, specificReceiver: Symbol): Unit = { - val useSpecificReceiver = specificReceiver != null && !field.hasAnnotation(ctx.definitions.ScalaStaticAnnot) + val useSpecificReceiver = specificReceiver != null && !field.isScalaStatic val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner) val fieldJName = field.name.mangledString.toString @@ -1126,7 +1127,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (specificReceiver != null) assert(style.isVirtual || specificReceiver == methodOwner, s"specificReceiver can only be specified for virtual calls. $method - $specificReceiver") - val useSpecificReceiver = specificReceiver != null && (specificReceiver ne defn.NullClass) && (specificReceiver ne defn.NothingClass) && !method.hasAnnotation(ctx.definitions.ScalaStaticAnnot) + val useSpecificReceiver = specificReceiver != null && (specificReceiver ne defn.NullClass) && (specificReceiver ne defn.NothingClass) && !method.isScalaStatic val receiver = if (useSpecificReceiver) specificReceiver else methodOwner // workaround for a JVM bug: https://bugs.openjdk.java.net/browse/JDK-8154587 diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 6daac69e27df..3bf8cb5c7aff 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -123,7 +123,7 @@ object DottyBackendInterface { def isStaticConstructor(using Context): Boolean = (sym.isStaticMember && sym.isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) def isStaticMember(using Context): Boolean = (sym ne NoSymbol) && - (sym.is(Flags.JavaStatic) || sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)) + (sym.is(Flags.JavaStatic) || sym.isScalaStatic) // guard against no sumbol cause this code is executed to select which call type(static\dynamic) to use to call array.clone /** diff --git a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala index 395527ffd3fe..11040f4872cc 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala @@ -10,6 +10,8 @@ import dotty.tools.dotc.ast.tpd import Decorators._ import reporting.messages._ +import dotty.tools.dotc.transform.SymUtils._ + /** A transformer that check that requirements of Static fields\methods are implemented: * 1. Only objects can have members annotated with `@static` * 2. The fields annotated with `@static` should precede any non-`@static` fields. @@ -31,7 +33,7 @@ class CheckStatic extends MiniPhase { val defns = tree.body.collect{case t: ValOrDefDef => t} var hadNonStaticField = false for (defn <- defns) - if (defn.symbol.hasAnnotation(ctx.definitions.ScalaStaticAnnot)) { + if (defn.symbol.isScalaStatic) { if (!ctx.owner.is(Module)) ctx.error(StaticFieldsOnlyAllowedInObjects(defn.symbol), defn.sourcePos) diff --git a/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala b/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala index a0a6f26508ca..226bed2f66ce 100644 --- a/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -9,6 +9,7 @@ import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core._ import dotty.tools.dotc.transform.MegaPhase._ +import dotty.tools.dotc.transform.SymUtils._ /** Removes selects that would be compiled into GetStatic * otherwise backend needs to be aware that some qualifiers need to be dropped. @@ -25,7 +26,7 @@ class SelectStatic extends MiniPhase with IdentityDenotTransformer { def isStaticMember = (sym is Flags.Module) && sym.initial.maybeOwner.initial.isStaticOwner || (sym is Flags.JavaStatic) || - sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot) + sym.isScalaStatic val isStaticRef = !sym.is(Package) && !sym.maybeOwner.is(Package) && isStaticMember val tree1 = if (isStaticRef && !tree.qualifier.symbol.isAllOf(JavaModule) && !tree.qualifier.isType) diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala index ff7890f62a4c..cb2751fe120f 100644 --- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala @@ -227,4 +227,8 @@ class SymUtils(val self: Symbol) extends AnyVal { def isCollectiveExtensionClass(using Context): Boolean = self.is(ModuleClass) && self.sourceModule.is(Extension, butNot = Method) + + def isScalaStatic(using Context): Boolean = + self.hasAnnotation(ctx.definitions.ScalaStaticAnnot) + } From 9a3b80e7e3613a6bfb38097977788b15c02e098f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 09:29:37 +0200 Subject: [PATCH 85/98] Remove comment and add TODO --- .../src/dotty/tools/backend/jvm/BTypesFromSymbols.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index c2def00d0176..59466e5e4f65 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -167,9 +167,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // like D is a member of C, not C$. val linkedClass = classSym.linkedClass val companionModuleMembers = { - // phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes, - // not local classes of the companion module (E in the example) that were lifted by lambdalift. - if (classSym.linkedClass.isTopLevelModuleClass) /*exitingPickler*/ getMemberClasses(classSym.linkedClass) + if (classSym.linkedClass.isTopLevelModuleClass) getMemberClasses(classSym.linkedClass) else Nil } @@ -324,7 +322,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (sym.isAllOf(Flags.JavaEnumTrait)) ACC_ENUM else 0, if (sym.is(Flags.JavaVarargs)) ACC_VARARGS else 0, if (sym.is(Flags.Synchronized)) ACC_SYNCHRONIZED else 0, - if (false /*sym.isDeprecated*/) asm.Opcodes.ACC_DEPRECATED else 0, + if (false /*sym.isDeprecated*/) asm.Opcodes.ACC_DEPRECATED else 0, // TODO: add an isDeprecated method in SymUtils if (sym.is(Flags.Enum)) asm.Opcodes.ACC_ENUM else 0 ) } From c46ab152b25ed3e8e3574f7a699477666674a42e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 09:42:28 +0200 Subject: [PATCH 86/98] Factor out `javaSimpleName`, `javaClassName` and `javaBinaryName` --- .../dotty/tools/backend/jvm/BCodeAsmCommon.scala | 2 +- .../dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 14 +++++++------- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 8 +++++--- .../dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 10 +++++----- .../tools/backend/jvm/BTypesFromSymbols.scala | 4 ++-- .../tools/backend/jvm/DottyBackendInterface.scala | 3 +++ .../src/dotty/tools/backend/sjs/JSEncoding.scala | 8 +++++--- .../src/dotty/tools/dotc/core/SymbolLoaders.scala | 4 +++- .../dotty/tools/dotc/transform/TreeChecker.scala | 3 ++- 9 files changed, 33 insertions(+), 23 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 9a7ae6fce6ae..7b5380b1d9b3 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -92,7 +92,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { ctx.debuglog(s"enclosing method for $classSym is $methodOpt (in ${methodOpt.map(_.enclosingClass)})") Some(EnclosingMethodEntry( classDesc(enclosingClassForEnclosingMethodAttribute(classSym)), - methodOpt.map(_.name.mangledString.toString).orNull, + methodOpt.map(_.javaSimpleName).orNull, methodOpt.map(methodDesc).orNull)) } else { None diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index de9013cbfcbf..3e61ac533d0f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -468,7 +468,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val useSpecificReceiver = specificReceiver != null && !field.isScalaStatic val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner) - val fieldJName = field.name.mangledString.toString + val fieldJName = field.javaSimpleName val fieldDescr = symInfoTK(field).descriptor val isStatic = field.isStaticMember val opc = @@ -516,7 +516,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case EnumTag => val sym = const.symbolValue val ownerName = internalName(sym.owner) - val fieldName = sym.name.mangledString.toString + val fieldName = sym.javaSimpleName val underlying = sym.info match { case t: TypeProxy => t.underlying case t => t @@ -705,7 +705,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // we initialize the MODULE$ field immediately after the super ctor if (!isModuleInitialized && jMethodName == INSTANCE_CONSTRUCTOR_NAME && - fun.symbol.name.mangledString.toString == INSTANCE_CONSTRUCTOR_NAME && + fun.symbol.javaSimpleName == INSTANCE_CONSTRUCTOR_NAME && claszSymbol.isStaticModuleClass) { isModuleInitialized = true mnode.visitVarInsn(asm.Opcodes.ALOAD, 0) @@ -803,7 +803,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // Emitting `def f(c: C) = c.clone()` as `Object.clone()` gives a VerifyError. val target: String = tpeTK(qual).asRefBType.classOrArrayType val methodBType = asmMethodType(sym) - bc.invokevirtual(target, sym.name.mangledString.toString, methodBType.descriptor) + bc.invokevirtual(target, sym.javaSimpleName, methodBType.descriptor) generatedType = methodBType.returnType } else { val receiverClass = if (!invokeStyle.isVirtual) null else { @@ -1158,7 +1158,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { receiverClass.info // ensure types the type is up to date; erasure may add lateINTERFACE to traits val receiverName = internalName(receiverClass) - val jname = method.name.mangledString.toString + val jname = method.javaSimpleName val bmType = asmMethodType(method) val mdescr = bmType.descriptor @@ -1447,7 +1447,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val targetHandle = new asm.Handle(invokeStyle, classBTypeFromSymbol(lambdaTarget.owner).internalName, - lambdaTarget.name.mangledString, + lambdaTarget.javaSimpleName, asmMethodType(lambdaTarget).descriptor, /* itf = */ isInterface) @@ -1473,7 +1473,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } } - val methodName = abstractMethod.name.mangledString + val methodName = abstractMethod.javaSimpleName val applyN = { val mt = asmMethodType(abstractMethod) mt.toASMType diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index a10d7bd263ef..c77c049fe3e5 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -27,6 +27,8 @@ import dotty.tools.dotc.core.TypeErasure import dotty.tools.dotc.transform.GenericSignatures import dotty.tools.io.AbstractFile +import dotty.tools.backend.jvm.DottyBackendInterface.symExtensions + /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. * @@ -369,7 +371,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case ClazzTag => av.visit(name, typeToTypeKind(const.typeValue)(bcodeStore)(innerClasesStore).toASMType) case EnumTag => val edesc = innerClasesStore.typeDescriptor(const.tpe) // the class descriptor of the enumeration class. - val evalue = const.symbolValue.name.mangledString // value the actual enumeration value. + val evalue = const.symbolValue.javaSimpleName // value the actual enumeration value. av.visitEnum(name, edesc, evalue) } case t: TypeApply if (t.fun.symbol == defn.Predef_classOf) => @@ -378,7 +380,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => val edesc = innerClasesStore.typeDescriptor(t.tpe) // the class descriptor of the enumeration class. - val evalue = t.symbol.name.mangledString // value the actual enumeration value. + val evalue = t.symbol.javaSimpleName // value the actual enumeration value. av.visitEnum(name, edesc, evalue) case t: SeqLiteral => val arrAnnotV: AnnotationVisitor = av.visitArray(name) @@ -517,7 +519,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val jReturnType = toTypeKind(methodInfo.resultType) val mdesc = MethodBType(paramJavaTypes, jReturnType).descriptor - val mirrorMethodName = m.name.mangledString.toString + val mirrorMethodName = m.javaSimpleName val mirrorMethod: asm.MethodVisitor = jclass.visitMethod( flags, mirrorMethodName, diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index d29eb717fbb7..130f07bc9fc1 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -263,7 +263,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val jfield = new asm.tree.FieldNode( flags, - f.name.mangledString.toString, + f.javaSimpleName, symInfoTK(f).descriptor, javagensig, null // no initial value @@ -404,7 +404,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { private def makeLocal(sym: Symbol, tk: BType): Local = { assert(nxtIdx != -1, "not a valid start index") - val loc = Local(tk, sym.name.mangledString.toString, nxtIdx, sym.is(Flags.Synthetic)) + val loc = Local(tk, sym.javaSimpleName, nxtIdx, sym.is(Flags.Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) ctx.error("attempt to create duplicate local var.", ctx.source.atSpan(sym.span)) @@ -545,7 +545,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { assert(mnode == null, "GenBCode detected nested method.") methSymbol = dd.symbol - jMethodName = methSymbol.name.mangledString.toString + jMethodName = methSymbol.javaSimpleName returnType = asmMethodType(dd.symbol).returnType isMethSymStaticCtor = methSymbol.isStaticConstructor @@ -659,7 +659,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { insnModA = new asm.tree.TypeInsnNode(asm.Opcodes.NEW, className) // INVOKESPECIAL val callee = methSymbol.enclosingClass.primaryConstructor - val jname = callee.name.mangledString.toString + val jname = callee.javaSimpleName val jowner = internalName(callee.owner) val jtype = asmMethodType(callee).descriptor insnModB = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESPECIAL, jowner, jname, jtype, false) @@ -681,7 +681,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // INVOKESTATIC CREATOR(): android.os.Parcelable$Creator; -- TODO where does this Android method come from? val callee = claszSymbol.companionModule.info.member(androidFieldName).symbol val jowner = internalName(callee.owner) - val jname = callee.name.mangledString.toString + val jname = callee.javaSimpleName val jtype = asmMethodType(callee).descriptor insnParcA = new asm.tree.MethodInsnNode(asm.Opcodes.INVOKESTATIC, jowner, jname, jtype, false) // PUTSTATIC `thisName`.CREATOR; diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 59466e5e4f65..32496ccd6202 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -83,7 +83,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { s"Cannot create ClassBType for special class symbol ${classSym.showFullName}") convertedClasses.getOrElse(classSym, { - val internalName = classSym.fullName.mangledString.replace('.', '/') + val internalName = classSym.javaBinaryName // We first create and add the ClassBType to the hash map before computing its info. This // allows initializing cylic dependencies, see the comment on variable ClassBType._info. val classBType = new ClassBType(internalName) @@ -240,7 +240,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { if (isAnonymousOrLocalClass(innerClassSym)) { None } else { - val outerName = innerClassSym.originalOwner.originalLexicallyEnclosingClass.fullName.mangledString.replace('.', '/') + val outerName = innerClassSym.originalOwner.originalLexicallyEnclosingClass.javaBinaryName def dropModule(str: String): String = if (!str.isEmpty && str.last == '$') str.take(str.length - 1) else str // Java compatibility. See the big comment in BTypes that summarizes the InnerClass spec. diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 3bf8cb5c7aff..0bfece08fcdc 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -162,6 +162,9 @@ object DottyBackendInterface { toDenot(sym).owner.is(Flags.PackageClass) } + def javaSimpleName(using Context): String = toDenot(sym).name.mangledString + def javaClassName(using Context): String = toDenot(sym).fullName.mangledString + def javaBinaryName(using Context): String = javaClassName.replace('.', '/') } private val primitiveCompilationUnits = Set( diff --git a/compiler/src/dotty/tools/backend/sjs/JSEncoding.scala b/compiler/src/dotty/tools/backend/sjs/JSEncoding.scala index eefa11436bbb..aa96e9121226 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSEncoding.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSEncoding.scala @@ -30,6 +30,8 @@ import ScopedVar.withScopedVars import JSDefinitions._ import JSInterop._ +import dotty.tools.backend.jvm.DottyBackendInterface.symExtensions + /** Encoding of symbol names for JavaScript * * Some issues that this encoding solves: @@ -119,7 +121,7 @@ object JSEncoding { js.LabelIdent(freshLabelName(base)) def labelSymbolName(sym: Symbol)(implicit ctx: Context): LabelName = - labelSymbolNames.getOrElseUpdate(sym, freshLabelName(sym.name.mangledString)) + labelSymbolNames.getOrElseUpdate(sym, freshLabelName(sym.javaSimpleName)) def getEnclosingReturnLabel()(implicit pos: ir.Position): js.LabelIdent = { if (returnLabelName.isEmpty) @@ -157,7 +159,7 @@ object JSEncoding { require(sym.owner.isClass && sym.isTerm && !sym.is(Flags.Method) && !sym.is(Flags.Module), "encodeFieldSym called with non-field symbol: " + sym) - val name0 = sym.name.mangledString + val name0 = sym.javaSimpleName val name = if (name0.charAt(name0.length()-1) != ' ') name0 else name0.substring(0, name0.length()-1) @@ -247,7 +249,7 @@ object JSEncoding { */ ir.Names.BoxedUnitClass } else { - ClassName(sym1.fullName.mangledString) + ClassName(sym1.javaClassName) } } diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index e4970b430506..f1c87957496b 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -20,6 +20,8 @@ import parsing.Parsers.OutlineParser import reporting.trace import ast.desugar +import dotty.tools.backend.jvm.DottyBackendInterface.symExtensions + object SymbolLoaders { import ast.untpd._ @@ -279,7 +281,7 @@ object SymbolLoaders { if (!sourceModule.isCompleted) sourceModule.completer.complete(sourceModule) - val packageName = if (root.isEffectiveRoot) "" else root.fullName.mangledString + val packageName = if (root.isEffectiveRoot) "" else root.symbol.javaClassName enterFlatClasses = Some { ctx => enterFlatClasses = None diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index 3b518c7227b1..047c010c0d9e 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -23,6 +23,7 @@ import scala.internal.Chars._ import collection.mutable import ProtoTypes._ +import dotty.tools.backend.jvm.DottyBackendInterface.symExtensions import scala.util.control.NonFatal @@ -50,7 +51,7 @@ class TreeChecker extends Phase with SymTransformer { val NoSuperClassFlags: FlagSet = Trait | Package def testDuplicate(sym: Symbol, registry: mutable.Map[String, Symbol], typ: String)(using Context): Unit = { - val name = sym.fullName.mangledString + val name = sym.javaClassName val isDuplicate = this.flatClasses && registry.contains(name) assert(!isDuplicate, s"$typ defined twice $sym ${sym.id} ${registry(name).id}") registry(name) = sym From a24625ff46527ab716a71e652f4ff076d782895a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 09:50:46 +0200 Subject: [PATCH 87/98] Import all flags in the backend --- .../tools/backend/jvm/BCodeAsmCommon.scala | 4 +-- .../tools/backend/jvm/BCodeBodyBuilder.scala | 30 ++++++++-------- .../tools/backend/jvm/BCodeHelpers.scala | 36 +++++++++---------- .../tools/backend/jvm/BCodeSkelBuilder.scala | 22 ++++++------ .../tools/backend/jvm/BTypesFromSymbols.scala | 36 +++++++++---------- .../backend/jvm/DottyBackendInterface.scala | 12 +++---- 6 files changed, 70 insertions(+), 70 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala index 7b5380b1d9b3..816fec8adaa4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala @@ -2,7 +2,7 @@ package dotty.tools package backend package jvm -import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.Symbols._ /** @@ -57,7 +57,7 @@ final class BCodeAsmCommon[I <: DottyBackendInterface](val interface: I) { assert(classSym.isClass, classSym) def enclosingMethod(sym: Symbol): Option[Symbol] = { if (sym.isClass || sym == NoSymbol) None - else if (sym.is(Flags.Method)) Some(sym) + else if (sym.is(Method)) Some(sym) else enclosingMethod(sym.originalOwner.originalLexicallyEnclosingClass) } enclosingMethod(classSym.originalOwner.originalLexicallyEnclosingClass) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 3e61ac533d0f..883c0093cb11 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -12,7 +12,7 @@ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.core.Constants._ import dotty.tools.dotc.core.Decorators._ -import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Flags.{Label => LabelFlag, _} import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.StdNames.{nme, str} import dotty.tools.dotc.core.Symbols._ @@ -353,7 +353,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { generatedType = genApply(app, expectedType) case This(qual) => - val symIsModuleClass = tree.symbol.is(Flags.ModuleClass) + val symIsModuleClass = tree.symbol.is(ModuleClass) assert(tree.symbol == claszSymbol || symIsModuleClass, s"Trying to access the this of another class: tree.symbol = ${tree.symbol}, class symbol = $claszSymbol compilation unit: $cunit") if (symIsModuleClass && tree.symbol != claszSymbol) { @@ -367,7 +367,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } case DesugaredSelect(Ident(nme.EMPTY_PACKAGE), module) => - assert(tree.symbol.is(Flags.Module), s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.span}") + assert(tree.symbol.is(Module), s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.span}") genLoadModule(tree) case DesugaredSelect(qualifier, _) => @@ -379,7 +379,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError def receiverClass = qualifier.tpe.widenDealias.typeSymbol - if (sym.is(Flags.Module)) { + if (sym.is(Module)) { genLoadQualUnlessElidable() genLoadModule(tree) } else if (sym.isStaticMember) { @@ -398,8 +398,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val desugared = cachedDesugarIdent(t) desugared match { case None => - if (!sym.is(Flags.Package)) { - if (sym.is(Flags.Module)) genLoadModule(sym) + if (!sym.is(Package)) { + if (sym.is(Module)) genLoadModule(sym) else locals.load(sym) } case Some(t) => @@ -544,7 +544,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { private def genReturn(r: Return): Unit = { val expr: Tree = r.expr - val fromSym: Symbol = if (r.from.symbol.is(Flags.Label)) r.from.symbol else NoSymbol + val fromSym: Symbol = if (r.from.symbol.is(LabelFlag)) r.from.symbol else NoSymbol if (NoSymbol == fromSym) { // return from enclosing method @@ -571,8 +571,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } } else { // return from labeled - assert(fromSym.is(Flags.Label), fromSym) - assert(!fromSym.is(Flags.Method), fromSym) + assert(fromSym.is(LabelFlag), fromSym) + assert(!fromSym.is(Method), fromSym) /* TODO At the moment, we disregard cleanups, because by construction we don't have return-from-labels * that cross cleanup boundaries. However, in theory such crossings are valid, so we should take care @@ -776,7 +776,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } else { // normal method call val invokeStyle = if (sym.isStaticMember) InvokeStyle.Static - else if (sym.is(Flags.Private) || sym.isClassConstructor) InvokeStyle.Special + else if (sym.is(Private) || sym.isClassConstructor) InvokeStyle.Special else InvokeStyle.Virtual if (invokeStyle.hasInstance) genLoadQualifier(fun) @@ -1030,7 +1030,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { def genLoadModule(tree: Tree): BType = { val module = ( - if (!tree.symbol.is(Flags.PackageClass)) tree.symbol + if (!tree.symbol.is(PackageClass)) tree.symbol else tree.symbol.info.member(nme.PACKAGE).symbol match { case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree") case s => abort(s"SI-5604: found package class where package object expected: $tree") @@ -1353,7 +1353,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * not using the rich equality is possible (their own equals method will do ok.) */ val mustUseAnyComparator: Boolean = { - val areSameFinals = l.tpe.typeSymbol.is(Flags.Final) && r.tpe.typeSymbol.is(Flags.Final) && (l.tpe =:= r.tpe) + val areSameFinals = l.tpe.typeSymbol.is(Final) && r.tpe.typeSymbol.is(Final) && (l.tpe =:= r.tpe) // todo: remove def isMaybeBoxed(sym: Symbol): Boolean = { (sym == defn.ObjectClass) || @@ -1369,7 +1369,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { case Literal(Constant(null)) => true case _ => false } - def isNonNullExpr(t: Tree): Boolean = t.isInstanceOf[Literal] || ((t.symbol ne null) && t.symbol.is(Flags.Module)) + def isNonNullExpr(t: Tree): Boolean = t.isInstanceOf[Literal] || ((t.symbol ne null) && t.symbol.is(Module)) if (mustUseAnyComparator) { val equalsMethod: Symbol = { @@ -1440,7 +1440,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val isInterface = isEmittedInterface(lambdaTarget.owner) val invokeStyle = if (lambdaTarget.isStaticMember) asm.Opcodes.H_INVOKESTATIC - else if (lambdaTarget.is(Flags.Private) || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL + else if (lambdaTarget.is(Private) || lambdaTarget.isClassConstructor) asm.Opcodes.H_INVOKESPECIAL else if (isInterface) asm.Opcodes.H_INVOKEINTERFACE else asm.Opcodes.H_INVOKEVIRTUAL @@ -1504,7 +1504,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { * which we represent as classes. */ private def isEmittedInterface(sym: Symbol): Boolean = sym.isInterface || - sym.is(Flags.JavaDefined) && (toDenot(sym).isAnnotation || sym.is(Flags.ModuleClass) && (sym.companionClass.is(Flags.PureInterface)) || sym.companionClass.is(Flags.Trait)) + sym.is(JavaDefined) && (toDenot(sym).isAnnotation || sym.is(ModuleClass) && (sym.companionClass.is(PureInterface)) || sym.companionClass.is(Trait)) } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index c77c049fe3e5..07e126df72c3 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -15,7 +15,7 @@ import dotty.tools.dotc.core.Annotations.Annotation import dotty.tools.dotc.core.Constants._ import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Decorators._ -import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.Names.Name import dotty.tools.dotc.core.NameKinds.ExpandedName import dotty.tools.dotc.core.Signature @@ -225,7 +225,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // If the `sym` is a java module class, we use the java class instead. This ensures that we // register the class (instead of the module class) in innerClassBufferASM. // The two symbols have the same name, so the resulting internalName is the same. - val classSym = if (sym.is(Flags.JavaDefined) && sym.is(Flags.ModuleClass)) sym.linkedClass else sym + val classSym = if (sym.is(JavaDefined) && sym.is(ModuleClass)) sym.linkedClass else sym getClassBTypeAndRegisterInnerClass(classSym).internalName } @@ -269,7 +269,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ final def asmMethodType(msym: Symbol): MethodBType = { - assert(msym.is(Flags.Method), s"not a method-symbol: $msym") + assert(msym.is(Method), s"not a method-symbol: $msym") val resT: BType = if (msym.isClassConstructor || msym.isConstructor) UNIT else toTypeKind(msym.info.resultType) @@ -343,7 +343,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { private def shouldEmitAnnotation(annot: Annotation): Boolean = { - annot.symbol.is(Flags.JavaDefined) && + annot.symbol.is(JavaDefined) && retentionPolicyOf(annot) != AnnotationRetentionSourceAttr } @@ -378,7 +378,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { av.visit(name, typeToTypeKind(t.args.head.tpe.classSymbol.denot.info)(bcodeStore)(innerClasesStore).toASMType) case Ident(nme.WILDCARD) => // An underscore argument indicates that we want to use the default value for this parameter, so do not emit anything - case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(Flags.JavaEnumTrait) => + case t: tpd.RefTree if t.symbol.denot.owner.isAllOf(JavaEnumTrait) => val edesc = innerClasesStore.typeDescriptor(t.tpe) // the class descriptor of the enumeration class. val evalue = t.symbol.javaSimpleName // value the actual enumeration value. av.visitEnum(name, edesc, evalue) @@ -482,7 +482,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { def getGenericSignature(sym: Symbol, owner: Symbol): String = { ctx.atPhase(ctx.erasurePhase) { val memberTpe = - if (sym.is(Flags.Method)) sym.denot.info + if (sym.is(Method)) sym.denot.info else owner.denot.thisType.memberInfo(sym) getGenericSignatureHelper(sym, owner, memberTpe).orNull } @@ -509,7 +509,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // TODO: evaluate the other flags we might be dropping on the floor here. // TODO: ACC_SYNTHETIC ? val flags = GenBCodeOps.PublicStatic | ( - if (m.is(Flags.JavaVarargs)) asm.Opcodes.ACC_VARARGS else 0 + if (m.is(JavaVarargs)) asm.Opcodes.ACC_VARARGS else 0 ) // TODO needed? for(ann <- m.annotations) { ann.symbol.initialize } @@ -563,7 +563,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def addForwarders(jclass: asm.ClassVisitor, jclassName: String, moduleClass: Symbol): Unit = { - assert(moduleClass.is(Flags.ModuleClass), moduleClass) + assert(moduleClass.is(ModuleClass), moduleClass) ctx.debuglog(s"Dumping mirror class for object: $moduleClass") val linkedClass = moduleClass.companionClass @@ -572,11 +572,11 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } ctx.debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") - for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Flags.Method, excluded = Flags.ExcludedForwarder)) { - val m = if (m0.is(Flags.Bridge)) m0.nextOverriddenSymbol else m0 + for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Method, excluded = ExcludedForwarder)) { + val m = if (m0.is(Bridge)) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) ctx.log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") - else if (m.isType || m.is(Flags.Deferred) || (m.owner eq defn.ObjectClass) || m.isConstructor || m.name.is(ExpandedName)) + else if (m.isType || m.is(Deferred) || (m.owner eq defn.ObjectClass) || m.isConstructor || m.name.is(ExpandedName)) ctx.debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") else if (conflictingNames(m.name)) ctx.log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") @@ -592,7 +592,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { /** The members of this type that have all of `required` flags but none of `excluded` flags set. * The members are sorted by name and signature to guarantee a stable ordering. */ - private def sortedMembersBasedOnFlags(tp: Type, required: Flags.Flag, excluded: Flags.FlagSet): List[Symbol] = { + private def sortedMembersBasedOnFlags(tp: Type, required: Flag, excluded: FlagSet): List[Symbol] = { // The output of `memberNames` is a Set, sort it to guarantee a stable ordering. val names = tp.memberNames(takeAllFilter).toSeq.sorted val buffer = mutable.ListBuffer[Symbol]() @@ -667,7 +667,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def genMirrorClass(moduleClass: Symbol, cunit: CompilationUnit): asm.tree.ClassNode = { - assert(moduleClass.is(Flags.ModuleClass)) + assert(moduleClass.is(ModuleClass)) assert(moduleClass.companionClass == NoSymbol, moduleClass) innerClassBufferASM.clear() this.cunit = cunit @@ -690,7 +690,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { null /* SourceDebugExtension */) } - val ssa = None // getAnnotPickle(mirrorName, if (moduleClass.is(Flags.Module)) moduleClass.companionClass else moduleClass.companionModule) + val ssa = None // getAnnotPickle(mirrorName, if (moduleClass.is(Module)) moduleClass.companionClass else moduleClass.companionModule) mirrorClass.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) emitAnnotations(mirrorClass, moduleClass.annotations ++ ssa) @@ -892,7 +892,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } wrap { - if (sym.is(Flags.Method)) { + if (sym.is(Method)) { CheckClassAdapter.checkMethodSignature(sig) } else if (sym.isTerm) { @@ -914,9 +914,9 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // generic information could disappear as a consequence of a seemingly // unrelated change. ctx.base.settings.YnoGenericSig.value - || sym.is(Flags.Artifact) - || sym.isAllOf(Flags.LiftedMethod) - || sym.is(Flags.Bridge) + || sym.is(Artifact) + || sym.isAllOf(LiftedMethod) + || sym.is(Bridge) ) private def getStaticForwarderGenericSignature(sym: Symbol, moduleClass: Symbol): String = { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 130f07bc9fc1..fd88204acf06 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -13,7 +13,7 @@ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.core.Annotations.Annotation import dotty.tools.dotc.core.Decorators._ -import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.StdNames.str import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types.Type @@ -106,7 +106,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { initJClass(cnode) - val methodSymbols = for (f <- cd.symbol.info.decls.toList if f.is(Flags.Method) && f.isTerm && !f.is(Flags.Module)) yield f + val methodSymbols = for (f <- cd.symbol.info.decls.toList if f.is(Method) && f.isTerm && !f.is(Module)) yield f val hasStaticCtor = methodSymbols exists (_.isStaticConstructor) if (!hasStaticCtor) { // but needs one ... @@ -117,7 +117,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val optSerial: Option[Long] = claszSymbol.getAnnotation(defn.SerialVersionUIDAnnot).flatMap { annot => - if (claszSymbol.is(Flags.Trait)) { + if (claszSymbol.is(Trait)) { ctx.error("@SerialVersionUID does nothing on a trait", annot.tree.sourcePos) None } else { @@ -184,13 +184,13 @@ trait BCodeSkelBuilder extends BCodeHelpers { } else { - val skipStaticForwarders = (claszSymbol.isInterface || claszSymbol.is(Flags.Module) || ctx.settings.XnoForwarders.value) + val skipStaticForwarders = (claszSymbol.isInterface || claszSymbol.is(Module) || ctx.settings.XnoForwarders.value) if (!skipStaticForwarders) { val lmoc = claszSymbol.companionModule // add static forwarders if there are no name conflicts; see bugs #363 and #1735 if (lmoc != NoSymbol) { // it must be a top level class (name contains no $s) - val isCandidateForForwarders = (lmoc.is(Flags.Module)) && lmoc.isStatic + val isCandidateForForwarders = (lmoc.is(Module)) && lmoc.isStatic if (isCandidateForForwarders) { ctx.log(s"Adding static forwarders from '$claszSymbol' to implementations in '$lmoc'") addForwarders(cnode, thisName, lmoc.moduleClass) @@ -254,11 +254,11 @@ trait BCodeSkelBuilder extends BCodeHelpers { * backend emits them as static). * No code is needed for this module symbol. */ - for (f <- claszSymbol.info.decls.filter(p => p.isTerm && !p.is(Flags.Method))) { + for (f <- claszSymbol.info.decls.filter(p => p.isTerm && !p.is(Method))) { val javagensig = getGenericSignature(f, claszSymbol) val flags = javaFieldFlags(f) - assert(!f.isStaticMember || !claszSymbol.isInterface || !f.is(Flags.Mutable), + assert(!f.isStaticMember || !claszSymbol.isInterface || !f.is(Mutable), s"interface $claszSymbol cannot have non-final static field $f") val jfield = new asm.tree.FieldNode( @@ -305,7 +305,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ var jumpDest: immutable.Map[ /* Labeled or LabelDef */ Symbol, asm.Label ] = null def programPoint(labelSym: Symbol): asm.Label = { - assert(labelSym.is(Flags.Label), s"trying to map a non-label symbol to an asm.Label, at: ${labelSym.span}") + assert(labelSym.is(Label), s"trying to map a non-label symbol to an asm.Label, at: ${labelSym.span}") jumpDest.getOrElse(labelSym, { val pp = new asm.Label jumpDest += (labelSym -> pp) @@ -388,7 +388,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { */ def makeLocal(tk: BType, name: String, tpe: Type, pos: Span): Symbol = { - val locSym = ctx.newSymbol(methSymbol, name.toTermName, Flags.Synthetic, tpe, NoSymbol, pos) + val locSym = ctx.newSymbol(methSymbol, name.toTermName, Synthetic, tpe, NoSymbol, pos) makeLocal(locSym, tk) locSym } @@ -404,7 +404,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { private def makeLocal(sym: Symbol, tk: BType): Local = { assert(nxtIdx != -1, "not a valid start index") - val loc = Local(tk, sym.javaSimpleName, nxtIdx, sym.is(Flags.Synthetic)) + val loc = Local(tk, sym.javaSimpleName, nxtIdx, sym.is(Synthetic)) val existing = slots.put(sym, loc) if (existing.isDefined) ctx.error("attempt to create duplicate local var.", ctx.source.atSpan(sym.span)) @@ -565,7 +565,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { } val isNative = methSymbol.hasAnnotation(NativeAttr) - val isAbstractMethod = (methSymbol.is(Flags.Deferred) || (methSymbol.owner.isInterface && ((methSymbol.is(Flags.Deferred)) || methSymbol.isClassConstructor))) + val isAbstractMethod = (methSymbol.is(Deferred) || (methSymbol.owner.isInterface && ((methSymbol.is(Deferred)) || methSymbol.isClassConstructor))) val flags = GenBCodeOps.mkFlags( javaFlags(methSymbol), if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0, diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 32496ccd6202..9bf597ce99fb 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -7,7 +7,7 @@ import scala.annotation.threadUnsafe import scala.collection.mutable import scala.collection.generic.Clearable -import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Phases.Phase import dotty.tools.dotc.transform.SymUtils._ @@ -96,7 +96,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val superClassSym: Symbol = { val t = classSym.asClass.superClass if (t.exists) t - else if (classSym.is(Flags.ModuleClass)) { + else if (classSym.is(ModuleClass)) { // workaround #371 println(s"Warning: mocking up superclass for $classSym") @@ -126,7 +126,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { val directlyInheritedTraitsSet = directlyInheritedTraits.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)) + val additional = (superCalls -- directlyInheritedTraitsSet).filter(_.is(Trait)) // if (additional.nonEmpty) // println(s"$fullName: adding supertraits $additional") directlyInheritedTraits.filter(t => !allBaseClasses(t) || superCalls(t)) ++ additional @@ -181,7 +181,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { * Here we get rid of the module class B, making sure that the class B is present. */ val nestedClassSymbolsNoJavaModuleClasses = nestedClassSymbols.filter(s => { - if (s.is(Flags.JavaDefined) && s.is(Flags.ModuleClass)) { + if (s.is(JavaDefined) && s.is(ModuleClass)) { // We could also search in nestedClassSymbols for s.linkedClassOfClass, but sometimes that // returns NoSymbol, so it doesn't work. val nb = nestedClassSymbols.count(mc => mc.name == s.name && mc.owner == s.owner) @@ -219,7 +219,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = { assert(innerClassSym.isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym") - val isNested = !innerClassSym.originalOwner.originalLexicallyEnclosingClass.is(Flags.PackageClass) + val isNested = !innerClassSym.originalOwner.originalLexicallyEnclosingClass.is(PackageClass) if (!isNested) None else { // See comment in BTypes, when is a class marked static in the InnerClass table. @@ -273,7 +273,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { * the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here. */ private def (sym: Symbol).isOriginallyStaticOwner: Boolean = - sym.is(Flags.PackageClass) || sym.is(Flags.ModuleClass) && sym.originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner + sym.is(PackageClass) || sym.is(ModuleClass) && sym.originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner /** * Return the Java modifiers for the given symbol. @@ -296,14 +296,14 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { final def javaFlags(sym: Symbol): Int = { - val privateFlag = sym.is(Flags.Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) + val privateFlag = sym.is(Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) - val finalFlag = sym.is(Flags.Final) && !toDenot(sym).isClassConstructor && !(sym.is(Flags.Mutable)) && !(sym.enclosingClass.is(Flags.Trait)) + val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !(sym.is(Mutable)) && !(sym.enclosingClass.is(Trait)) import asm.Opcodes._ GenBCodeOps.mkFlags( if (privateFlag) ACC_PRIVATE else ACC_PUBLIC, - if (sym.is(Flags.Deferred) || sym.isOneOf(Flags.AbstractOrTrait)) ACC_ABSTRACT else 0, + if (sym.is(Deferred) || sym.isOneOf(AbstractOrTrait)) ACC_ABSTRACT else 0, if (sym.isInterface) ACC_INTERFACE else 0, if (finalFlag && @@ -311,19 +311,19 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { // without having to provide any implementations, but that is an // illegal combination of modifiers at the bytecode level so // suppress final if abstract if present. - !sym.isOneOf(Flags.AbstractOrTrait) && + !sym.isOneOf(AbstractOrTrait) && // Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks - !sym.is(Flags.Bridge)) + !sym.is(Bridge)) ACC_FINAL else 0, if (sym.isStaticMember) ACC_STATIC else 0, - if (sym.is(Flags.Bridge)) ACC_BRIDGE | ACC_SYNTHETIC else 0, - if (sym.is(Flags.Artifact)) ACC_SYNTHETIC else 0, + if (sym.is(Bridge)) ACC_BRIDGE | ACC_SYNTHETIC else 0, + if (sym.is(Artifact)) ACC_SYNTHETIC else 0, if (sym.isClass && !sym.isInterface) ACC_SUPER else 0, - if (sym.isAllOf(Flags.JavaEnumTrait)) ACC_ENUM else 0, - if (sym.is(Flags.JavaVarargs)) ACC_VARARGS else 0, - if (sym.is(Flags.Synchronized)) ACC_SYNCHRONIZED else 0, + if (sym.isAllOf(JavaEnumTrait)) ACC_ENUM else 0, + if (sym.is(JavaVarargs)) ACC_VARARGS else 0, + if (sym.is(Synchronized)) ACC_SYNCHRONIZED else 0, if (false /*sym.isDeprecated*/) asm.Opcodes.ACC_DEPRECATED else 0, // TODO: add an isDeprecated method in SymUtils - if (sym.is(Flags.Enum)) asm.Opcodes.ACC_ENUM else 0 + if (sym.is(Enum)) asm.Opcodes.ACC_ENUM else 0 ) } @@ -331,7 +331,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { javaFlags(sym) | GenBCodeOps.mkFlags( if (sym hasAnnotation TransientAttr) asm.Opcodes.ACC_TRANSIENT else 0, if (sym hasAnnotation VolatileAttr) asm.Opcodes.ACC_VOLATILE else 0, - if (sym.is(Flags.Mutable)) 0 else asm.Opcodes.ACC_FINAL + if (sym.is(Mutable)) 0 else asm.Opcodes.ACC_FINAL ) } } diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 0bfece08fcdc..467d25d0ab83 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -3,7 +3,7 @@ package dotty.tools.backend.jvm import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.ast.Trees import dotty.tools.dotc -import dotty.tools.dotc.core.Flags.{termFlagSet} +import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.transform.{Erasure, GenericSignatures} import dotty.tools.dotc.transform.SymUtils._ import java.io.{File => _} @@ -118,12 +118,12 @@ object DottyBackendInterface { extension symExtensions on (sym: Symbol) { - def isInterface(using Context): Boolean = (sym.is(Flags.PureInterface)) || sym.is(Flags.Trait) + def isInterface(using Context): Boolean = (sym.is(PureInterface)) || sym.is(Trait) def isStaticConstructor(using Context): Boolean = (sym.isStaticMember && sym.isClassConstructor) || (sym.name eq nme.STATIC_CONSTRUCTOR) def isStaticMember(using Context): Boolean = (sym ne NoSymbol) && - (sym.is(Flags.JavaStatic) || sym.isScalaStatic) + (sym.is(JavaStatic) || sym.isScalaStatic) // guard against no sumbol cause this code is executed to select which call type(static\dynamic) to use to call array.clone /** @@ -131,7 +131,7 @@ object DottyBackendInterface { * for such objects will get a MODULE$ flag and a corresponding static initializer. */ def isStaticModuleClass(using Context): Boolean = - (sym.is(Flags.Module)) && { + (sym.is(Module)) && { // scalac uses atPickling here // this would not work if modules are created after pickling // for example by specialization @@ -157,9 +157,9 @@ object DottyBackendInterface { * such objects. */ def isTopLevelModuleClass(using Context): Boolean = - sym.is(Flags.ModuleClass) && + sym.is(ModuleClass) && ctx.atPhase(ctx.flattenPhase) { - toDenot(sym).owner.is(Flags.PackageClass) + toDenot(sym).owner.is(PackageClass) } def javaSimpleName(using Context): String = toDenot(sym).name.mangledString From ea5fb1f29b7825da8c5ef4dc3f5e5964b38ec10c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 09:54:05 +0200 Subject: [PATCH 88/98] Remove redundant extraction --- .../src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 883c0093cb11..d87030869f04 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -782,11 +782,8 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (invokeStyle.hasInstance) genLoadQualifier(fun) genLoadArguments(args, paramTKs(app)) - val DesugaredSelect(qual, _) = fun // fun is a Select, also checked in genLoadQualifier - val isArrayClone = fun match { - case DesugaredSelect(qual, nme.clone_) if qual.tpe.widen.isInstanceOf[JavaArrayType] => true - case _ => false - } + val DesugaredSelect(qual, name) = fun // fun is a Select, also checked in genLoadQualifier + val isArrayClone = name == nme.clone_ && qual.tpe.widen.isInstanceOf[JavaArrayType] if (isArrayClone) { // Special-case Array.clone, introduced in 36ef60e. The goal is to generate this call // as "[I.clone" instead of "java/lang/Object.clone". This is consistent with javac. From 8d9fa9c3f6fa8aef9cda4a3e53cda91b848d3085 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 10:02:18 +0200 Subject: [PATCH 89/98] Avoid list allocation --- compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index fd88204acf06..9f76075fae0d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -106,7 +106,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { initJClass(cnode) - val methodSymbols = for (f <- cd.symbol.info.decls.toList if f.is(Method) && f.isTerm && !f.is(Module)) yield f + val methodSymbols = for (f <- cd.symbol.info.decls.iterator if f.is(Method) && f.isTerm && !f.is(Module)) yield f val hasStaticCtor = methodSymbols exists (_.isStaticConstructor) if (!hasStaticCtor) { // but needs one ... From d67e1f4891362a5967536414196cfb8f993e59fe Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 10:11:35 +0200 Subject: [PATCH 90/98] Add TODOs --- compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 4 ++-- compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index d87030869f04..43fb0ce3c432 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -331,7 +331,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } val (fun, args) = call match { case Apply(fun, args) => (fun, args) - case t @ DesugaredSelect(_, _) => (t, Nil) + case t @ DesugaredSelect(_, _) => (t, Nil) // TODO: use Select case t @ Ident(_) => (t, Nil) } @@ -517,7 +517,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { val sym = const.symbolValue val ownerName = internalName(sym.owner) val fieldName = sym.javaSimpleName - val underlying = sym.info match { + val underlying = sym.info match { // TODO: Is this actually necessary? Could it be replaced by a call to widen? case t: TypeProxy => t.underlying case t => t } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 9f76075fae0d..06e766ea653c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -174,7 +174,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { case _ => () } - val ssa = None // getAnnotPickle(thisName, claszSymbol) + val ssa = None // TODO: inlined form `getAnnotPickle(thisName, claszSymbol)`. Should something be done on Dotty? cnode.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign) emitAnnotations(cnode, claszSymbol.annotations ++ ssa) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala index 0f2c1707d342..60ceda5fa8b2 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSyncAndTry.scala @@ -410,7 +410,7 @@ trait BCodeSyncAndTry extends BCodeBodyBuilder { } /* Does this tree have a try-catch block? */ - def mayCleanStack(tree: Tree): Boolean = tree.find { t => t match { + def mayCleanStack(tree: Tree): Boolean = tree.find { t => t match { // TODO: use existsSubTree case Try(_, _, _) => true case _ => false } From 51ee1da10e481ea345e2307b07f42e7b6aaa2db6 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 8 Jun 2020 15:13:00 +0200 Subject: [PATCH 91/98] Revert "Avoid list allocation" This reverts commit 8d9fa9c3f6fa8aef9cda4a3e53cda91b848d3085. --- compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 06e766ea653c..e86f8455a8c8 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -106,7 +106,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { initJClass(cnode) - val methodSymbols = for (f <- cd.symbol.info.decls.iterator if f.is(Method) && f.isTerm && !f.is(Module)) yield f + val methodSymbols = for (f <- cd.symbol.info.decls.toList if f.is(Method) && f.isTerm && !f.is(Module)) yield f val hasStaticCtor = methodSymbols exists (_.isStaticConstructor) if (!hasStaticCtor) { // but needs one ... From 20b404d782b3eac15959f2fd6d00d9eb68d4205d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 9 Jun 2020 17:14:13 +0200 Subject: [PATCH 92/98] Use isBottom class --- compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 43fb0ce3c432..ff97bb307d3b 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -1124,7 +1124,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (specificReceiver != null) assert(style.isVirtual || specificReceiver == methodOwner, s"specificReceiver can only be specified for virtual calls. $method - $specificReceiver") - val useSpecificReceiver = specificReceiver != null && (specificReceiver ne defn.NullClass) && (specificReceiver ne defn.NothingClass) && !method.isScalaStatic + val useSpecificReceiver = specificReceiver != null && !defn.isBottomClass(specificReceiver) && !method.isScalaStatic val receiver = if (useSpecificReceiver) specificReceiver else methodOwner // workaround for a JVM bug: https://bugs.openjdk.java.net/browse/JDK-8154587 From 33b7aa8fd77f6357768b56e6e09543fce61a4827 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 9 Jun 2020 17:16:11 +0200 Subject: [PATCH 93/98] Remove unnecessary casts --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 07e126df72c3..1582d1c5d6e1 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -301,7 +301,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { for(annot <- annotations; if shouldEmitAnnotation(annot)) { val typ = annot.tree.tpe val assocs = assocsFromApply(annot.tree) - val av = cw.visitAnnotation(typeDescriptor(typ.asInstanceOf[Type]), isRuntimeVisible(annot)) + val av = cw.visitAnnotation(typeDescriptor(typ), isRuntimeVisible(annot)) emitAssocs(av, assocs, BCodeHelpers.this)(this) } @@ -312,7 +312,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { for(annot <- annotations; if shouldEmitAnnotation(annot)) { val typ = annot.tree.tpe val assocs = assocsFromApply(annot.tree) - val av = mw.visitAnnotation(typeDescriptor(typ.asInstanceOf[Type]), isRuntimeVisible(annot)) + val av = mw.visitAnnotation(typeDescriptor(typ), isRuntimeVisible(annot)) emitAssocs(av, assocs, BCodeHelpers.this)(this) } @@ -323,7 +323,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { for(annot <- annotations; if shouldEmitAnnotation(annot)) { val typ = annot.tree.tpe val assocs = assocsFromApply(annot.tree) - val av = fw.visitAnnotation(typeDescriptor(typ.asInstanceOf[Type]), isRuntimeVisible(annot)) + val av = fw.visitAnnotation(typeDescriptor(typ), isRuntimeVisible(annot)) emitAssocs(av, assocs, BCodeHelpers.this)(this) } From 7f233385f5ba8ed0df5ae9b41b353b5c3934b2e7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 9 Jun 2020 17:36:19 +0200 Subject: [PATCH 94/98] Update comment --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 1582d1c5d6e1..9d368ab6efdc 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -531,9 +531,9 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { emitAnnotations(mirrorMethod, others) val params: List[Symbol] = Nil // backend uses this to emit annotations on parameter lists of forwarders // to static methods of companion class - // in Dotty this link does not exists: there is no way to get from method type + // Old assumption: in Dotty this link does not exists: there is no way to get from method type // to inner symbols of DefDef - // todo: somehow handle. + // TODO: now we have paramSymss and could use it here. emitParamAnnotations(mirrorMethod, params.map(_.annotations)) mirrorMethod.visitCode() From 5385a82cf970f689ae0c7ac4eef04f5fee16d896 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 9 Jun 2020 17:38:13 +0200 Subject: [PATCH 95/98] Use denot name directly --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 9d368ab6efdc..b9d389cd14d8 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -568,7 +568,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val linkedClass = moduleClass.companionClass lazy val conflictingNames: Set[Name] = { - (linkedClass.info.allMembers.map(_.symbol) collect { case sym if sym.name.isTermName => sym.name }).toSet + (linkedClass.info.allMembers.collect { case d if d.name.isTermName => d.name }).toSet } ctx.debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") From 3e3613414a82bf22627249db02763561706e8474 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 9 Jun 2020 17:43:53 +0200 Subject: [PATCH 96/98] Factor out compilingArray --- .../src/dotty/tools/backend/jvm/BCodeHelpers.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index b9d389cd14d8..3035cde9cf6f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -231,7 +231,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { private def assertClassNotArray(sym: Symbol): Unit = { assert(sym.isClass, sym) - assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) + assert(sym != defn.ArrayClass || compilingArray, sym) } private def assertClassNotArrayNotPrimitive(sym: Symbol): Unit = { @@ -795,7 +795,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { */ def primitiveOrClassToBType(sym: Symbol): BType = { assert(sym.isClass, sym) - assert(sym != defn.ArrayClass || ctx.compilationUnit.source.file.name == "Array.scala", sym) + assert(sym != defn.ArrayClass || compilingArray, sym) primitiveTypeMap.getOrElse(sym, storage.getClassBTypeAndRegisterInnerClass(sym)).asInstanceOf[BType] } @@ -805,7 +805,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * signatures, e.g. `def apply(i: Int): T`. A TyperRef to T is replaced by ObjectReference. */ def nonClassTypeRefToBType(sym: Symbol): ClassBType = { - assert(sym.isType && ctx.compilationUnit.source.file.name == "Array.scala", sym) + assert(sym.isType && compilingArray, sym) ObjectReference.asInstanceOf[ct.bTypes.ClassBType] } @@ -937,6 +937,9 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ctx.error(msg) throw new RuntimeException(msg) } + + private def compilingArray(using ctx: Context) = + ctx.compilationUnit.source.file.name == "Array.scala" } object BCodeHelpers { @@ -957,4 +960,5 @@ object BCodeHelpers { val Special = new InvokeStyle(2) // InvokeSpecial (private methods, constructors) val Super = new InvokeStyle(3) // InvokeSpecial (super calls) } + } From 821399345a91b698fd6bad04caf571f5d8330d20 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 9 Jun 2020 17:47:07 +0200 Subject: [PATCH 97/98] Remove ExistentialType logic --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 9 --------- 1 file changed, 9 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 3035cde9cf6f..2c1e7c093e51 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -828,15 +828,6 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { ctx.debuglog(s"typeKind of annotated type $a") typeToTypeKind(t)(ct)(storage) - /* ExistentialType should (probably) be eliminated by erasure. We know they get here for - * classOf constants: - * class C[T] - * class T { final val k = classOf[C[_]] } - */ - /* case e @ ExistentialType(_, t) => - debuglog(s"typeKind of existential type $e") - t.toTypeKind(ctx)(storage)*/ - /* The cases below should probably never occur. They are kept for now to avoid introducing * new compiler crashes, but we added a warning. The compiler / library bootstrap and the * test suite don't produce any warning. From bf7b5b33c0cee6dd7308410d89f1918c4e8ee68f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 9 Jun 2020 17:49:36 +0200 Subject: [PATCH 98/98] Add TODO --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 2c1e7c093e51..ddd50a933193 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -614,6 +614,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * must-single-thread */ def getExceptions(excs: List[Annotation]): List[String] = { + // TODO: implement ThrownException // for (ThrownException(exc) <- excs.distinct) // yield internalName(exc) Nil