Skip to content
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

All inherited interface members should be implemented on an interface marked with DynamicInterfaceCastableImplementationAttribute #41529

Closed
jkoritzinsky opened this issue Aug 28, 2020 · 12 comments
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.InteropServices code-analyzer Marks an issue that suggests a Roslyn analyzer code-fixer Marks an issue that suggests a Roslyn code fixer
Milestone

Comments

@jkoritzinsky
Copy link
Member

jkoritzinsky commented Aug 28, 2020

An interface marked with a System.Runtime.InteropServices.DynamicInterfaceCastableImplementationAttribute attribute should provide a default interface implementation of all inherited interface methods and should not provide any new non-private interface methods without a default implementation.

interface Foo
{
      void Frob();
}

[DynamicInterfaceCastableImplementation]
interface Bar : Foo
{
	void Baz();
}

Category: Usage
Default: Enabled
Severity: Warning

When a method is not implemented, a warning will be emitted on the attributed interface name. A code fix will be offered to implement the method with a default implementation that throws a NotImplementedException.

When a method is defined on the implementation interface, a warning will be emitted on the method name. If the method has a body, a code fix will be offered to make the method public sealed. Otherwise, a code fix will be offered to make the method sealed and add a body that throws a NotImplementedException.

cc @terrajobst @stephentoub @AaronRobinsonMSFT @elinor-fung

@jkoritzinsky jkoritzinsky added api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime.InteropServices code-analyzer Marks an issue that suggests a Roslyn analyzer labels Aug 28, 2020
@jkoritzinsky jkoritzinsky added this to the 6.0.0 milestone Aug 28, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Aug 28, 2020
@AaronRobinsonMSFT AaronRobinsonMSFT removed the untriaged New issue has not been triaged by the area owner label Aug 28, 2020
@Mrnikbobjeff
Copy link

Does this actually mean that the interface has to have implementations for all methods but not provide them itself?
Specifically I would like to know whether
public interface IA { string Foo() => "Test"; } public interface IB : IA { }
IB could fulfill the attribute contract

@jkoritzinsky
Copy link
Member Author

Yes, your example would fulfill the attribute contract.

@jkoritzinsky jkoritzinsky added api-ready-for-review API is ready for review, it is NOT ready for implementation code-fixer Marks an issue that suggests a Roslyn code fixer and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Apr 20, 2021
@jkoritzinsky jkoritzinsky added the blocking Marks issues that we want to fast track in order to unblock other important work label May 19, 2021
@jkoritzinsky
Copy link
Member Author

Marking as blocking so we codify that we'll start the schedule with this issue on Friday.

@KevinCathcart
Copy link
Contributor

Is there a hard rule that no inbox analyzers are allowed to default to error severity? If not, then I pose this question: If this is not a good candidate for error severity, then what would qualify? Consider that if hypothetically the development of this feature had been driven by the compiler team rather than by COMWrappers (perhaps one could imaging the compiler team inventing it as part of an effort to refresh and improving dynamic and the DLR), then the compiler absolutely would already be emitting an error here.

When you apply this attribute you are making the statement that the interface is effectively concrete (regardless of the fact that the metadata says otherwise since it is an interface). Thus logically speaking an interface that has this attribute but which has failed to have a concrete implementation of all methods has a direct analogy in. That would be a concrete class failing to implement all abstract methods of a base class (or to fail to implement all non-DIM methods of some interface it claims to implement).

The compiler treats those an as error. Other than a rule that no in-box analyzers are allowed to default to error, it seems to me that any argument that this should be only a warning, would be equally an argument that the compiler out to downgrade the class cases to a warning. I guess there is an argument that we don't want error level diagnostics to suddenly appear in code that previously compiled (modulo people using the warnings as errors feature, but they are literally asking for it). My counter argument would be that given how extremely obscure this feature still is at the moment, I'm not sure that is really a big deal [0]. Obviously if somebody really needed to compile code that would error with this (for example there is probably a unit test that verifies the behavior in this scenario), they could suppress the diagnostic, or change the default level of the diagnostic.

