@@ -1035,19 +1035,51 @@ object desugar {
1035
1035
Bind (name, Ident (nme.WILDCARD )).withSpan(tree.span)
1036
1036
}
1037
1037
1038
- def defTree (tree : Tree )(implicit ctx : Context ): Tree = tree match {
1039
- case tree : ValDef => valDef(tree)
1040
- case tree : TypeDef =>
1041
- if (tree.isClassDef) classDef(tree)
1042
- else if (tree.mods.is(Opaque , butNot = Synthetic )) opaqueAlias(tree)
1043
- else tree
1044
- case tree : DefDef =>
1045
- if (tree.name.isConstructorName) tree // was already handled by enclosing classDef
1046
- else defDef(tree)
1047
- case tree : ModuleDef => moduleDef(tree)
1048
- case tree : PatDef => patDef(tree)
1038
+ /** The type of tests that check whether a MemberDef is OK for some flag.
1039
+ * The test succeeds if the partial function is defined and returns true.
1040
+ */
1041
+ type MemberDefTest = PartialFunction [MemberDef , Boolean ]
1042
+
1043
+ val legalOpaque : MemberDefTest = {
1044
+ case TypeDef (_, rhs) =>
1045
+ def rhsOK (tree : Tree ): Boolean = tree match {
1046
+ case _ : TypeBoundsTree | _ : Template => false
1047
+ case LambdaTypeTree (_, body) => rhsOK(body)
1048
+ case _ => true
1049
+ }
1050
+ rhsOK(rhs)
1051
+ }
1052
+
1053
+ /** Check that modifiers are legal for the definition `tree`.
1054
+ * Right now, we only check for `opaque`. TODO: Move other modifier checks here.
1055
+ */
1056
+ def checkModifiers (tree : Tree )(implicit ctx : Context ): Tree = tree match {
1057
+ case tree : MemberDef =>
1058
+ var tested : MemberDef = tree
1059
+ def fail (msg : String ) = ctx.error(msg, tree.sourcePos)
1060
+ def checkApplicable (flag : FlagSet , test : MemberDefTest ): Unit =
1061
+ if (tested.mods.is(flag) && ! (test.isDefinedAt(tree) && test(tree))) {
1062
+ fail(i " modifier ` $flag` is not allowed for this definition " )
1063
+ tested = tested.withMods(tested.mods.withoutFlags(flag))
1064
+ }
1065
+ checkApplicable(Opaque , legalOpaque)
1066
+ tested
1067
+ case _ =>
1068
+ tree
1049
1069
}
1050
1070
1071
+ def defTree (tree : Tree )(implicit ctx : Context ): Tree =
1072
+ checkModifiers(tree) match {
1073
+ case tree : ValDef => valDef(tree)
1074
+ case tree : TypeDef =>
1075
+ if (tree.isClassDef) classDef(tree) else tree
1076
+ case tree : DefDef =>
1077
+ if (tree.name.isConstructorName) tree // was already handled by enclosing classDef
1078
+ else defDef(tree)
1079
+ case tree : ModuleDef => moduleDef(tree)
1080
+ case tree : PatDef => patDef(tree)
1081
+ }
1082
+
1051
1083
/** { stats; <empty > }
1052
1084
* ==>
1053
1085
* { stats; () }
0 commit comments