@@ -8,7 +8,7 @@ import Symbols.*, StdNames.*, Trees.*, ContextOps.*
88import Decorators .*
99import Annotations .Annotation
1010import NameKinds .{UniqueName , ContextBoundParamName , ContextFunctionParamName , DefaultGetterName , WildcardParamName }
11- import typer .{Namer , Checking }
11+ import typer .{Namer , Checking , ErrorReporting }
1212import util .{Property , SourceFile , SourcePosition , SrcPos , Chars }
1313import config .{Feature , Config }
1414import config .Feature .{sourceVersion , migrateTo3 , enabled , betterForsEnabled }
@@ -199,9 +199,10 @@ object desugar {
199199 def valDef (vdef0 : ValDef )(using Context ): Tree =
200200 val vdef @ ValDef (_, tpt, rhs) = vdef0
201201 val valName = normalizeName(vdef, tpt).asTermName
202+ val tpt1 = qualifiedType(tpt, valName)
202203 var mods1 = vdef.mods
203204
204- val vdef1 = cpy.ValDef (vdef)(name = valName).withMods(mods1)
205+ val vdef1 = cpy.ValDef (vdef)(name = valName, tpt = tpt1 ).withMods(mods1)
205206
206207 if isSetterNeeded(vdef) then
207208 val setterParam = makeSyntheticParameter(tpt = SetterParamTree ().watching(vdef))
@@ -2145,6 +2146,10 @@ object desugar {
21452146 case PatDef (mods, pats, tpt, rhs) =>
21462147 val pats1 = if (tpt.isEmpty) pats else pats map (Typed (_, tpt))
21472148 flatTree(pats1 map (makePatDef(tree, mods, _, rhs)))
2149+ case QualifiedTypeTree (parent, None , qualifier) =>
2150+ ErrorReporting .errorTree(parent, em " missing parameter name in qualified type " , tree.srcPos)
2151+ case QualifiedTypeTree (parent, Some (paramName), qualifier) =>
2152+ qualifiedType(parent, paramName, qualifier, tree.span)
21482153 case ext : ExtMethods =>
21492154 Block (List (ext), syntheticUnitLiteral.withSpan(ext.span))
21502155 case f : FunctionWithMods if f.hasErasedParams => makeFunctionWithValDefs(f, pt)
@@ -2323,4 +2328,23 @@ object desugar {
23232328 collect(tree)
23242329 buf.toList
23252330 }
2331+
2332+ /** If `tree` is a `QualifiedTypeTree`, then desugars it using `paramName` as
2333+ * the qualified paramater name. Otherwise, returns `tree` unchanged.
2334+ */
2335+ def qualifiedType (tree : Tree , paramName : TermName )(using Context ): Tree = tree match
2336+ case QualifiedTypeTree (parent, None , qualifier) => qualifiedType(parent, paramName, qualifier, tree.span)
2337+ case _ => tree
2338+
2339+ /** Returns the annotated type used to represent the qualified type with the
2340+ * given components:
2341+ * `parent @qualified[parent]((paramName: parent) => qualifier)`.
2342+ */
2343+ def qualifiedType (parent : Tree , paramName : TermName , qualifier : Tree , span : Span )(using Context ): Tree =
2344+ val param = makeParameter(paramName, parent, EmptyModifiers ) // paramName: parent
2345+ val predicate = WildcardFunction (List (param), qualifier) // (paramName: parent) => qualifier
2346+ val qualifiedAnnot = scalaAnnotationDot(nme.qualified)
2347+ val annot = Apply (TypeApply (qualifiedAnnot, List (parent)), predicate).withSpan(span) // @qualified[parent](predicate)
2348+ Annotated (parent, annot).withSpan(span) // parent @qualified[parent](predicate)
2349+
23262350}
0 commit comments