@@ -18,6 +18,7 @@ import scala.reflect.io.AbstractFile
18
18
import scala .tools .tasty .{TastyName , TastyFlags }, TastyFlags ._ , TastyName .ObjectName
19
19
import scala .tools .nsc .tasty .{TastyUniverse , TastyModes , SafeEq }, TastyModes ._
20
20
import scala .reflect .internal .MissingRequirementError
21
+ import scala .collection .mutable
21
22
22
23
trait ContextOps { self : TastyUniverse =>
23
24
import self .{symbolTable => u }, u .{internal => ui }
@@ -67,6 +68,25 @@ trait ContextOps { self: TastyUniverse =>
67
68
final def ignoreAnnotations : Boolean = u.settings.YtastyNoAnnotations
68
69
final def verboseDebug : Boolean = u.settings.debug
69
70
71
+ def isScala3Macro (sym : Symbol ): Boolean = isScala3Inline(sym) && sym.is(Macro )
72
+ def isScala3Inline (sym : Symbol ): Boolean = sym.completer.tastyFlagSet.is(Inline )
73
+ def isScala2Macro (sym : Symbol ): Boolean = sym.completer.tastyFlagSet.is(Erased ) && sym.is(Macro )
74
+
75
+ def isLatentCandidate (sym : Symbol ): Boolean = isScala3Inline(sym) || isScala2Macro(sym)
76
+
77
+ def canEnter (decl : Symbol ): Boolean = ! isScala3Macro(decl)
78
+ def enter (clazz : Symbol , decl : Symbol ): Unit = enter(clazz.rawInfo.decls, decl)
79
+ private [ContextOps ] def enter (decls : u.Scope , decl : Symbol ): Unit = {
80
+ if (allowsOverload(decl)) {
81
+ if (canEnterOverload(decl)) {
82
+ decls.enter(decl)
83
+ }
84
+ }
85
+ else {
86
+ decls.enterIfNew(decl)
87
+ }
88
+ }
89
+
70
90
def canEnterOverload (decl : Symbol ): Boolean = {
71
91
! (decl.isModule && isSymbol(findObject(decl.name)))
72
92
}
@@ -92,6 +112,9 @@ trait ContextOps { self: TastyUniverse =>
92
112
def source : AbstractFile
93
113
def mode : TastyMode
94
114
115
+ def registerLatent (sym : Symbol ): Unit
116
+ def enterLatents (): Unit
117
+
95
118
private final def loadingMirror : u.Mirror = u.mirrorThatLoaded(owner)
96
119
97
120
final def requiredPackage (fullname : TastyName ): Symbol = {
@@ -390,11 +413,46 @@ trait ContextOps { self: TastyUniverse =>
390
413
final class InitialContext (val topLevelClass : Symbol , val source : AbstractFile ) extends Context {
391
414
def mode : TastyMode = EmptyTastyMode
392
415
def owner : Symbol = topLevelClass.owner
416
+ def registerLatent (sym : Symbol ): Unit = ()
417
+ def enterLatents (): Unit = ()
393
418
}
394
419
395
420
final class FreshContext (val owner : Symbol , val outer : Context , val mode : TastyMode ) extends Context {
396
421
private [this ] var mySource : AbstractFile = null
422
+ private [this ] var myLatentDefs : mutable.ArrayBuffer [Symbol ] = null
423
+ private [this ] var myMacros : mutable.ArrayBuffer [Symbol ] = null
397
424
def atSource (source : AbstractFile ): this .type = { mySource = source ; this }
398
425
def source : AbstractFile = if (mySource == null ) outer.source else mySource
426
+ def registerLatent (sym : Symbol ): Unit = {
427
+ if (isScala2Macro(sym)) {
428
+ val macros = {
429
+ if (myMacros == null ) myMacros = mutable.ArrayBuffer .empty
430
+ myMacros
431
+ }
432
+ macros += sym
433
+ } else {
434
+ val defs = {
435
+ if (myLatentDefs == null ) myLatentDefs = mutable.ArrayBuffer .empty
436
+ myLatentDefs
437
+ }
438
+ defs += sym
439
+ }
440
+ }
441
+ def enterLatents (): Unit = {
442
+ for {
443
+ owner <- Option .when(owner.isClass)(owner)
444
+ defs <- Option (myLatentDefs)
445
+ } {
446
+ val macros = Option (myMacros).getOrElse(mutable.ArrayBuffer .empty)
447
+ val decls = owner.rawInfo.decls
448
+ for (d <- defs if ! macros.exists(_.name == d.name)) {
449
+ enter(decls, d)
450
+ }
451
+ defs.clear()
452
+ macros.clear()
453
+ }
454
+ myLatentDefs = null
455
+ myMacros = null
456
+ }
399
457
}
400
458
}
0 commit comments