Skip to content

Commit b0b5a26

Browse files
Improve module method checks (#283)
1 parent 4e1d3cf commit b0b5a26

File tree

148 files changed

+633
-444
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+633
-444
lines changed

hkmc2/shared/src/main/scala/hkmc2/codegen/Block.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ final case class ClsLikeDefn(
357357

358358
final case class Handler(
359359
sym: BlockMemberSymbol,
360-
resumeSym: LocalSymbol & NamedSymbol,
360+
resumeSym: VarSymbol,
361361
params: Ls[ParamList],
362362
body: Block,
363363
):

hkmc2/shared/src/main/scala/hkmc2/codegen/HandlerLowering.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,11 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
518518
clsSym,
519519
BlockMemberSymbol(clsSym.nme, Nil),
520520
syntax.Cls,
521-
S(PlainParamList(Param(FldFlags.empty, pcVar, N) :: Nil)),
521+
S(PlainParamList({
522+
val p = Param(FldFlags.empty.copy(value = true), pcVar, N)
523+
pcVar.decl = S(p)
524+
p
525+
} :: Nil)),
522526
Nil,
523527
S(paths.contClsPath),
524528
resumeFnDef :: Nil,
@@ -527,7 +531,12 @@ class HandlerLowering(paths: HandlerPaths)(using TL, Raise, Elaborator.State, El
527531
Assign(freshTmp(), PureCall(
528532
Value.Ref(State.builtinOpsMap("super")), // refers to runtime.FunctionContFrame which is pure
529533
Value.Lit(Tree.UnitLit(true)) :: Nil), End()),
530-
End()))
534+
AssignField(
535+
clsSym.asPath,
536+
pcVar.id,
537+
Value.Ref(pcVar),
538+
End()
539+
)(S(pcSymbol))))
531540

532541
private def genNormalBody(b: Block, clsSym: BlockMemberSymbol)(using HandlerCtx): Block =
533542
val transform = new BlockTransformerShallow(SymbolSubst()):

hkmc2/shared/src/main/scala/hkmc2/codegen/Lifter.scala

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
132132
* @param ignoredDefns The definitions which must not be lifted.
133133
* @param inScopeDefns Definitions which are in scope to another definition (excluding itself and its nested definitions).
134134
* @param modLocals A map from the modules and objects to the local to which it is instantiated after lifting.
135-
* @param localCaptureSyms The symbols in a capture corresponding to a particular local
135+
* @param localCaptureSyms The symbols in a capture corresponding to a particular local.
136+
* The `VarSymbol` is the parameter in the capture class, and the `BlockMemberSymbol` is the field in the class.
136137
* @param prevFnLocals Locals belonging to function definitions that have already been traversed
137138
* @param prevClsDefns Class definitions that have already been traversed, excluding modules
138139
* @param curModules Modules that that we are currently nested in (cleared if we are lifted out)
@@ -152,7 +153,7 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
152153
val ignoredDefns: Set[BlockMemberSymbol] = Set.empty,
153154
val inScopeDefns: Map[BlockMemberSymbol, Set[BlockMemberSymbol]] = Map.empty,
154155
val modLocals: Map[BlockMemberSymbol, Local] = Map.empty,
155-
val localCaptureSyms: Map[Local, LocalSymbol & NamedSymbol] = Map.empty,
156+
val localCaptureSyms: Map[Local, (VarSymbol, BlockMemberSymbol)] = Map.empty,
156157
val prevFnLocals: FreeVars = FreeVars.empty,
157158
val prevClsDefns: List[ClsLikeDefn] = Nil,
158159
val curModules: List[ClsLikeDefn] = Nil,
@@ -186,7 +187,7 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
186187
def withInScopes(mp: Map[BlockMemberSymbol, Set[BlockMemberSymbol]]) = copy(inScopeDefns = mp)
187188
def addFnLocals(f: FreeVars) = copy(prevFnLocals = prevFnLocals ++ f)
188189
def addClsDefn(c: ClsLikeDefn) = copy(prevClsDefns = c :: prevClsDefns)
189-
def addLocalCaptureSyms(m: Map[Local, LocalSymbol & NamedSymbol]) = copy(localCaptureSyms = localCaptureSyms ++ m)
190+
def addLocalCaptureSyms(m: Map[Local, (VarSymbol, BlockMemberSymbol)]) = copy(localCaptureSyms = localCaptureSyms ++ m)
190191
def getBmsReqdInfo(sym: BlockMemberSymbol) = bmsReqdInfo.get(sym)
191192
def replCapturePaths(paths: Map[BlockMemberSymbol, Path]) = copy(capturePaths = paths)
192193
def addCapturePath(src: BlockMemberSymbol, path: Path) = copy(capturePaths = capturePaths + (src -> path))
@@ -218,7 +219,8 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
218219
* @param f The function to create the capture class for.
219220
* @param ctx The lifter context. Determines which variables will be captured.
220221
* @return The triple (defn, varsMap, varsList), where `defn` is the capture class's definition,
221-
* `varsMap` maps the function's locals to the correpsonding `VarSymbol` in the class, and
222+
* `varsMap` maps the function's locals to the correpsonding `VarSymbol` (for the class parameters)
223+
* and `BlockLocalSymbol` (for the class fields) in the class, and
222224
* `varsList` specifies the order of these variables in the class's constructor.
223225
*/
224226
def createCaptureCls(f: FunDefn, ctx: LifterCtx) =
@@ -233,21 +235,54 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
233235