Footnote [0] The complete list of public GitHub repos with source using this attribute as of time of writing:
  • dotnet/runtime
  • microsoft/CsWinRT
  • dotnet/samples
  • mono/SkiaSharp (has CsWinRT generated source for a COM wrapper)
  • SteamTools-Team/SteamTools (has CsWinRT generated source for a COM wrapper)
  • Silver-Fang/WindowsContracts.Net (repo is just CsWinRT generated source for Windows.Foundation.UniversalApiContract, Windows.Foundation.FoundationContract, and Windows.Networking.Connectivity.WwanContract)
  • A few other repos that are just forks of one of the above (that GitHub does not know are forks), or that include an unzipped copy of all the samples.

So basically only Microsoft/.NET Foundation have written public code using this that is not CsWinRT generated. So while I'm sure there are a handful of private projects using this, I'd not be shocked if it was only 100 or fewer. Or to put it another way, the legacy Desktop Framework made regularly made breaking changes that were far more impactful than adding an error here.

All that said, I'm sure the underlying feature will only become more popular to use in hand written code over time. Many developers simply only use the LTS releases for example.

@bartonjs
Copy link
Member

bartonjs commented May 21, 2021

Video

The analyzer looks good as proposed.

Regarding Error vs Warning: @terrajobst can you chime in with what the heuristics are? If there's a mode where we can be an on-by-default Error we think that might be the right answer.

@bartonjs bartonjs added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels May 21, 2021
@jkoritzinsky jkoritzinsky removed the blocking Marks issues that we want to fast track in order to unblock other important work label May 21, 2021
@jkoritzinsky jkoritzinsky added the blocked Issue/PR is blocked on something - see comments label May 21, 2021
@jkoritzinsky
Copy link
Member Author

Blocked on dotnet/roslyn#53605

@Youssef1313
Copy link
Member

@jkoritzinsky If you're working on this, you can temporarily use SyntaxFactory instead of SyntaxGenerator. The fix to SyntaxGenerator (when done) might take some time to flow into roslyn-analyzers repository (the version in roslyn-analyzers isn't updated frequently).

@jkoritzinsky
Copy link
Member Author

@Youssef1313 that worked. It's ugly, but it'll do.

@jkoritzinsky jkoritzinsky removed the blocked Issue/PR is blocked on something - see comments label May 22, 2021
@jkoritzinsky jkoritzinsky added the in-pr There is an active PR which will close this issue when it is merged label Jun 17, 2021
@jkoritzinsky jkoritzinsky self-assigned this Jul 6, 2021
@sharwell
Copy link
Member

Is there a hard rule that no inbox analyzers are allowed to default to error severity?

I always argue for the position that error severity is reserved for cases where the language specification fails to provide unambiguous semantics allowing the production of binary code for source in the specified form. Warnings are for cases where the binary code is unambiguous according to the language specification, but may not be what the user wanted. On this definition, analyzers cannot produce error diagnostics, but source generators might.

Use of Treat Warnings as Errors is highly encouraged for CI scenarios, which forces action be taken to address warnings one step removed from the innermost developer loop.

@Youssef1313
Copy link
Member

@sharwell FYI there is an analyzer with error default severity dotnet/roslyn-analyzers#5155.

@sharwell
Copy link
Member

sharwell commented Jul 26, 2021

@Youssef1313 I don't see any analyzers using that value, so I'll just update the comment for clarity. dotnet/roslyn-analyzers#5303

@jkoritzinsky
Copy link
Member Author

Fixed by dotnet/roslyn-analyzers#5129

@jkoritzinsky jkoritzinsky removed the in-pr There is an active PR which will close this issue when it is merged label Aug 18, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Sep 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.InteropServices code-analyzer Marks an issue that suggests a Roslyn analyzer code-fixer Marks an issue that suggests a Roslyn code fixer
Projects
None yet
Development

No branches or pull requests

9 participants