Skip to content

Conversation

@kerams
Copy link
Contributor

@kerams kerams commented Dec 17, 2022

Implements fsharp/fslang-suggestions#155.

LGSIrSyGe6

@baronfel raised this question:

Can the TPs define their own warning codes instead of piggybacking on the FS ones? And/or provide URLs as well. This is all allowed in existing MSBuild diagnostics and can help out users to find detailed docs

Currently all diagnostics are implicitly FS-prefixed. Maybe we could allow TPs to send custom codes and URLs to the compiler, which would just ignore those and use FS3033 and FS3088 until custom codes are supported? Just so that the TP interface won't have to keep changing.

Analysis of issues and open questions, XML docs (once the API is ironed out), tests incoming.

@kerams kerams requested a review from a team as a code owner December 17, 2022 12:52
Comment on lines +4766 to +4769
match kind with
| SynStringKind.Regular -> 1, 1
| SynStringKind.Verbatim -> 2, 1
| SynStringKind.TripleQuote -> 3, 3
Copy link
Contributor Author

@kerams kerams Dec 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Triple quoted verbatim strings do not have their own kind, so the diagnostic range becomes off by one. Not sure it's worth adding, they are fairly rare.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abonie : I assume you plan to touch the parsing and tree representation of string kinds anyway, could you account for this as well please?
i.e. the ability to cover the range(s) involved precisely, and perharps even Trivia(s) to give ranges per line in case of multiline strings.

Comment on lines +597 to +602

type ITypeProvider3 =
abstract ApplyStaticArguments : context:ITypeProviderDiagnosticsContext * typeWithoutArguments:Type * typePathWithArguments:string[] * staticArguments:obj[] -> Type

abstract ApplyStaticArgumentsForMethod:
context: ITypeProviderDiagnosticsContext * methodWithoutArguments: MethodBase * methodNameWithArguments: string * staticArguments: obj[] -> MethodBase
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsyme, I couldn't extend ITypeProvider as you had suggested, because TPs that rely on the old version of the interface in their ProvidedTypes.fs would fail to load. There's ITypeProvider2 that allows to tack on additional functionality, so I opted for the same approach.

Copy link
Contributor Author

@kerams kerams Dec 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I test backwards compatibility with VS which includes FSharp.Core 7.0 without these additions, ITypeProvider3 can't be loaded and the TP doesn't work. Even if I ditch the interface and use reflection to access the methods, there are 2 new types we now depend on. I'm at a loss here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can ITypeProvider3 extend ITypeProvider2 ?

Copy link
Contributor Author

@kerams kerams Dec 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I don't see how that would solve the problem (i.e. the interface missing in FSharp.Core that an older compiler will use, causing a type load exception).

Comment on lines 120 to 127
member DefineStaticParameters: parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedMethod) -> unit

member DefineStaticParameters: parameters: ProvidedStaticParameter list * instantiationFunction: (ProvidedMethod -> string -> obj[] -> ProvidedMethod) -> unit

member ReportWarning: staticParameterName: string * rangeInParameterIfString: (int * int) option * message: string * throwIfNotSupported: bool -> unit

member ReportError: staticParameterName: string * rangeInParameterIfString: (int * int) option * message: string -> unit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really not happy with adding these 3 methods (and with the reference to self in instantiationFunction in particular), but I could not think of a way to report diagnostics for static method arguments by calling ReportWarning/Error through the provider type itself, as is the case when applying type-level static arguments.

| TypeProviderDiagnosticSeverity.Warning ->
Error (FSComp.SR.etProviderWarning (tpDesignation, message), m) |> warning
| TypeProviderDiagnosticSeverity.Error ->
stopProcessingRecovery (Error (FSComp.SR.etProviderError (tpDesignation, message), m)) m
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stopProcessingRecovery allows the TP to continue, but when I tried to use Error, which does take the control away, the diagnostic gets wrapped in additional exception, and the entire TP range gets a squiggly line, hiding what was meant to be highlighted. Not sure how to avoid that.


[<AllowNullLiteral>]
type ITypeProviderDiagnosticsContext =
abstract ReportDiagnostic: staticParameterName: string * rangeInParameterIfString: (int * int) option * message: string * severity: TypeProviderDiagnosticSeverity -> unit
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be a good idea to have ReportDiagnostics, allowing the TP to report multiple errors at once before the control is taken away. For example, multiple problems in a query string could be highlighted at the same time, not one by one as they are fixed.

@T-Gro
Copy link
Member

T-Gro commented Dec 19, 2022

Could the built-in message template also include the static parameter name?
The more info we can put (as placeholders) into the template, the more unified the experience will be.

Also, the template itself will get localized, whereas the content provided by the TP will not - that is why I would staticParameterName into a sentence in the localized template already.

@kerams
Copy link
Contributor Author

kerams commented Dec 19, 2022

Sure it could, though I'm not sure how useful it would be.

The type provider '{0}' reported a warning: {1}</target>
vs
The type provider '{0}' reported a warning for static parameter '{2}': {1}</target>

The static parameter will already be underlined, so this does not add any new information (outside of an IDE perhaps it does, but it's still of no help without the message from the TP).

@dsyme
Copy link
Contributor

dsyme commented Jan 10, 2023

@kerams Do you know what's causing the current build failures?

 Check Diagnostics (TestProject): [|D:\a\_work\1\s\tests\service/data/TestProject/TestProject.fs (48,11)-(48,66) typecheck error The static parameter 'Query' of the provided type or method 'GenerativeProvider' requires a value. Static parameters to type providers may be optionally specified using named arguments, e.g. 'GenerativeProvider<Query=...>'.;
   D:\a\_work\1\s\tests\service/data/TestProject/TestProject.fs (48,11)-(48,66) typecheck error The static parameter 'Query' of the provided type or method 'GenerativeProvider' requires a value. Static parameters to type providers may be optionally specified using named arguments, e.g. 'GenerativeProvider<Query=...>'.;
   D:\a\_work\1\s\tests\service/data/TestProject/TestProject.fs (51,22)-(51,24) typecheck error The value or constructor 'T2' is not defined.|]

@kerams
Copy link
Contributor Author

kerams commented Jan 10, 2023

@dsyme, yeah, I've made changes to tests/service/data/TestTP/ProvidedTypes.fs (which should go into the TPSDK instead) and the test TP just so that I could try it out in a different solution (that's where the screenshot is from). TestProject.fs, which uses the test TP, remains unchanged, hence the failures caused by missing parameters.

I didn't know how you'd want to test all this (especially the compatibility of FSC vis-a-vis ProvidedTypes.fs versions) and whether the changes to tests/service/data/TestTP/ProvidedTypes.fs would get reverted later on.

@dsyme
Copy link
Contributor

dsyme commented Jan 10, 2023

I didn't know how you'd want to test all this and whether the changes to tests/service/data/TestTP/ProvidedTypes.fs would get reverted later on.

There are tests for type providers under tests/fsharp/typeProviders, it might be possible to add a simple test there.

It's also good you have prototyped additions to the TPSDK.

@kerams
Copy link
Contributor Author

kerams commented Jan 10, 2023

Will do. It would be great if you could help me sort out the open conversations above in the meantime. Also, as you've mentioned elsewhere, there are several copies of ProvidedTypes lying around the compiler. Should I add the diagnostics support to all of them?

@kerams kerams closed this Jul 20, 2023
@kerams kerams deleted the tp branch July 20, 2023 13:34
@kerams kerams mentioned this pull request May 14, 2025
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants