Uh oh!
There was an error while loading. Please reload this page.
Correctly colorize parameterized CE builders - #16052
Conversation
* This change enables correct colorization of custom computation expression builders with generic type parameters, e.g., `builder<…>`.
psfinaki
commented
Sep 27, 2023
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
psfinaki
commented
Sep 27, 2023
Ohh thanks - that looks useful! As for testing - I haven't done much in the colorization space but to me |
auduchinok
commented
Sep 27, 2023
Hm, this doesn't sound right to me. We only colorize the builder values as keywords when they are used in an actual sequence expression application. In some of the tools this is done via checking |
vzarytovskii
commented
Sep 27, 2023
Tbh, I'm not horribly against it, however this should be done in tooling instead (in semantic highlighting, I presume). |
auduchinok
commented
Sep 27, 2023
Yes, and we should have tests that show that |
This change gives such functions keyword coloring (and ![]() However, if we still think keyword colorization shouldn't apply in such cases, I can make this change: - | Expr.App (funcExpr = Expr.Val (vref, _, m))+ | Expr.App (funcExpr = Expr.Val (vref, _, m); args = [])
|
auduchinok
commented
Sep 27, 2023
This looks nice! Would be good to have the tests anyway 🙂 |
If I add a test like this: [<Theory>][<InlineData("builder")>][<InlineData("builder<int>")>][<InlineData("builder<_>")>]memberthis.CustomBuilder_GenericTypeParameters builder =
this.VerifyColorizerAtEndOfMarker(
fileContents = $"type Builder<'T> () = member _.Return x = x member _.Run x = xlet builder<'T> = Builder<'T> ()let x = (*marker*)%s{builder} {{ return 3 }}",
marker ="(*marker*)b",
defines =[],
classificationType = ClassificationTypeNames.Keyword)…it fails because |
* Test that FSharpSymbolUse.IsFromComputationExpression only returns
true in `builder { … }`, `builder () { … }`, `builder<…> { … }`.brianrourkeboll
commented
Sep 27, 2023
Are these similar to what you were thinking? 9b7579e |
* For the double symbol uses for the builders, see: https://github.com/dotnet/fsharp/blob/fb39b9440dd27f5ed093e0617cdce49d9dbffa3c/src/Compiler/Service/SemanticClassification.fs#L179-L192
* For a computation expression builder type `Builder`, we don't expect
keyword highlighting (or `FSharpSymbolUse.IsFromComputationExpression`
to return true) in `type Builder () = …` or `Builder () { … }`.
Change
builder<…> { … }(type application).builder () { … }(function application).1Edit: It turns out that there was a very old issue for this, which might as well be linked: #110.
Example
In the following example,
builderis now correctly colorized as a keyword (likeasyncand any other custom builder that doesn't have generic type parameters).Before
After
Tests
SyntacticClassificationServiceTestsseems to be too low-level to catch this change. I have added tests forFSharpSymbolUse.IsFromComputationExpressionunderTests.Service.Symbols.ComputationExpressions.Footnotes
This does not apply to direct invocations of constructors, e.g.,
Builder () { … }. I think this behavior makes sense, since a Pascal-case constructor doesn't "feel" like it should get keyword coloring, even in this context.I can think of even funkier valid cases where keyword coloring still does not apply and almost certainly (?) shouldn't…
↩