Skip to content

Commit 34a2fea

Browse files
Run java bound checks just after typer and then discard java compilation units
1 parent b9f9260 commit 34a2fea

File tree

4 files changed

+70
-66
lines changed

4 files changed

+70
-66
lines changed

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,8 @@ class Pickler extends Phase {
8787
}
8888
}
8989

90-
protected def discardBeforePickler(unit: CompilationUnit)(using Context): Boolean =
91-
unit.isJava // stop here for java files
92-
9390
override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] = {
94-
val result = super.runOn(units.filterNot(discardBeforePickler))
91+
val result = super.runOn(units)
9592
if ctx.settings.YtestPickler.value
9693
testUnpickler(
9794
using ctx.fresh

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 40 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
6868

6969
override def changesMembers: Boolean = true // the phase adds super accessors and synthetic members
7070

71-
override def run(using Context): Unit =
72-
val unit = ctx.compilationUnit
73-
if unit.isJava then
74-
AppliedTypeChecker().traverse(unit.tpdTree)
75-
else
76-
super.run
77-
7871
override def transformPhase(using Context): Phase = thisPhase.next
7972

8073
protected def newTransformer(using Context): Transformer =
@@ -92,53 +85,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
9285
// TODO fill in
9386
}
9487

95-
private def normalizeTypeArgs(tree: TypeApply)(using Context): TypeApply = tree.tpe match
96-
case pt: PolyType => // wait for more arguments coming
97-
tree
98-
case _ =>
99-
def decompose(tree: TypeApply): (Tree, List[Tree]) = tree.fun match
100-
case fun: TypeApply =>
101-
val (tycon, args) = decompose(fun)
102-
(tycon, args ++ tree.args)
103-
case _ =>
104-
(tree.fun, tree.args)
105-
end decompose
106-
def reorderArgs(pnames: List[Name], namedArgs: List[NamedArg], otherArgs: List[Tree]): List[Tree] = pnames match
107-
case pname :: pnames1 =>
108-
namedArgs.partition(_.name == pname) match
109-
case (NamedArg(_, arg) :: _, namedArgs1) =>
110-
arg :: reorderArgs(pnames1, namedArgs1, otherArgs)
111-
case _ =>
112-
val otherArg :: otherArgs1 = otherArgs
113-
otherArg :: reorderArgs(pnames1, namedArgs, otherArgs1)
114-
case nil =>
115-
assert(namedArgs.isEmpty && otherArgs.isEmpty)
116-
Nil
117-
end reorderArgs
118-
119-
val (tycon, args) = decompose(tree)
120-
tycon.tpe.widen match
121-
case tp: PolyType if args.exists(isNamedArg) =>
122-
val (namedArgs, otherArgs) = args.partition(isNamedArg)
123-
val args1 = reorderArgs(tp.paramNames, namedArgs.asInstanceOf[List[NamedArg]], otherArgs)
124-
TypeApply(tycon, args1).withSpan(tree.span).withType(tree.tpe)
125-
case _ =>
126-
tree
127-
end normalizeTypeArgs
128-
129-
private class AppliedTypeChecker extends TreeTraverser {
130-
/** Scan a tree and check all the AppliedTypeTrees in it. */
131-
def traverse(tree: Tree)(using Context): Unit = tree match
132-
case tpt: TypeTree =>
133-
Checking.checkAppliedTypesIn(tpt)
134-
case tree: AppliedTypeTree =>
135-
Checking.checkAppliedType(tree, EmptyTree)
136-
case tree: TypeApply =>
137-
traverseChildren(normalizeTypeArgs(tree))
138-
case _ =>
139-
traverseChildren(tree)
140-
}
141-
14288
class PostTyperTransformer extends Transformer {
14389

14490
private var inJavaAnnot: Boolean = false
@@ -218,21 +164,54 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
218164
=> Checking.checkAppliedTypesIn(tree)
219165
case _ =>
220166

221-
private def transformSelect(tree: Select, targs: List[Tree])(using Context): Tree = {
167+
private def transformSelect(tree: Select, targs: List[Tree])(using Context): Tree =
222168
val qual = tree.qualifier
223-
qual.symbol.moduleClass.denot match {
169+
qual.symbol.moduleClass.denot match
224170
case pkg: PackageClassDenotation =>
225171
val pobj = pkg.packageObjFor(tree.symbol)
226-
if (pobj.exists)
172+
if pobj.exists then
227173
return transformSelect(cpy.Select(tree)(qual.select(pobj).withSpan(qual.span), tree.name), targs)
228174
case _ =>
229-
}
175+
230176
val tree1 = super.transform(tree)
231-
constToLiteral(tree1) match {
177+
constToLiteral(tree1) match
232178
case _: Literal => tree1
233179
case _ => superAcc.transformSelect(tree1, targs)
234-
}
235-
}
180+
181+
private def normalizeTypeArgs(tree: TypeApply)(using Context): TypeApply = tree.tpe match
182+
case pt: PolyType => // wait for more arguments coming
183+
tree
184+
case _ =>
185+
def decompose(tree: TypeApply): (Tree, List[Tree]) = tree.fun match
186+
case fun: TypeApply =>
187+
val (tycon, args) = decompose(fun)
188+
(tycon, args ++ tree.args)
189+
case _ =>
190+
(tree.fun, tree.args)
191+
end decompose
192+
193+
def reorderArgs(pnames: List[Name], namedArgs: List[NamedArg], otherArgs: List[Tree]): List[Tree] = pnames match
194+
case pname :: pnames1 =>
195+
namedArgs.partition(_.name == pname) match
196+
case (NamedArg(_, arg) :: _, namedArgs1) =>
197+
arg :: reorderArgs(pnames1, namedArgs1, otherArgs)
198+
case _ =>
199+
val otherArg :: otherArgs1 = otherArgs
200+
otherArg :: reorderArgs(pnames1, namedArgs, otherArgs1)
201+
case nil =>
202+
assert(namedArgs.isEmpty && otherArgs.isEmpty)
203+
Nil
204+
end reorderArgs
205+
206+
val (tycon, args) = decompose(tree)
207+
tycon.tpe.widen match
208+
case tp: PolyType if args.exists(isNamedArg) =>
209+
val (namedArgs, otherArgs) = args.partition(isNamedArg)
210+
val args1 = reorderArgs(tp.paramNames, namedArgs.asInstanceOf[List[NamedArg]], otherArgs)
211+
TypeApply(tycon, args1).withSpan(tree.span).withType(tree.tpe)
212+
case _ =>
213+
tree
214+
end normalizeTypeArgs
236215

237216
private object dropInlines extends TreeMap {
238217
override def transform(tree: Tree)(using Context): Tree = tree match {

compiler/src/dotty/tools/dotc/typer/FrontEnd.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class FrontEnd extends Phase {
8080
typr.println("typed: " + unit.source)
8181
record("retained untyped trees", unit.untpdTree.treeSize)
8282
record("retained typed trees after typer", unit.tpdTree.treeSize)
83+
if unit.isJava then
84+
JavaChecks.check(unit.tpdTree)
8385
catch
8486
case ex: CompilationUnit.SuspendException =>
8587
}
@@ -92,7 +94,7 @@ class FrontEnd extends Phase {
9294
}
9395

9496
protected def discardAfterTyper(unit: CompilationUnit)(using Context): Boolean =
95-
unit.suspended
97+
unit.isJava || unit.suspended
9698

9799
override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] =
98100
val unitContexts =
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dotty.tools.dotc
2+
package typer
3+
4+
import core.Contexts._
5+
import ast.tpd._
6+
7+
/** PostTyper doesn't run on java sources,
8+
* but some checks still need to be applied.
9+
*/
10+
object JavaChecks {
11+
/** Check the bounds of AppliedTypeTrees. */
12+
private object AppliedTypeChecker extends TreeTraverser {
13+
def traverse(tree: Tree)(using Context): Unit = tree match
14+
case tpt: TypeTree =>
15+
Checking.checkAppliedTypesIn(tpt)
16+
case tree: AppliedTypeTree =>
17+
Checking.checkAppliedType(tree)
18+
case _ =>
19+
traverseChildren(tree)
20+
}
21+
22+
/** Scan a tree and check it. */
23+
def check(tree: Tree)(using Context): Unit =
24+
ctx.debuglog("checking type bounds in " + ctx.compilationUnit.source.name)
25+
AppliedTypeChecker.traverse(tree)
26+
}

0 commit comments

Comments
 (0)