net_automatic_interface icon indicating copy to clipboard operation
net_automatic_interface copied to clipboard

Add support for `unsafe` keyword

Open WizzardMaker opened this issue 1 year ago • 7 comments

Thanks for implementing init so quickly last time!

I've found out, that the unsafe keyword is missing in the interface generation. It's necessary for using pointer types

Example:

public class Test {
    public unsafe Test* Function() {
        return (Test*)0;  
    }
}

Should generate:

public interface Test {
    public unsafe Test* Function();
}

On a side note, I've also seen that IntPtr gets converted to nint - they are syntactically the same but slightly differ in semantics, where IntPtr always denotes "unsafe" pointers and nint just being a representation of the native integer size. Nothing too critical but just wanted to point it out

WizzardMaker avatar Nov 02 '24 13:11 WizzardMaker

similarly, I've noticed that it doesn't support the params keyword either. Not sure if it can be resolved in the same PR or if it would need to be a separate one.

ChaseFlorell avatar Nov 05 '24 00:11 ChaseFlorell

@ChaseFlorell I think that should be a separate PR.

ChristianSauer avatar Nov 05 '24 07:11 ChristianSauer

as for the IntPR -> nint problem, that might require special handling. The types are taken from the compiler, I do not know why it's falling back to nint.

ChristianSauer avatar Nov 05 '24 07:11 ChristianSauer

as for the IntPR -> nint problem, that might require special handling. The types are taken from the compiler, I do not know why it's falling back to nint.

I think the fallback is due to the use of SymbolDisplayMiscellaneousOptions.UseSpecialTypes in our display options. A generated interface will always use int over Int32, and similarly will use nint over IntPtr - it is a direct alias in C# 11: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/numeric-intptr#summary

simonmckenzie avatar Nov 05 '24 10:11 simonmckenzie

Getting the IsUnsafe flag looks difficult - I had a bit of a look, and I can see that it's present in method.ConstructedFrom.UnderlyingMethodSymbol.InUnsafe, but it's all internal. I don't see a way to get at that data via the public API.

Given an IMethodSymbol, this is the full path to the flag:

((Microsoft.CodeAnalysis.CSharp.Symbols.SourceMemberMethodSymbol)
((Microsoft.CodeAnalysis.CSharp.Symbols.PublicModel.MethodSymbol)
((Microsoft.CodeAnalysis.IMethodSymbol)method).ConstructedFrom).UnderlyingMethodSymbol).IsUnsafe

😬

You can see the internal implementation here:

https://github.com/dotnet/roslyn/blob/2d7ee0d5da8eebaf39e6d01fb6be6f67c3a64d55/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs#L659-L665

simonmckenzie avatar Dec 03 '24 23:12 simonmckenzie

similarly, I've noticed that it doesn't support the params keyword either. Not sure if it can be resolved in the same PR or if it would need to be a separate one.

Hi @ChaseFlorell,

I've added a fix for params in #65.

simonmckenzie avatar Dec 04 '24 00:12 simonmckenzie

@simonmckenzie I had the same problem unfortunately. It seems to be almost impossible to get the unsafe flag. Bit of a pity - I had assumed it's kind of like an attribute.

ChristianSauer avatar Jan 24 '25 09:01 ChristianSauer