|
1 | | -package dotty.tools.dotc |
| 1 | +package dotty.tools |
| 2 | +package dotc |
2 | 3 | package core |
3 | 4 |
|
4 | | -import Contexts._, Symbols._, Types._, Flags._, Scopes._, Decorators._, NameOps._ |
| 5 | +import Contexts._, Symbols._, Types._, Flags._, Scopes._, Decorators._, Names._, NameOps._ |
5 | 6 | import Denotations._ |
6 | | -import SymDenotations.LazyType, Names.Name, StdNames.nme |
| 7 | +import SymDenotations.{LazyType, SymDenotation}, Names.Name, StdNames.nme |
| 8 | +import config.Config |
| 9 | +import ast.untpd |
7 | 10 |
|
8 | 11 | /** Operations that are shared between Namer and TreeUnpickler */ |
9 | 12 | object NamerOps: |
@@ -57,4 +60,101 @@ object NamerOps: |
57 | 60 | else NoSymbol.assertingErrorsReported(s"no companion $name in $scope") |
58 | 61 | } |
59 | 62 |
|
| 63 | + private val noAppliesNeededFlags = Abstract | Trait | Case | Synthetic | Module |
| 64 | + val CreatorCompanionFlags = Synthetic | CreatorProxy |
| 65 | + val applyProxyFlags = Synthetic | CreatorProxy | Inline | Method |
| 66 | + |
| 67 | + def needsCreatorCompanion(cls: Symbol)(using Context): Boolean = |
| 68 | + Config.addCreatorCompanions |
| 69 | + && cls.isClass |
| 70 | + && !cls.flagsUNSAFE.isOneOf(noAppliesNeededFlags) |
| 71 | + && !cls.isAnonymousClass |
| 72 | + |
| 73 | + class ApplyProxyCompleter(constr: Symbol)(using Context) extends LazyType: |
| 74 | + def complete(denot: SymDenotation)(using Context): Unit = |
| 75 | + denot.info = constr.info |
| 76 | + |
| 77 | + def addCreatorMethods(scope: MutableScope, cls: ClassSymbol, modcls: ClassSymbol)(using Context): scope.type = |
| 78 | + def creatorProxy(constr: Symbol): Symbol = |
| 79 | + newSymbol( |
| 80 | + modcls, nme.apply, applyProxyFlags | (constr.flagsUNSAFE & AccessFlags), |
| 81 | + ApplyProxyCompleter(constr), coord = constr.coord) |
| 82 | + //.showing(i"created apply ${result.showLocated}") |
| 83 | + if Config.addCreatorApplies then |
| 84 | + for dcl <- cls.info.decls do |
| 85 | + if dcl.isConstructor then scope.enter(creatorProxy(dcl)) |
| 86 | + scope |
| 87 | + end addCreatorMethods |
| 88 | + |
| 89 | + def creatorCompanionCompleter(cls: ClassSymbol)( |
| 90 | + modul: TermSymbol, modcls: ClassSymbol)(using Context): LazyType = |
| 91 | + new LazyType with SymbolLoaders.SecondCompleter { |
| 92 | + def complete(denot: SymDenotation)(using Context): Unit = |
| 93 | + val prefix = modcls.owner.thisType |
| 94 | + denot.info = ClassInfo( |
| 95 | + prefix, modcls, defn.AnyType :: Nil, |
| 96 | + addCreatorMethods(newScope, cls, modcls), TermRef(prefix, modul)) |
| 97 | + }.withSourceModule(modul) |
| 98 | + |
| 99 | + def creatorCompanion(cls: ClassSymbol)(using Context): TermSymbol = |
| 100 | + val companion = newModuleSymbol( |
| 101 | + cls.owner, cls.name.toTermName, |
| 102 | + CreatorCompanionFlags, CreatorCompanionFlags, |
| 103 | + creatorCompanionCompleter(cls), coord = cls.coord) |
| 104 | + companion.moduleClass.registerCompanion(cls) |
| 105 | + cls.registerCompanion(companion.moduleClass) |
| 106 | + companion |
| 107 | + //.showing(i"created creator companion $companion") |
| 108 | +/* |
| 109 | + if needsCreatorCompanion(cls) && !cls.linkedClass.exists then |
| 110 | + val companion = newModuleSymbol( |
| 111 | + cls.owner, cls.name.toTermName, |
| 112 | + CreatorCompanionFlags, CreatorCompanionFlags, |
| 113 | + creatorCompanionCompleter(cls), coord = cls.coord).entered |
| 114 | + companion.moduleClass.registerCompanion(cls) |
| 115 | + cls.registerCompanion(companion.moduleClass) |
| 116 | + println(i"created proxy companion $companion") |
| 117 | +
|
| 118 | + def ensureApplyProxyCompanion(cls: ClassSymbol)(using Context): Unit = |
| 119 | + println(i"ensure proxy companion $cls ${cls.flagsString}") |
| 120 | + if needsCreatorCompanion(cls) && !cls.linkedClass.exists then |
| 121 | +
|
| 122 | + val companion = newModuleSymbol( |
| 123 | + cls.owner, cls.name.toTermName, |
| 124 | + applyProxyCompanionFlags, applyProxyCompanionFlags, |
| 125 | + applyProxyCompanionCompleter(cls), coord = cls.coord).entered |
| 126 | + companion.moduleClass.registerCompanion(cls) |
| 127 | + cls.registerCompanion(companion.moduleClass) |
| 128 | + println(i"created proxy companion $companion") |
| 129 | +*/ |
| 130 | + |
| 131 | + /** For all nested classes without companion objects |
| 132 | + * add a companion object. For all constructors, add an apply method. |
| 133 | + */ |
| 134 | + def addCreatorDefs(cls: ClassSymbol)(using Context): Unit = |
| 135 | + //println(i"add creator defs $cls / ${}") |
| 136 | + def memberExists(cls: ClassSymbol, name: TermName): Boolean = |
| 137 | + cls.baseClasses.exists(_.info.decls.lookupEntry(name) != null) |
| 138 | + for mbr <- cls.info.decls do |
| 139 | + if needsCreatorCompanion(mbr) |
| 140 | + && !mbr.asClass.unforcedRegisteredCompanion.exists |
| 141 | + && !memberExists(cls, mbr.name.toTermName) |
| 142 | + then |
| 143 | + creatorCompanion(mbr.asClass).entered |
| 144 | + |
| 145 | + if cls.is(Module) |
| 146 | + && needsCreatorCompanion(cls.linkedClass) |
| 147 | + && !memberExists(cls, nme.apply) |
| 148 | + then |
| 149 | + addCreatorMethods(cls.info.decls.openForMutations, cls.linkedClass.asClass, cls) |
| 150 | + end addCreatorDefs |
| 151 | + |
| 152 | + def makeCreatorCompanion(modul: TermSymbol, cls: ClassSymbol)(using Context): Unit = |
| 153 | + val modcls = modul.moduleClass.asClass |
| 154 | + modul.setFlag(CreatorCompanionFlags) |
| 155 | + modcls.setFlag(CreatorCompanionFlags) |
| 156 | + modcls.info = creatorCompanionCompleter(cls)(modul, modcls) |
| 157 | + cls.registeredCompanion = modcls |
| 158 | + modcls.registeredCompanion = cls |
| 159 | + |
60 | 160 | end NamerOps |
0 commit comments