234236
val fresh = FreshInt()
235237

236-
val varsMap: Map[Local, TermSymbol] = cap.map: s =>
238+
val varsMap = cap.map: s =>
237239
val id = fresh.make
238-
s -> TermSymbol(syntax.ParamBind, S(clsSym), Tree.Ident(s.nme + id + "$"))
240+
val nme = s.nme + id + "$"
241+
val varSym = VarSymbol(Tree.Ident(nme))
242+
val fldSym = BlockMemberSymbol(nme, Nil)
243+
val fldDef = TermDefinition(
244+
S(clsSym),
245+
syntax.ImmutVal,
246+
fldSym,
247+
Nil, N, N,
248+
S(Term.Ref(s)(Tree.Ident(s.nme), 666)), // FIXME: 666 is a dummy value
249+
FlowSymbol("‹class-param-res›"),
250+
TermDefFlags.empty,
251+
Nil
252+
)
253+
fldSym.defn = S(fldDef)
254+
s -> (
255+
varSym,
256+
fldDef,
257+
)
239258
.toMap
240259

241260
val varsList = cap.toList
242261

243262
val defn = ClsLikeDefn(
244263
None, clsSym, BlockMemberSymbol(nme, Nil),
245264
syntax.Cls,
246-
S(PlainParamList(varsList.map(s => Param(FldFlags.empty, varsMap(s), None)))),
247-
Nil, None, Nil, Nil, Nil, End(), End()
265+
S(PlainParamList(varsList.map: s =>
266+
val sym = varsMap(s)._1
267+
val p = Param(FldFlags.empty.copy(value = true), sym, None)
268+
sym.decl = S(p)
269+
p
270+
)),
271+
Nil, None, Nil, Nil,
272+
varsList.map(varsMap(_)._2),
273+
varsList.map(varsMap(_)).foldLeft[Block](End()):
274+
case (acc, (varSym, fldDef)) =>
275+
AssignField(
276+
clsSym.asPath,
277+
Tree.Ident(fldDef.sym.nme),
278+
Value.Ref(varSym),
279+
acc
280+
)(S(fldDef.sym))
281+
,
282+
End()
248283
)
249284

250-
(defn, varsMap, varsList)
285+
(defn, varsMap.view.mapValues(_.mapSecond(_.sym)).toMap, varsList)
251286

252287
private val innerSymCache: MutMap[Local, Set[Local]] = MutMap.empty
253288

@@ -597,7 +632,7 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
597632
case _ => super.applyBlock(rewritten)
598633

599634
case Assign(lhs, rhs, rest) => ctx.getLocalCaptureSym(lhs) match
600-
case Some(captureSym) =>
635+
case Some((captureSym, _)) =>
601636
AssignField(ctx.getLocalClosPath(lhs).get, captureSym.id, applyResult(rhs), applyBlock(rest))(N)
602637
case None => ctx.getLocalPath(lhs) match
603638
case None => super.applyBlock(rewritten)
@@ -655,7 +690,7 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
655690
// This rewrites naked references to locals. If a function is in a capture, then we select that value
656691
// from the capture; otherwise, we see if that local is passed directly as a parameter to this defn.
657692
case Value.Ref(l) => ctx.getLocalCaptureSym(l) match
658-
case Some(captureSym) =>
693+
case Some((captureSym, _)) =>
659694
Select(ctx.getLocalClosPath(l).get, captureSym.id)(N)
660695
case None => ctx.getLocalPath(l) match
661696
case Some(value) => Value.Ref(value)
@@ -690,8 +725,13 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
690725
val fresh = FreshInt()
691726
(nme: String) =>
692727
val id = fresh.make
693-
TermSymbol(syntax.ParamBind, S(d.isym), Tree.Ident(nme + "$" + id))
694-
case _ => ((nme: String) => VarSymbol(Tree.Ident(nme)))
728+
(
729+
VarSymbol(Tree.Ident(nme + "$" + id)),
730+
TermSymbol(syntax.ParamBind, S(d.isym), Tree.Ident(nme + "$" + id))
731+
)
732+
case _ => (nme: String) =>
733+
val vsym = VarSymbol(Tree.Ident(nme))
734+
(vsym, vsym)
695735

