-
Notifications
You must be signed in to change notification settings - Fork 337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improvement: Add separate option for decorations for evidence params #6219
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,7 @@ case class UserConfiguration( | |
showInferredType: Option[String] = None, | ||
showImplicitArguments: Boolean = false, | ||
showImplicitConversionsAndClasses: Boolean = false, | ||
showEvidenceParams: Boolean = false, | ||
enableStripMarginOnTypeFormatting: Boolean = true, | ||
enableIndentOnPaste: Boolean = false, | ||
enableSemanticHighlighting: Boolean = true, | ||
|
@@ -260,6 +261,16 @@ object UserConfiguration { | |
|shown in the hover. | ||
|""".stripMargin, | ||
), | ||
UserConfigurationOption( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could also do the same trick as with type, where we have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not really a fan of this solution in val x = List(1) match
case head :: tail => 1
case _ => 0
// with 'minimal'
val x: Int = List(1) match
case head :: tail => 1
case _ => 0
// with 'true' (currently also with minimal)
val x: Int = List(1) match
case head: Int :: tail: List[Int] => 1
case _ => 0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @jkciesluk, doing it this way makes it far more flexible. At some point we can consider better options for the user to configure those settings but that is more of a client problem. |
||
"show-evidence-params", | ||
"false", | ||
"false", | ||
"Should display context bounds evidence parameters at usage sites", | ||
"""|When this option is enabled, each place where a context bound is used has it | ||
|displayed either as additional decorations if they are supported by the editor or | ||
|shown in the hover. | ||
|""".stripMargin, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be good to include examples here and the client later |
||
), | ||
UserConfigurationOption( | ||
"enable-semantic-highlighting", | ||
"true", | ||
|
@@ -538,6 +549,8 @@ object UserConfiguration { | |
getBooleanKey("show-implicit-arguments").getOrElse(false) | ||
val showImplicitConversionsAndClasses = | ||
getBooleanKey("show-implicit-conversions-and-classes").getOrElse(false) | ||
val showEvidenceParams = | ||
getBooleanKey("show-evidence-params").getOrElse(false) | ||
val enableStripMarginOnTypeFormatting = | ||
getBooleanKey("enable-strip-margin-on-type-formatting").getOrElse(true) | ||
val enableIndentOnPaste = | ||
|
@@ -609,6 +622,7 @@ object UserConfiguration { | |
showInferredType, | ||
showImplicitArguments, | ||
showImplicitConversionsAndClasses, | ||
showEvidenceParams, | ||
enableStripMarginOnTypeFormatting, | ||
enableIndentOnPaste, | ||
enableSemanticHighlighting, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ import dotty.tools.dotc.ast.tpd | |
import dotty.tools.dotc.ast.tpd.* | ||
import dotty.tools.dotc.core.Contexts.Context | ||
import dotty.tools.dotc.core.Flags | ||
import dotty.tools.dotc.core.Names.Name | ||
import dotty.tools.dotc.core.StdNames.* | ||
import dotty.tools.dotc.core.Symbols.* | ||
import dotty.tools.dotc.core.Types.* | ||
|
@@ -73,17 +74,23 @@ class PcInlayHintsProvider( | |
LabelPart(")") :: Nil, | ||
InlayHintKind.Parameter, | ||
) | ||
case ImplicitParameters(symbols, pos, allImplicit) | ||
if params.implicitParameters() => | ||
val labelParts = symbols.map(s => List(labelPart(s, s.decodedName))) | ||
val label = | ||
if allImplicit then labelParts.separated("(using ", ", ", ")") | ||
else labelParts.separated(", ") | ||
inlayHints.add( | ||
adjustPos(pos).toLsp, | ||
label, | ||
InlayHintKind.Parameter, | ||
) | ||
case ImplicitParameters(args, pos, allImplicit) | ||
if params.implicitParameters() || params.contextBounds() => | ||
val symbols = args.collect { | ||
case Param(sym) if params.implicitParameters() => sym | ||
case ContextBound(sym) if params.contextBounds() => sym | ||
} | ||
if symbols.isEmpty then inlayHints | ||
else | ||
val labelParts = symbols.map(s => List(labelPart(s, s.decodedName))) | ||
val label = | ||
if allImplicit then labelParts.separated("(using ", ", ", ")") | ||
else labelParts.separated(", ") | ||
inlayHints.add( | ||
adjustPos(pos).toLsp, | ||
label, | ||
InlayHintKind.Parameter, | ||
) | ||
case ValueOf(label, pos) if params.implicitParameters() => | ||
inlayHints.add( | ||
adjustPos(pos).toLsp, | ||
|
@@ -210,17 +217,20 @@ object ImplicitConversion: | |
end ImplicitConversion | ||
|
||
object ImplicitParameters: | ||
def unapply(tree: Tree)(using Context) = | ||
def unapply(tree: Tree)(using Context): Option[(List[ImplicitParamSym], SourcePosition, Boolean)] = | ||
tree match | ||
jkciesluk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
case Apply(fun, args) | ||
if args.exists(isSyntheticArg) && !tree.sourcePos.span.isZeroExtent => | ||
val (implicitArgs, providedArgs) = args.partition(isSyntheticArg) | ||
val allImplicit = providedArgs.isEmpty || providedArgs.forall { | ||
case Ident(name) => name == nme.MISSING | ||
case _ => false | ||
fun.typeOpt.widen.paramNamess.headOption.map {paramNames => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a need for widening ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, without it given (using Xg): Yg with
def doY = "7"
val y = given_Yg<<(using Xg)>> // fun.typeOpt has no params, we need to widen |
||
val (implicitArgs0, providedArgs) = args.zip(paramNames).partition((arg, _) => isSyntheticArg(arg)) | ||
val firstImplicitPos = implicitArgs0.head._1.sourcePos | ||
val implicitArgs = implicitArgs0.map(ImplicitParamSym(_)) | ||
val allImplicit = providedArgs.isEmpty || providedArgs.forall { | ||
case (Ident(name), _) => name == nme.MISSING | ||
case _ => false | ||
} | ||
(implicitArgs, firstImplicitPos, allImplicit) | ||
} | ||
val pos = implicitArgs.head.sourcePos | ||
Some(implicitArgs.map(_.symbol), pos, allImplicit) | ||
case _ => None | ||
|
||
private def isSyntheticArg(tree: Tree)(using Context) = tree match | ||
|
@@ -229,6 +239,19 @@ object ImplicitParameters: | |
case _ => false | ||
end ImplicitParameters | ||
|
||
sealed trait ImplicitParamSym extends Any | ||
case class Param(sym: Symbol) extends AnyVal with ImplicitParamSym | ||
case class ContextBound(sym: Symbol) extends AnyVal with ImplicitParamSym | ||
|
||
object ImplicitParamSym: | ||
def apply(argWithName: (Tree, Name))(using Context) = | ||
val (arg, name) = argWithName | ||
if isContextBoundParam(name) then ContextBound(arg.symbol) | ||
else Param(arg.symbol) | ||
private def isContextBoundParam(name: Name) = | ||
// In 3.1.3 NameKinds.ContextBoundParamName.separator is not available | ||
name.toString.startsWith("evidence$") | ||
|
||
object ValueOf: | ||
def unapply(tree: Tree)(using Context) = | ||
tree match | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move all the settings to a single object first.