From 8bebd63ca31e1799a75aa5947b2df028f813456d Mon Sep 17 00:00:00 2001 From: Katarzyna Marek Date: Thu, 27 Jun 2024 10:23:54 +0200 Subject: [PATCH] fix: cover additional cases for singleton types (#6541) * fix: cover additional cases for singleton types * deprecate Scala "3.1.3" --- .../meta/internal/metals/MtagsResolver.scala | 1 + .../scala/meta/internal/pc/Compat.scala | 4 -- .../meta/internal/pc/MetalsNavigateAST.scala | 11 ------ .../meta/internal/pc/MetalsSealedDesc.scala | 8 ---- .../meta/internal/pc/MetalsSignatures.scala | 35 ----------------- .../pc/printer/RefinedDotcPrinter.scala | 16 -------- .../scala/meta/internal/pc/Compat.scala | 4 -- .../meta/internal/pc/MetalsNavigateAST.scala | 20 ---------- .../meta/internal/pc/MetalsSealedDesc.scala | 15 ------- .../meta/internal/pc/MetalsSignatures.scala | 36 ----------------- .../pc/printer/RefinedDotcPrinter.scala | 16 -------- .../scala/meta/internal/pc/Compat.scala | 4 -- .../pc/printer/RefinedDotcPrinter.scala | 6 --- .../pc/completions/SingletonCompletions.scala | 25 ++++++++++-- project/V.scala | 2 +- .../tests/pc/SingletonCompletionsSuite.scala | 39 ++++++++++++++++++- 16 files changed, 61 insertions(+), 181 deletions(-) delete mode 100644 mtags/src/main/scala-3.0/scala/meta/internal/pc/Compat.scala delete mode 100644 mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsNavigateAST.scala delete mode 100644 mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSealedDesc.scala delete mode 100644 mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSignatures.scala delete mode 100644 mtags/src/main/scala-3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala delete mode 100644 mtags/src/main/scala-3.1/scala/meta/internal/pc/Compat.scala delete mode 100644 mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsNavigateAST.scala delete mode 100644 mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSealedDesc.scala delete mode 100644 mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSignatures.scala delete mode 100644 mtags/src/main/scala-3.1/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala delete mode 100644 mtags/src/main/scala-3.3.0/scala/meta/internal/pc/Compat.scala delete mode 100644 mtags/src/main/scala-3.3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala diff --git a/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala b/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala index 0f9ce9de61c..81097835d76 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/MtagsResolver.scala @@ -76,6 +76,7 @@ object MtagsResolver { "3.3.2-RC1" -> "1.2.2", "3.3.2-RC2" -> "1.2.2", "3.3.2-RC3" -> "1.2.2", + "3.1.3" -> "1.3.2", ) class Default extends MtagsResolver { diff --git a/mtags/src/main/scala-3.0/scala/meta/internal/pc/Compat.scala b/mtags/src/main/scala-3.0/scala/meta/internal/pc/Compat.scala deleted file mode 100644 index b6a4d617c5f..00000000000 --- a/mtags/src/main/scala-3.0/scala/meta/internal/pc/Compat.scala +++ /dev/null @@ -1,4 +0,0 @@ -package scala.meta.internal.pc - -object Compat: - val EvidenceParamName = dotty.tools.dotc.core.NameKinds.EvidenceParamName diff --git a/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsNavigateAST.scala b/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsNavigateAST.scala deleted file mode 100644 index 6462a6fb272..00000000000 --- a/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsNavigateAST.scala +++ /dev/null @@ -1,11 +0,0 @@ -package scala.meta.internal.pc - -import dotty.tools.dotc.ast.NavigateAST -import dotty.tools.dotc.ast.Positioned -import dotty.tools.dotc.ast.untpd.ExtMethods -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.util.Spans.Span - -object MetalsNavigateAST: - def pathToExtensionParam(span: Span, methods: ExtMethods)(using Context) = - methods.paramss.flatten.flatMap(NavigateAST.pathTo(span, _)) diff --git a/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSealedDesc.scala b/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSealedDesc.scala deleted file mode 100644 index 02c406cac98..00000000000 --- a/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSealedDesc.scala +++ /dev/null @@ -1,8 +0,0 @@ -package scala.meta.internal.pc - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.Symbol - -object MetalsSealedDesc: - // For scala 3.0.0 and 3.0.1 method `sealedDescendants` is not available - def sealedDescendants(sym: Symbol)(using Context): List[Symbol] = sym diff --git a/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSignatures.scala b/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSignatures.scala deleted file mode 100644 index b953152db47..00000000000 --- a/mtags/src/main/scala-3.0/scala/meta/internal/pc/MetalsSignatures.scala +++ /dev/null @@ -1,35 +0,0 @@ -package scala.meta.internal.pc - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.util.SourcePosition -import dotty.tools.dotc.core.Contexts.* -import dotty.tools.dotc.util.Signatures -import dotty.tools.dotc.util.Signatures.Signature -import scala.meta.internal.mtags.MtagsEnrichments.* -import scala.meta.pc.SymbolSearch -import dotty.tools.dotc.core.Flags -import dotty.tools.dotc.core.Denotations.* - -object MetalsSignatures: - - def signatures( - path: List[tpd.Tree], - pos: SourcePosition, - )(using Context): (Int, Int, List[(Signature, Denotation)]) = - val (paramN, callableN, alternatives) = - Signatures.callInfo(path, pos.span) - val infos = alternatives.flatMap { denot => - val updatedDenot = - path.headOption - .map { t => - val pre = t.qual - denot.asSeenFrom(pre.tpe.widenTermRefExpr) - } - .getOrElse(denot) - Signatures.toSignature(updatedDenot).map { - (_, updatedDenot) - } - } - (paramN, callableN, infos) - end signatures -end MetalsSignatures diff --git a/mtags/src/main/scala-3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala b/mtags/src/main/scala-3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala deleted file mode 100644 index ce554a7d4f3..00000000000 --- a/mtags/src/main/scala-3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala +++ /dev/null @@ -1,16 +0,0 @@ -package scala.meta.internal.pc.printer - -import dotty.tools.dotc.printing.RefinedPrinter -import dotty.tools.dotc.core.Types.* -import dotty.tools.dotc.core.Contexts.Context - -abstract class RefinedDotcPrinter(_ctx: Context) extends RefinedPrinter(_ctx): - - override protected def toTextRefinement(rt: RefinedType) = - val keyword = rt.refinedInfo match - case _: ExprType | _: MethodOrPoly => "def " - case _: TypeBounds => "type " - case _: TypeProxy => "val " - case _ => "" - (keyword ~ refinementNameString(rt) ~ toTextRHS(rt.refinedInfo)).close -end RefinedDotcPrinter diff --git a/mtags/src/main/scala-3.1/scala/meta/internal/pc/Compat.scala b/mtags/src/main/scala-3.1/scala/meta/internal/pc/Compat.scala deleted file mode 100644 index b6a4d617c5f..00000000000 --- a/mtags/src/main/scala-3.1/scala/meta/internal/pc/Compat.scala +++ /dev/null @@ -1,4 +0,0 @@ -package scala.meta.internal.pc - -object Compat: - val EvidenceParamName = dotty.tools.dotc.core.NameKinds.EvidenceParamName diff --git a/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsNavigateAST.scala b/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsNavigateAST.scala deleted file mode 100644 index 7c54eb0a0b9..00000000000 --- a/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsNavigateAST.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scala.meta.internal.pc - -import dotty.tools.dotc.ast.NavigateAST -import dotty.tools.dotc.ast.Positioned -import dotty.tools.dotc.ast.untpd.ExtMethods -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.util.Spans.Span - -object MetalsNavigateAST: - // normally we use NavigateAST.pathTo, but its signature changes between 3.1.2 and 3.1.3 - def pathToExtensionParam(span: Span, methods: ExtMethods)(using Context) = - val untypedPath = NavigateAST.untypedPath(span) - val cropped = untypedPath.takeWhile { - case ExtMethods(paramss, _) - if paramss.flatten.exists(_.span.contains(span)) => - false - case _ => true - } - if cropped.length == untypedPath.length then List.empty - else cropped diff --git a/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSealedDesc.scala b/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSealedDesc.scala deleted file mode 100644 index d416e0e859d..00000000000 --- a/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSealedDesc.scala +++ /dev/null @@ -1,15 +0,0 @@ -package scala.meta.internal.pc - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Flags.* -import dotty.tools.dotc.core.StdNames.* -import dotty.tools.dotc.core.Symbols.Symbol - -object MetalsSealedDesc: - def sealedDescendants(sym: Symbol)(using Context): List[Symbol] = - sym.sealedDescendants.filter(child => - !(child.is(Sealed) && (child.is(Abstract) || child.is(Trait))) - && child.maybeOwner.exists - && (child.isPublic || child.isAccessibleFrom(sym.info)) - && child.name != tpnme.LOCAL_CHILD - ) diff --git a/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSignatures.scala b/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSignatures.scala deleted file mode 100644 index ba214430f10..00000000000 --- a/mtags/src/main/scala-3.1/scala/meta/internal/pc/MetalsSignatures.scala +++ /dev/null @@ -1,36 +0,0 @@ -package scala.meta.internal.pc - -import scala.meta.internal.mtags.MtagsEnrichments.* -import scala.meta.pc.SymbolSearch - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.* -import dotty.tools.dotc.core.Denotations.* -import dotty.tools.dotc.core.Flags -import dotty.tools.dotc.util.Signatures -import dotty.tools.dotc.util.Signatures.Signature -import dotty.tools.dotc.util.SourcePosition - -object MetalsSignatures: - - def signatures( - path: List[tpd.Tree], - pos: SourcePosition, - )(using Context): (Int, Int, List[(Signature, Denotation)]) = - val (paramN, callableN, alternatives) = - Signatures.callInfo(path, pos.span) - val infos = alternatives.flatMap { denot => - val updatedDenot = - path.headOption - .map { t => - val pre = t.qual - denot.asSeenFrom(pre.tpe.widenTermRefExpr) - } - .getOrElse(denot) - Signatures.toSignature(updatedDenot).map { - (_, updatedDenot) - } - } - (paramN, callableN, infos) - end signatures -end MetalsSignatures diff --git a/mtags/src/main/scala-3.1/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala b/mtags/src/main/scala-3.1/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala deleted file mode 100644 index f07fb7f439f..00000000000 --- a/mtags/src/main/scala-3.1/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala +++ /dev/null @@ -1,16 +0,0 @@ -package scala.meta.internal.pc.printer - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types.* -import dotty.tools.dotc.printing.RefinedPrinter - -abstract class RefinedDotcPrinter(_ctx: Context) extends RefinedPrinter(_ctx): - - override protected def toTextRefinement(rt: RefinedType) = - val keyword = rt.refinedInfo match - case _: ExprType | _: MethodOrPoly => "def " - case _: TypeBounds => "type " - case _: TypeProxy => "val " - case _ => "" - (keyword ~ refinementNameString(rt) ~ toTextRHS(rt.refinedInfo)).close -end RefinedDotcPrinter diff --git a/mtags/src/main/scala-3.3.0/scala/meta/internal/pc/Compat.scala b/mtags/src/main/scala-3.3.0/scala/meta/internal/pc/Compat.scala deleted file mode 100644 index b6a4d617c5f..00000000000 --- a/mtags/src/main/scala-3.3.0/scala/meta/internal/pc/Compat.scala +++ /dev/null @@ -1,4 +0,0 @@ -package scala.meta.internal.pc - -object Compat: - val EvidenceParamName = dotty.tools.dotc.core.NameKinds.EvidenceParamName diff --git a/mtags/src/main/scala-3.3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala b/mtags/src/main/scala-3.3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala deleted file mode 100644 index 21b5271f330..00000000000 --- a/mtags/src/main/scala-3.3.0/scala/meta/internal/pc/printer/RefinedDotcPrinter.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scala.meta.internal.pc.printer - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.printing.RefinedPrinter - -abstract class RefinedDotcPrinter(_ctx: Context) extends RefinedPrinter(_ctx) diff --git a/mtags/src/main/scala-3/scala/meta/internal/pc/completions/SingletonCompletions.scala b/mtags/src/main/scala-3/scala/meta/internal/pc/completions/SingletonCompletions.scala index f7796fb1977..1fc66764952 100644 --- a/mtags/src/main/scala-3/scala/meta/internal/pc/completions/SingletonCompletions.scala +++ b/mtags/src/main/scala-3/scala/meta/internal/pc/completions/SingletonCompletions.scala @@ -10,10 +10,12 @@ import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.StdNames +import dotty.tools.dotc.core.Symbols import dotty.tools.dotc.core.Types.AndType import dotty.tools.dotc.core.Types.AppliedType import dotty.tools.dotc.core.Types.ConstantType import dotty.tools.dotc.core.Types.OrType +import dotty.tools.dotc.core.Types.TermRef import dotty.tools.dotc.core.Types.Type import dotty.tools.dotc.core.Types.TypeRef import dotty.tools.dotc.util.Spans.Span @@ -21,7 +23,7 @@ import dotty.tools.dotc.util.Spans.Span object SingletonCompletions: def contribute( path: List[Tree], - tpe: Type, + tpe0: Type, completionPos: CompletionPos )(using ctx: Context): List[CompletionValue] = for { @@ -31,6 +33,11 @@ object SingletonCompletions: case (l @ Literal(const)) :: _ => List(const.show -> l.span) case _ => Nil query = name.replace(Cursor.value, "") + tpe = tpe0 match + // for Tuple 2 we want to suggest first arg completion + case AppliedType(t: TypeRef, args) if t.classSymbol == Symbols.defn.Tuple2 && args.nonEmpty => + args.head + case t => t singletonValues = collectSingletons(tpe).map(_.show) range = completionPos.cursorPos.withStart(span.start).withEnd(span.start + query.length).toLsp value <- singletonValues.collect { @@ -57,15 +64,25 @@ object InterCompletionType: def inferType(path: List[Tree], span: Span)(using Context): Option[Type] = path match - // List(@@) - case SeqLiteral(_, tpe) :: _ if !tpe.tpe.isErroneous => Some(tpe.tpe) case Block(_, expr) :: rest if expr.span.contains(span) => inferType(rest, span) case If(cond, _, _) :: rest if !cond.span.contains(span) => inferType(rest, span) - case (defn: ValOrDefDef) :: rest if !defn.tpt.tpe.isErroneous => Some(defn.tpt.tpe) case CaseDef(_, _, body) :: Match(_, cases) :: rest if body.span.contains(span) && cases.exists(_.span.contains(span)) => inferType(rest, span) + case NamedArg(_, arg) :: rest if arg.span.contains(span) => inferType(rest, span) + // x match + // case @@ + case CaseDef(pat, _, _) :: Match(sel, cases) :: rest if pat.span.contains(span) && cases.exists(_.span.contains(span)) && !sel.tpe.isErroneous => + sel.tpe match + case tpe: TermRef => Some(tpe.symbol.info).filterNot(_.isErroneous) + case tpe => Some(tpe) + // List(@@) + case SeqLiteral(_, tpe) :: _ if !tpe.tpe.isErroneous => + Some(tpe.tpe) + // val _: T = @@ + // def _: T = @@ + case (defn: ValOrDefDef) :: rest if !defn.tpt.tpe.isErroneous => Some(defn.tpt.tpe) // f(@@) case (app: Apply) :: rest => val param = diff --git a/project/V.scala b/project/V.scala index 47ce025b647..2fcf66df92e 100644 --- a/project/V.scala +++ b/project/V.scala @@ -113,7 +113,7 @@ object V { // whenever version is removed please add it to MtagsResolver under last supported Metals version def deprecatedScala3Versions = - Seq("3.3.2", "3.2.2", "3.1.3") + Seq("3.3.2", "3.2.2") // NOTE if you had a new Scala Version make sure it's contained in quickPublishScalaVersions def scala3Versions = nonDeprecatedScala3Versions ++ deprecatedScala3Versions diff --git a/tests/cross/src/test/scala/tests/pc/SingletonCompletionsSuite.scala b/tests/cross/src/test/scala/tests/pc/SingletonCompletionsSuite.scala index 09c75f8e026..8a93275efef 100644 --- a/tests/cross/src/test/scala/tests/pc/SingletonCompletionsSuite.scala +++ b/tests/cross/src/test/scala/tests/pc/SingletonCompletionsSuite.scala @@ -245,7 +245,7 @@ class SingletonCompletionsSuite extends BaseCompletionSuite { ) check( - "match-case", + "match-case-result", """|val h: "foo" = | 1 match | case _ => "@@" @@ -254,6 +254,43 @@ class SingletonCompletionsSuite extends BaseCompletionSuite { |""".stripMargin ) + check( + "match-case", + """|def h(foo: "foo") = + | foo match + | case "@@" => + |""".stripMargin, + """|"foo": "foo" + |""".stripMargin + ) + + check( + "match-case2", + """|def h = + | ("foo" : "foo") match + | case "@@" => + |""".stripMargin, + """|"foo": "foo" + |""".stripMargin + ) + + check( + "named-args", + """|def h(foo: "foo") = ??? + |def k = h(foo = "@@") + |""".stripMargin, + """|"foo": "foo" + |""".stripMargin + ) + + check( + "map-type", + """|def m = Map["foo", Int]("@@") + |""".stripMargin, + """|"foo": "foo" + |""".stripMargin + ) + check( "dont-show-on-select", """|val f: "foo" = List(1,2,3).@@