696736
val capturesSymbols = includedCaptures.map: sym =>
697737
(sym, createSym(sym.nme + "$capture"))
@@ -706,27 +746,27 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
706746
(sym, createSym(sym.nme + "$member"))
707747

708748
val extraParamsCaptures = capturesSymbols.map: // parameter list
709-
case (d, sym) => Param(FldFlags.empty, sym, None)
749+
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
710750
val newCapturePaths = capturesSymbols.map: // mapping from sym to param symbol
711-
case (d, sym) => d -> sym.asPath
751+
case (d, (_, sym)) => d -> sym.asPath
712752
.toMap
713753

714754
val extraParamsLocals = localsSymbols.map: // parameter list
715-
case (d, sym) => Param(FldFlags.empty, sym, None)
755+
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
716756
val newLocalsPaths = localsSymbols.map: // mapping from sym to param symbol
717-
case (d, sym) => d -> sym
757+
case (d, (_, sym)) => d -> sym
718758
.toMap
719759

720760
val extraParamsIsyms = isymSymbols.map: // parameter list
721-
case (d, sym) => Param(FldFlags.empty, sym, None)
761+
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
722762
val newIsymPaths = isymSymbols.map: // mapping from sym to param symbol
723-
case (d, sym) => d -> sym
763+
case (d, (_, sym)) => d -> sym
724764
.toMap
725765

726766
val extraParamsBms = bmsSymbols.map: // parameter list
727-
case (d, sym) => Param(FldFlags.empty, sym, None)
767+
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
728768
val newBmsPaths = bmsSymbols.map: // mapping from sym to param symbol
729-
case (d, sym) => d -> sym.asPath
769+
case (d, (_, sym)) => d -> sym.asPath
730770
.toMap
731771

732772
val extraParams = extraParamsBms ++ extraParamsIsyms ++ extraParamsLocals ++ extraParamsCaptures

hkmc2/shared/src/main/scala/hkmc2/codegen/js/JSBuilder.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ class JSBuilder(using TL, State, Ctx) extends CodeBuilder:
201201
// * Note: `_pubFlds` is not used because in JS, fields are not declared
202202
val clsParams = paramsOpt.fold(Nil)(_.paramSyms)
203203
val ctorParams = clsParams.map(p => p -> scope.allocateName(p))
204+
val ctorFields = ctorParams.filter: p =>
205+
p._1.decl match
206+
case S(Param(flags = FldFlags(value = true))) => true
207+
case _ => false
204208
val ctorAuxParams = auxParams.map(ps => ps.params.map(p => p.sym -> scope.allocateName(p.sym)))
205209

206210
val isModule = kind is syntax.Mod
@@ -212,7 +216,7 @@ class JSBuilder(using TL, State, Ctx) extends CodeBuilder:
212216
val nme = scp.allocateName(fld)
213217
doc" # $mtdPrefix#$nme;"
214218
.mkDocument(doc"")
215-
val preCtorCode = (ctorParams ++ ctorAuxParams.flatMap(ps => ps)).foldLeft(body(preCtor, endSemi = true)):
219+
val preCtorCode = ctorAuxParams.flatMap(ps => ps).foldLeft(body(preCtor, endSemi = true)):
216220
case (acc, (sym, nme)) =>
217221
doc"$acc # this.${sym.name} = $nme;"
218222
val ctorCode = doc"$preCtorCode${body(ctor, endSemi = false)}"
@@ -267,9 +271,9 @@ class JSBuilder(using TL, State, Ctx) extends CodeBuilder:
267271
else doc""" # ${mtdPrefix}toString() { return "${sym.nme}${
268272
if paramsOpt.isEmpty then doc"""""""
269273
else doc"""(" + ${
270-
ctorParams.headOption.fold("\"\"")("globalThis.Predef.render(this." + _._1.name + ")")
274+
ctorFields.headOption.fold("\"\"")("globalThis.Predef.render(this." + _._1.name + ")")
271275
}${
272-
ctorParams.tailOption.fold("")(_.map(
276+
ctorFields.tailOption.fold("")(_.map(
273277
""" + ", " + globalThis.Predef.render(this.""" + _._1.name + ")").mkString)
274278
} + ")""""
275279
}; }"""

0 commit comments

Comments
 (0)