diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json deleted file mode 100644 index 76a3dd65c9..0000000000 --- a/.config/dotnet-tools.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "silk.net.silktouch.dotnettool": { - "version": "3.0.0-preview", - "commands": [ - "silktouch" - ] - } - } -} \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index 4d4f60532d..ef75ce2282 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -17,27 +17,27 @@ - + - + - - - + + + - + - + @@ -45,7 +45,7 @@ - + diff --git a/Silk.NET.sln b/Silk.NET.sln index b64a83616c..058a1297c2 100644 --- a/Silk.NET.sln +++ b/Silk.NET.sln @@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libraries", "libraries", "{ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Maths", "src\libraries\Silk.NET.Maths\Silk.NET.Maths.csproj", "{7A2A3176-DBA1-4026-AF65-8E36B4F09B01}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.Windowing", "src\libraries\Silk.NET.Windowing\Silk.NET.Windowing.csproj", "{7A2A3176-DBA1-4026-AF65-8E36B4F09B02}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{FD15E196-1C63-47D6-8AD5-64F015120B4B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "infrastructure", "infrastructure", "{F07CABFC-DC6A-4B5B-BC56-B10EEC2C0BFA}" @@ -44,8 +46,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Maths.Benchmarks", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.Scraper", "src\generators\Silk.NET.SilkTouch.Scraper\Silk.NET.SilkTouch.Scraper.csproj", "{EA623F04-DADA-4714-B2C5-44C82E211492}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.Common", "src\generators\Silk.NET.SilkTouch.Common\Silk.NET.SilkTouch.Common.csproj", "{C6833D95-14A8-499A-85E4-C09FA094DCE8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilkTouch", "src\generators\SilkTouch\SilkTouch.csproj", "{7DF67686-3F46-4569-935F-4A9E9903B575}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.Roslyn", "src\generators\Silk.NET.SilkTouch.Roslyn\Silk.NET.SilkTouch.Roslyn.csproj", "{11841F56-7603-40D9-BC06-10EBBE17D905}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.ClangSharp.Xml", "src\generators\Silk.NET.SilkTouch.ClangSharp.Xml\Silk.NET.SilkTouch.ClangSharp.Xml.csproj", "{CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.Emitter", "src\generators\Silk.NET.SilkTouch.Emitter\Silk.NET.SilkTouch.Emitter.csproj", "{50F26B27-32B6-4D66-ADD5-CC9C38373B19}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.Overloader", "src\generators\Silk.NET.SilkTouch.Overloader\Silk.NET.SilkTouch.Overloader.csproj", "{46A89F89-77B3-4679-A82F-04A552545B16}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Core", "src\libraries\Silk.NET.Core\Silk.NET.Core.csproj", "{69CF4437-59F7-4304-9AE1-4B58E1A93367}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Vulkan", "src\bindings\Silk.NET.Vulkan\Silk.NET.Vulkan.csproj", "{AF6E05E0-9C51-4D52-AC7E-056714CAC5F4}" @@ -70,11 +82,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.Integrat EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.TestFramework", "tests\Silk.NET.SilkTouch.TestFramework\Silk.NET.SilkTouch.TestFramework.csproj", "{381D1039-3259-488F-BB25-D90EE63A3E82}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.TypeResolution", "src\generators\Silk.NET.SilkTouch.TypeResolution\Silk.NET.SilkTouch.TypeResolution.csproj", "{7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.TypeResolution.Tests", "tests\Silk.NET.SilkTouch.TypeResolution.Tests\Silk.NET.SilkTouch.TypeResolution.Tests.csproj", "{89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch.DotnetTool", "src\generators\Silk.NET.SilkTouch.DotnetTool\Silk.NET.SilkTouch.DotnetTool.csproj", "{50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Core.Tests", "tests\Silk.NET.Core.Tests\Silk.NET.Core.Tests.csproj", "{6076C9E6-D094-49C5-B526-0AF355D11AC7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -122,6 +130,54 @@ Global {EA623F04-DADA-4714-B2C5-44C82E211492}.Release|x64.Build.0 = Release|Any CPU {EA623F04-DADA-4714-B2C5-44C82E211492}.Release|x86.ActiveCfg = Release|Any CPU {EA623F04-DADA-4714-B2C5-44C82E211492}.Release|x86.Build.0 = Release|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Debug|x64.ActiveCfg = Debug|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Debug|x64.Build.0 = Debug|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Debug|x86.ActiveCfg = Debug|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Debug|x86.Build.0 = Debug|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Release|Any CPU.Build.0 = Release|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Release|x64.ActiveCfg = Release|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Release|x64.Build.0 = Release|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Release|x86.ActiveCfg = Release|Any CPU + {C6833D95-14A8-499A-85E4-C09FA094DCE8}.Release|x86.Build.0 = Release|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Debug|x64.ActiveCfg = Debug|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Debug|x64.Build.0 = Debug|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Debug|x86.ActiveCfg = Debug|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Debug|x86.Build.0 = Debug|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Release|Any CPU.Build.0 = Release|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Release|x64.ActiveCfg = Release|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Release|x64.Build.0 = Release|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Release|x86.ActiveCfg = Release|Any CPU + {7DF67686-3F46-4569-935F-4A9E9903B575}.Release|x86.Build.0 = Release|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Debug|x64.ActiveCfg = Debug|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Debug|x64.Build.0 = Debug|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Debug|x86.ActiveCfg = Debug|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Debug|x86.Build.0 = Debug|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Release|Any CPU.ActiveCfg = Release|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Release|Any CPU.Build.0 = Release|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Release|x64.ActiveCfg = Release|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Release|x64.Build.0 = Release|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Release|x86.ActiveCfg = Release|Any CPU + {11841F56-7603-40D9-BC06-10EBBE17D905}.Release|x86.Build.0 = Release|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Debug|x64.ActiveCfg = Debug|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Debug|x64.Build.0 = Debug|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Debug|x86.ActiveCfg = Debug|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Debug|x86.Build.0 = Debug|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Release|Any CPU.Build.0 = Release|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Release|x64.ActiveCfg = Release|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Release|x64.Build.0 = Release|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Release|x86.ActiveCfg = Release|Any CPU + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793}.Release|x86.Build.0 = Release|Any CPU {50F26B27-32B6-4D66-ADD5-CC9C38373B19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {50F26B27-32B6-4D66-ADD5-CC9C38373B19}.Debug|Any CPU.Build.0 = Debug|Any CPU {50F26B27-32B6-4D66-ADD5-CC9C38373B19}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -134,6 +190,18 @@ Global {50F26B27-32B6-4D66-ADD5-CC9C38373B19}.Release|x64.Build.0 = Release|Any CPU {50F26B27-32B6-4D66-ADD5-CC9C38373B19}.Release|x86.ActiveCfg = Release|Any CPU {50F26B27-32B6-4D66-ADD5-CC9C38373B19}.Release|x86.Build.0 = Release|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Debug|Any CPU.Build.0 = Debug|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Debug|x64.ActiveCfg = Debug|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Debug|x64.Build.0 = Debug|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Debug|x86.ActiveCfg = Debug|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Debug|x86.Build.0 = Debug|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Release|Any CPU.ActiveCfg = Release|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Release|Any CPU.Build.0 = Release|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Release|x64.ActiveCfg = Release|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Release|x64.Build.0 = Release|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Release|x86.ActiveCfg = Release|Any CPU + {46A89F89-77B3-4679-A82F-04A552545B16}.Release|x86.Build.0 = Release|Any CPU {69CF4437-59F7-4304-9AE1-4B58E1A93367}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {69CF4437-59F7-4304-9AE1-4B58E1A93367}.Debug|Any CPU.Build.0 = Debug|Any CPU {69CF4437-59F7-4304-9AE1-4B58E1A93367}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -266,42 +334,22 @@ Global {381D1039-3259-488F-BB25-D90EE63A3E82}.Release|x64.Build.0 = Release|Any CPU {381D1039-3259-488F-BB25-D90EE63A3E82}.Release|x86.ActiveCfg = Release|Any CPU {381D1039-3259-488F-BB25-D90EE63A3E82}.Release|x86.Build.0 = Release|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Debug|x64.ActiveCfg = Debug|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Debug|x64.Build.0 = Debug|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Debug|x86.ActiveCfg = Debug|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Debug|x86.Build.0 = Debug|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Release|Any CPU.Build.0 = Release|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Release|x64.ActiveCfg = Release|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Release|x64.Build.0 = Release|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Release|x86.ActiveCfg = Release|Any CPU - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2}.Release|x86.Build.0 = Release|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Debug|x64.ActiveCfg = Debug|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Debug|x64.Build.0 = Debug|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Debug|x86.ActiveCfg = Debug|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Debug|x86.Build.0 = Debug|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Release|Any CPU.Build.0 = Release|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Release|x64.ActiveCfg = Release|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Release|x64.Build.0 = Release|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Release|x86.ActiveCfg = Release|Any CPU - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE}.Release|x86.Build.0 = Release|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Debug|x64.ActiveCfg = Debug|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Debug|x64.Build.0 = Debug|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Debug|x86.ActiveCfg = Debug|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Debug|x86.Build.0 = Debug|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Release|Any CPU.Build.0 = Release|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Release|x64.ActiveCfg = Release|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Release|x64.Build.0 = Release|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Release|x86.ActiveCfg = Release|Any CPU - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF}.Release|x86.Build.0 = Release|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Debug|x64.ActiveCfg = Debug|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Debug|x64.Build.0 = Debug|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Debug|x86.ActiveCfg = Debug|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Debug|x86.Build.0 = Debug|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Release|Any CPU.Build.0 = Release|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Release|x64.ActiveCfg = Release|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Release|x64.Build.0 = Release|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Release|x86.ActiveCfg = Release|Any CPU + {6076C9E6-D094-49C5-B526-0AF355D11AC7}.Release|x86.Build.0 = Release|Any CPU + {7A2A3176-DBA1-4026-AF65-8E36B4F09B02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A2A3176-DBA1-4026-AF65-8E36B4F09B02}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A2A3176-DBA1-4026-AF65-8E36B4F09B02}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A2A3176-DBA1-4026-AF65-8E36B4F09B02}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -316,7 +364,12 @@ Global {8238D9F3-E158-4633-8017-B29AA3AD61F7} = {EA3CA547-452A-4D9E-BDB3-3BC5D7F15ACA} {CB8B28DE-456A-4B8E-85A6-2C50CEE08CA2} = {FD15E196-1C63-47D6-8AD5-64F015120B4B} {EA623F04-DADA-4714-B2C5-44C82E211492} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} + {C6833D95-14A8-499A-85E4-C09FA094DCE8} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} + {7DF67686-3F46-4569-935F-4A9E9903B575} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} + {11841F56-7603-40D9-BC06-10EBBE17D905} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} + {CD47A2B9-D3D6-40CF-AE0A-B571EF9F7793} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} {50F26B27-32B6-4D66-ADD5-CC9C38373B19} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} + {46A89F89-77B3-4679-A82F-04A552545B16} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} {69CF4437-59F7-4304-9AE1-4B58E1A93367} = {C9718C94-2F21-4E8D-B55D-8F0B1A131346} {AF6E05E0-9C51-4D52-AC7E-056714CAC5F4} = {9020C7C6-C366-4BD3-8C8A-F81394EC7174} {A0726B46-F2F6-4996-A640-1BD01EEBAF07} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C} @@ -328,9 +381,8 @@ Global {5329AC43-7177-4953-AFAB-A9FA7B9A4C7C} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C} {66FE736C-C407-44C3-A94E-4345E22AA95E} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C} {381D1039-3259-488F-BB25-D90EE63A3E82} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C} - {7D181E77-CAD4-4288-AC0A-9C4D55ED1EC2} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} - {89E8EDA4-EB19-45FC-AFA1-B6A16211A9EE} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C} - {50F2BCCC-BDC8-4694-B55E-583A6A77E1CF} = {8238D9F3-E158-4633-8017-B29AA3AD61F7} + {7A2A3176-DBA1-4026-AF65-8E36B4F09B02} = {C9718C94-2F21-4E8D-B55D-8F0B1A131346} + {6076C9E6-D094-49C5-B526-0AF355D11AC7} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F5273D7F-3334-48DF-94E3-41AE6816CD4D} diff --git a/documentation/for-contributors/generators/README.md b/documentation/for-contributors/generators/README.md index c5b04edb01..710984539b 100644 --- a/documentation/for-contributors/generators/README.md +++ b/documentation/for-contributors/generators/README.md @@ -2,12 +2,12 @@ SilkTouch is the Silk.NET project's C# native interoperability code generation stack. It contains useful generators which together generate the majority of the library's codebase. -It does this by centering all parts around a [common symbol layer](./symbol-layer/README.md), which allows other parts to be used in any configuration deemed useful, parts don't have a way other then the symbol layer to exchange data, enforcing interoperability. +It does this by splitting the generation process into multiple phases, all anchored around the concept of a "shared infrastructure" - abstractions for SilkTouch generators which are agnostic of where they're running. Currently the only places SilkTouch can run is in a Roslyn Source Generator and using a `dotnet tool` Command Line Interface, but the idea is so long as no incompatibilities are introduced by each individual phase (such as being locked to .NET 6 instead of .NET Standard 2.0) the generator should be able to run in whatever form factor is desirable - the Shared Infrastructure will provide everything a generator could need for consuming a JSON configuration with C# input code and producing additional generated C# code as a result. Learn more about each individual cornerstone of the SilkTouch Stack: - -- [Symbol Layer](./symbol-layer/README.md) -- [Emitter](emitter.md) -- [Scraper](scraper.md) +- [Shared Infrastructure](shared-infrastructure.md) +- [Emitter](emitter.md) +- [Overloader](overloader.md) +- [Scraper](scraper.md) TODO: Add a link to the original proposal once the proposals folder has been reorganised according to the Software Development Plan. diff --git a/documentation/for-contributors/generators/emitter.md b/documentation/for-contributors/generators/emitter.md new file mode 100644 index 0000000000..f46d2b527d --- /dev/null +++ b/documentation/for-contributors/generators/emitter.md @@ -0,0 +1,3 @@ +# Emitter + +The Emitter. \ No newline at end of file diff --git a/documentation/for-contributors/generators/emitter/README.md b/documentation/for-contributors/generators/emitter/README.md deleted file mode 100644 index fe733a1755..0000000000 --- a/documentation/for-contributors/generators/emitter/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Emitter - -The emitter is responsible for creating Roslyn C# Code Symbols from our symbol layer. - -See [here](./about%20formatting.md) for how formatting works, and [here](./visitor.md) for details on the visitor implementation. - -In general the emitter tries it's best to be very basic doing only the job of 1:1 translating shared symbol layer into C# roslyn symbols. diff --git a/documentation/for-contributors/generators/emitter/visitor.md b/documentation/for-contributors/generators/emitter/visitor.md index 83e6fba60d..39f7b62004 100644 --- a/documentation/for-contributors/generators/emitter/visitor.md +++ b/documentation/for-contributors/generators/emitter/visitor.md @@ -1,7 +1,5 @@ # Visitor -See [here](../symbol-layer/symbol-visitor.md) for details on how the base symbol visitor works. - To Transform our internal symbol layer to C# code a visitor (`CSharpEmitter.Visitor`) is used. ## State diff --git a/documentation/for-contributors/generators/overloader.md b/documentation/for-contributors/generators/overloader.md new file mode 100644 index 0000000000..427bb135ad --- /dev/null +++ b/documentation/for-contributors/generators/overloader.md @@ -0,0 +1,3 @@ +# Overloader + +The Overloader. \ No newline at end of file diff --git a/documentation/for-contributors/generators/scraper.md b/documentation/for-contributors/generators/scraper.md index 5fba76f0c0..6eb51ac3c1 100644 --- a/documentation/for-contributors/generators/scraper.md +++ b/documentation/for-contributors/generators/scraper.md @@ -1,16 +1,39 @@ # Scraper -The Scraper will call into ClangSharp to generate XML from the given C headers (`GenerateXML`), and then convert the output produced by ClangSharp into symbols defined by the [Symbol Layer](./symbol-layer/README.md) (`ScrapeXML`). +The SilkTouch Scraper is responsible for walking through the abstract syntax tree (AST) of a C/C++ header and all the referenced headers therein to generate C# bindings to as much of this as possible where the configuration indicates this is desirable. Only certain headers will have bindings generated for them, which can be specified by providing the paths to the headers to "traverse" in the JSON configuration. -The Scraper should stay quite small and easy to use, as it is also the window to all the complexity that comes from C++, Clang, header, etc. It should only bridge the XML output into the symbol layer. +## ClangSharp -## Scraping XML +To walk through the C/C++ AST, ClangSharp's P/Invoke Generator is used, which is a proven tool for generating C# bindings to C/C++ APIs published by Microsoft. It does this by using the clang compiler to walk through the AST. -To scrape XML there is a visitor that visits each XML node and outputs several symbols per node. -This is what happens in `XmlVisitor.cs`, called from `ScrapeXML`. +ClangSharp's P/Invoke Generator is capable of producing C# bindings on its own, however these are raw bindings that use DllImport and don't aim to lift the bindings to be more C#-friendly. However, as part of Scraper development work was done to add an "XML output mode" to ClangSharp which instead of producing pure C# code, it outputs XML which roughly represents what the C# code would've looked like. -## Generating XML using ClangSharp +## The Subagent -This is what happens in `ClangScraper.cs`, which is configured using `ClangScraperConfiguration.cs`. -The XML is generated by the `ClangSharp.PInvokeGenerator` see [dotnet/ClangSharp](https://github.com/dotnet/ClangSharp) and the [PInvokeGenerator file](https://github.com/dotnet/ClangSharp/blob/main/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs). -Check XML docs for details on what methods do. +ClangSharp uses libclang, which has funny rules over multithreading. To maintain a degree of parallelism during generation, the invocation of ClangSharp was moved to be done in a separate process. The original intention was to invoke the `ClangSharpPInvokeGenerator` tool as shipped publicly, but unfortunately `dotnet tool`s cannot be referenced by other libraries or `dotnet tool`s. As such, we created our own shim which mimics the behaviour of and duplicates a lot of code from the `ClangSharpPInvokeGenerator` tool, but within the same CLI executable. + +### The `ISubagent` abstraction + +`ISubagent` is responsible for launching the ClangSharp tool with certain parameters, inputs, and configuration. This is an abstraction such that the main Scraper assembly remains easily portable to another form factor should we enable the Scraper to run in another form factor in the future, as well as to prevent the library assembly knowing too much about the assembly in which its executing. + +The only implementation of this interface is the `ClangSharpSubagent` class in the `SilkTouch` assembly (CLI implementation of the Shared Infrastructure) which gathers information on the currently executing assembly, and relaunches it with `clangsharp` as the first argument and a JSON-encoded record as the second. + +### The `silktouch clangsharp` command + +This is the command that invokes ClangSharp as described in the previous section. This deserializes the JSON-encoded record and passes the data held therein to the `PInvokeGenerator` class within ClangSharp. This will generate the XML dump and then quit, possibly with some ClangSharp-generated diagnostics and a non-zero error code if those diagnostics are severe. The implementation of this is in the `ClangSharpHandoff` class. + +## XML Mods + +Once an initial XML dump has been generated by The Subagent, the XML dump will be parsed by the `Silk.NET.SilkTouch.ClangSharp.Xml` library and produce a tree of records. This is done in the `ScraperGenerator` ahead of the XML mods stage. + +The purpose of the XML mods stage is to walk this tree of records, and modify it depending on the project configuration (for example changing all names to be PascalCase, or adding custom attributes to cause the Overloader to generate certain overloads). Each mod must be specifically enabled, and has free range over the XML. As such, they execute in the order in which they were specified in the project configuration. + +Each XML mod has access to the `ScraperJobConfiguration.ModOptions` and the full XML tree. It does not have any access to resources beyond that, such as the SilkTouch Context. + +TODO: Write words here about each XML mod once XML mods have been implemented + +## Transformation + +After the XML mods have been applied, the transformation stage is responsible for converting the bindings represented by the XML tree back into C# code that can be output via the SilkTouch Context (and added to the project compilation). Unlike ClangSharp, this stage will output bindings which are compatible with/invoke the Emitter and Overloader instead of using DllImport directly. + +TODO: Write more words here once this stage is implemented. diff --git a/documentation/for-contributors/generators/shared-infrastructure.md b/documentation/for-contributors/generators/shared-infrastructure.md new file mode 100644 index 0000000000..fe2d3327d8 --- /dev/null +++ b/documentation/for-contributors/generators/shared-infrastructure.md @@ -0,0 +1,46 @@ +# Shared Infrastructure + +The Shared Infrastructure contains common code and abstractions for bootstrapping and running generators within the SilkTouch Stack. It aims to ensure that SilkTouch generators are easily portable, and have a unified interface over multiple generation mediums such that no extra code is required in individual generators to accomodate new form factors. + +## "Form Factor" + +A "Form Factor", referred to throughout the documentation, is simply a distinct type of application which invokes the SilkTouch Stack via the Shared Infrastructure (i.e. "it's a place where SilkTouch runs"). Distinct types such as Roslyn Source Generators and Command Line Interfaces, which are the two first-party form factors supported today. + +## Configuration + +All JSON configuration structures are represented by C# records in the Silk.NET.SilkTouch.Configuration namespace (in the Configuration folder of Silk.NET.SilkTouch.Common). + +### Project Configuration + +Each project has its own JSON configuration file which defines what each generator does for that particular project. This file should be added by the user as an `AdditionalFiles` file, with the name `silktouch.json` unless the `silktouch_config_file` `.editorconfig` option in the source generator format factor or the `config` option in the CLI form factor are used to override this with a new file name or file path (either absolute or relative). + +Each generator has its own specific configuration structure, which is outlined in XML documentation in the `Config.cs` file as well as the markdown documents for each individual generator. + +The project configuration also provides a (relative or absolute) path to a file containing the global configuration. + +### Global Configuration + +The global configuration contains variables which aren't specific to a particular project or generation process/job. Stuff like the License Header, which doesn't need to be duplicated across every single project configuration. + +### CLI Configuration +The CLI has 3 ways to be configured: +- Command line parameters, possible formats are "key1=value1 --key2=value2 /key3=value3 --key4 value4 /key5 value5" +- A JSON file, with the path taken either from the config option `config` or by default silktouch.json (in the working directory) +- Environment Variables, prefixed with SilkTouch_ (to configure hierarchical data, use two underscores like `set SilkTouch_Parent__Root=value`) +The CLI uses the Microsoft.Extensions.Configuration package for this, for more information on how to use the above options see [here](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/) (note that we do not use user secrets) + +## Generation + +### SilkTouch "Context" + +The SilkTouch "Context" (represented by the `SilkTouchContext` class in the `Silk.NET.SilkTouch.Generation` namespace, or Generation folder of Silk.MET.SilkTouch.Common) encapsulates all inputs and outputs passed into and retrieved from a generator running atop the Shared Infrastructure. It exists to isolate each individual generator from one another, and provide one unified data structure containing everything a generator might reasonably need to access about a project. + +Some SilkTouch Contexts have access to outputs generated by other generators in the `AdditionalSyntaxTrees` property. To ease context consumption, there is a `AllSyntaxTrees` property which will contain both the Roslyn `Compilation`'s syntax trees as well as the newly-added syntax trees. Currently this is only the Emitter and Overloader if the Scraper has ran before them, though it is intended that the Shared Infrastructure will be expanded to have a full-blown dependency resolution mechanism to allow more generator modularity and dynamic definition of a generator's soft or hard dependencies. + +### The Generator Object + +The Generator Object (represented by the `SilkTouchGenerator` class) is responsible for the consumption of basic project information, and morphing/storing this information in a way that allows for Contexts to be created from the generator object. After a context is created, it will be consumed by a generator, and then once again "ingested" by the generator object. This generator object forwards the results to bindable events, which are subscribed to by the form factor. + +The intention of this is to reduce duplicated code between the two form factors we maintain, and provide an interface to ease the bootstrapping of SilkTouch code generation - this class significantly reduces the amount of work required to implement another form factor. + +Currently there are no methods on `SilkTouchGenerator` which can create a `SilkTouchContext` directly, nor are there APIs which nicely facilitate the passing of generated outputs to a stage depending on them. Both of which are things we'd like to address in the future. \ No newline at end of file diff --git a/documentation/for-contributors/generators/symbol-layer/README.md b/documentation/for-contributors/generators/symbol-layer/README.md deleted file mode 100644 index 028353bce1..0000000000 --- a/documentation/for-contributors/generators/symbol-layer/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Symbol Layer - -The symbol layer is a set of types in the Silk.NET.SilkTouch.Symbols, all inheriting from the central Silk.NET.SilkTouch.Symbols.Symbol type. - -The symbol layer is intended as a way to represent data passed between components of SilkTouch and is entirely immutable, with the only exception being the [Type Store](./type-store.md). - -The way to update & iterate symbols is using a [Symbol Visitor](./symbol-visitor.md). - -See [symbols](./symbols/README.md) for a list of all symbols, their visitor method, test details, etc. - -See [type references](./type-references.md) for an explanation of type references. diff --git a/documentation/for-contributors/generators/symbol-layer/symbol-visitor.md b/documentation/for-contributors/generators/symbol-layer/symbol-visitor.md deleted file mode 100644 index a1c3b97d58..0000000000 --- a/documentation/for-contributors/generators/symbol-layer/symbol-visitor.md +++ /dev/null @@ -1,19 +0,0 @@ -# Symbol Visitor - -A symbol visitor visits each symbol and then calls the appropriate methods to recursively visit all parts. -Each symbol visitor has access to a [type store](./type-store.md). It has to be provided in the constructor of every symbol visitor. -It's generally adviced to simply bubble up this constructor parameter to users of your type. - -## Updating Symbols - -Each method returns the same type it gets as parameter, so prefer to override the most specific method possible. -For example, if you wish to rename all `TypeSymbol`s, override `VisitTypeSymbol`. But if you want to add a field to every struct, override `VisitStructSymbol`. If you want to rewrite the type of a symbol, for example generate a class for every struct, again, override the most specific method that is compatible with both (in this case `VisitTypeSymbol`) and do type checks as necessary. - -### Type IDs - -See [type store](./type-store.md) for details on what type Ids are. -**Do not change type IDs when visiting symbols. This breaks all references to that type.** - -## Managing State - -While the base `SymbolVisitor` is stateless, derived types are free to introduce (mutable) state. This allow propagating state other then the new symbol up the tree. diff --git a/documentation/for-contributors/generators/symbol-layer/symbols/README.md b/documentation/for-contributors/generators/symbol-layer/symbols/README.md deleted file mode 100644 index 6cd34caa64..0000000000 --- a/documentation/for-contributors/generators/symbol-layer/symbols/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Symbols - -This document / folder is for tracking all the available symbols, and documenting what creation of one entails. - -## Relation to SymbolVisitor - -In general each symbol listed below should have a corresponding method `VisitMySymbol` the only exception being `UnresolvedTypeReference` as only few visitors should ever interact with it. - -## List - -(Order alphabetically please!) - -Parent Symbols (Unlisted, abstract): -| Name | See Also | -| ---- | -------- | -| MemberSymbol | | -| Symbol | | -| TypeReference | [here](../type-references.md) | -| TypeSymbol | | -| MethodSymbol | - -| Name | Symbol Layer File | Symbol Layer Tests | Emitter Tests | -| ---------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -| ClassSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/ClassSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ClassSymbolTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/ClassSymbolTests.cs) | -| ExternalTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/ExternalTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/ExternalTypeReferenceTests.cs) | -| FunctionPointerTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/FunctionPointerTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FunctionPointerTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/FunctionPointerTypeReferenceTests.cs) | -| FieldSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/FieldSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterFieldTests.cs) | -| IdentifierSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/IdentifierSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/IdentifierTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierSymbolTests.cs) | -| InternalTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/InternalTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/InternalTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/InternalTypeReferenceTests.cs) | -| NamespaceSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/NamespaceSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/NamespaceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterNamespaceTests.cs) | -| PointerTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/PointerTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/PointerTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/PointerTypeReferenceTests.cs) | -| StaticExternalMethodSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/StaticExternalMethodSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StaticExternalMethodSymbolTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/StaticExternalMethodSymbolTests.cs) | -| StructSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/StructSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StructTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructTests.cs) | -| UnresolvedTypeReference | [here](src/generators/Silk.NET.SilkTouch.Symbols/UnresolvedTypeReference.cs) | [here](tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/UnresolvedTypeReferenceTests.cs) | - | - -## How to create a symbol - -Checklist: - -- [ ] Write a short description of what this symbol does in the above list. -- [ ] Add the symbol to Silk.NET.SilkTouch.Symbols -- [ ] Add a partial of SymbolVisitor to below the definition, and add visiting method in there. -- [ ] Call the new visiting method either from - - The root Visit(Symbol) method, this should rarely be needed - - The parent's visit method -- [ ] Add Tests to Silk.NET.SilkTouch.Symbols.Tests for - - [ ] The type being visited with it's own visiting method - - [ ] The type being visited with it's parent (not needed if this is a new root type, with no parent) - - [ ] Each part being visited correctly. Only shallowly check this, don't check parts of parts. -- [ ] Handle symbol in Silk.NET.SilkTouch.Emitter -- [ ] Add Tests to Silk.NET.SilkTouch.Emitter.Tests - - [ ] Transforming a sample Symbol matching a specific string - - [ ] Other tests, this is highly dependend on how complex the C# output looks like - - [ ] More is better! -- [ ] You're done. Feel free to use the symbol wherever needed. Prefer to add usages in a separate PR. diff --git a/documentation/for-contributors/generators/symbol-layer/type-references.md b/documentation/for-contributors/generators/symbol-layer/type-references.md deleted file mode 100644 index a17f3c482d..0000000000 --- a/documentation/for-contributors/generators/symbol-layer/type-references.md +++ /dev/null @@ -1,14 +0,0 @@ -# Type References - -Type references are a special kind of symbol used to reference types. - -There are several kinds of type references. -During scraping (see [scraper](../scraper.md)) `UnresolvedTypeReference`s are created. -These should be resolved right after, in a process called [type resolution](../type-resolution.md). - -Type resolution leads to a variety of more specialized type references, with the two base ones being - -- `InternalTypeReference`, referencing another newly defined type somewhere in the tree. (Note that it's generally not adviced to define types this way, they should already occur somewhere higher up in the tree) -- `ExternalTypeReference`, referencing some external type, usually well known types from the standard library - -There are several other type reference types, but they are wrappers around other references, for example `PointerTypeReference`. diff --git a/documentation/for-contributors/generators/symbol-layer/type-store.md b/documentation/for-contributors/generators/symbol-layer/type-store.md deleted file mode 100644 index 1f63fc658b..0000000000 --- a/documentation/for-contributors/generators/symbol-layer/type-store.md +++ /dev/null @@ -1,15 +0,0 @@ -# Type Store - -The type store is a simple helper to resolve type identifier to the latest instance. -It's available from inside every [Symbol Visitor](./symbol-visitor.md). - -## Type IDs - -`TypeId`s are a small `struct` intended to help reference types across trees. -This is useful because all symbols are immutable, and this makes it impossible to have loops in the symbol tree. -To allow loops, the type store is mutable and resolves each type id to the latest immutable version. - -## Updating - -The type store needs updating when changing a type. Usually [Symbol Visitors](./symbol-visitor) will do this automatically after visiting a type (`VisitType`), but inheritors overriding this should do this manually using -`Store(TypeSymbol)`. diff --git a/documentation/for-contributors/generators/testing.md b/documentation/for-contributors/generators/testing.md index 7c8fa690aa..740e0b2c7c 100644 --- a/documentation/for-contributors/generators/testing.md +++ b/documentation/for-contributors/generators/testing.md @@ -4,8 +4,6 @@ SilkTouch Generators should be extensively Tested. ## Unit Tests -See also [symbol creation instructions](./symbol-layer/symbols/README.md) for details on symbol unit tests. - ### Traits All Unit & Integration tests should be flagged with the appropriate Category (Emitter, Scraper, Symbols, Integration) using `Trait("Category", "MyCategory")`. @@ -27,6 +25,6 @@ Tests should be written covering XML -> Symbol conversion. No C(++) -> XML tests Tests should be written covering Symbol -> C# conversion. -## Integration Tests +### Integration Integration Tests should exist to cover most if not all areas of the generator. These are simply a sanity check & samples of what the generator can do. Unit Tests are still required. diff --git a/documentation/for-contributors/generators/type-resolution.md b/documentation/for-contributors/generators/type-resolution.md deleted file mode 100644 index 6f8cbd3840..0000000000 --- a/documentation/for-contributors/generators/type-resolution.md +++ /dev/null @@ -1,5 +0,0 @@ -# Type Resolution - -The resolution code lives in Silk.NET.SilkTouch.TypeResolution and is concerned with resolving `UnresolvedTypeReference` to actual `TypeReference`s. - -As the individual parts are only loosely connected and aren't generally dependent on each other, we do not document the individual parts here, please check the XML docs of each of the classes. diff --git a/nuget.config b/nuget.config index 128d95e590..b2f8b565e8 100644 --- a/nuget.config +++ b/nuget.config @@ -1,12 +1,12 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/Silk.NET.SilkTouch.ClangSharp.Xml.csproj b/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/Silk.NET.SilkTouch.ClangSharp.Xml.csproj new file mode 100644 index 0000000000..4f444d8c8b --- /dev/null +++ b/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/Silk.NET.SilkTouch.ClangSharp.Xml.csproj @@ -0,0 +1,7 @@ + + + + net6.0 + + + diff --git a/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/XmlBindings.cs b/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/XmlBindings.cs new file mode 100644 index 0000000000..af62acb74a --- /dev/null +++ b/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/XmlBindings.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Silk.NET.SilkTouch.ClangSharp.Xml +{ + /// + /// The root of the XML bindings tree. + /// + public class XmlBindings + { + + } +} diff --git a/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/XmlBindingsVisitor.cs b/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/XmlBindingsVisitor.cs new file mode 100644 index 0000000000..4fac621b52 --- /dev/null +++ b/src/generators/Silk.NET.SilkTouch.ClangSharp.Xml/XmlBindingsVisitor.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Silk.NET.SilkTouch.ClangSharp.Xml +{ + /// + /// A visitor for the XML bindings tree. + /// + public class XmlBindingsVisitor + { + + } +} diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/Shims.cs b/src/generators/Silk.NET.SilkTouch.Common/Shims.cs similarity index 100% rename from src/generators/Silk.NET.SilkTouch.TypeResolution/Shims.cs rename to src/generators/Silk.NET.SilkTouch.Common/Shims.cs diff --git a/src/generators/Silk.NET.SilkTouch.Common/Silk.NET.SilkTouch.Common.csproj b/src/generators/Silk.NET.SilkTouch.Common/Silk.NET.SilkTouch.Common.csproj new file mode 100644 index 0000000000..6791d3327d --- /dev/null +++ b/src/generators/Silk.NET.SilkTouch.Common/Silk.NET.SilkTouch.Common.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.0 + Silk.NET.SilkTouch + true + + + + + + + + + + + + + diff --git a/src/generators/Silk.NET.SilkTouch.DotnetTool/Program.cs b/src/generators/Silk.NET.SilkTouch.DotnetTool/Program.cs deleted file mode 100644 index e9341e2e55..0000000000 --- a/src/generators/Silk.NET.SilkTouch.DotnetTool/Program.cs +++ /dev/null @@ -1,530 +0,0 @@ -using System; -using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.Invocation; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using System.Xml; -using ClangSharp; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Silk.NET.SilkTouch.Emitter; -using Silk.NET.SilkTouch.Scraper; -using Silk.NET.SilkTouch.Symbols; -using Silk.NET.SilkTouch.TypeResolution; -using Symbol=Silk.NET.SilkTouch.Symbols.Symbol; -using Type=System.Type; - -namespace Silk.NET.SilkTouch.DotnetTool -{ - internal class Program - { - static async Task Main(string[] args) - { - var logLevel = new Option(new[] { "log-level", "l" }, () => LogLevel.Information); - var useStandardIncludes = new Option(new[] { "standard-includes", "si" }, () => true); - var extraIncludedDirectories = new Option - (new[] { "extra-included-directories", "exd" }, Array.Empty) - { - AllowMultipleArgumentsPerToken = true - }; - var includedNames = new Option - (new[] { "included-names" }, Array.Empty) - { - AllowMultipleArgumentsPerToken = true - }; - var excludedNames = new Option - (new[] { "excluded-names" }, Array.Empty) - { - AllowMultipleArgumentsPerToken = true - }; - var definedMacros = new Option - (new[] { "defined-macros" }, Array.Empty) - { - AllowMultipleArgumentsPerToken = true - }; - var headerFile = new Option(new[] { "header-file" }) - { - IsRequired = true - }; - - var usedSymbolVisitors = new Option - ( - new[] { "used-symbol-visitors", "vs" }, - () => AvailableSymbolVisitors.AllTypeResolvers, - "The symbol visitors called to process the raw symbols into those used to emit C#." + - " Generally includes most type resolvers and overloaders as appropriate." - ); - - var xmlFile = new Option(new[] { "xml-file", "xf" }, "The File to read/write XML from/to"); - var rawSymbolsFile = new Option - (new[] { "raw-symbols-file", "rsf" }, "The File to read/write Raw Symbols from/to"); - var processedSymbolsFile = new Option - (new[] { "processed-symbols-file", "psf" }, "The File to read/write Processed Symbols from/to"); - var csharpDir = new Option - (new[] { "csharp-directory", "csharp-dir", "csd" }, "The Directory to read/write C# files from/to"); - - var generateBindings = new Command("bindings") - { - logLevel, - xmlFile, - rawSymbolsFile, - processedSymbolsFile, - csharpDir, - extraIncludedDirectories, - includedNames, - excludedNames, - definedMacros, - headerFile, - usedSymbolVisitors - }; - generateBindings.SetHandler - ( - - (async (context) => - { - var serviceProvider = CreateServiceProvider(context.ParseResult.GetValueForOption(logLevel)); - XmlDocument xmlDoc = GetXml - ( - serviceProvider, - context.ParseResult.GetValueForOption(useStandardIncludes), - context.ParseResult.GetValueForOption(extraIncludedDirectories)!, - context.ParseResult.GetValueForOption(headerFile)!.FullName, - context.ParseResult.GetValueForOption(includedNames)!, - context.ParseResult.GetValueForOption(excludedNames)!, - context.ParseResult.GetValueForOption(definedMacros)! - ); - var xmlFileRes = context.ParseResult.GetValueForOption(xmlFile); - if (xmlFileRes is not null) - { - if (xmlFileRes.Exists) xmlFileRes.Delete(); - await using var stream = xmlFileRes.OpenWrite(); - await using var writer = new XmlTextWriter(stream, Encoding.UTF8); - xmlDoc.WriteTo(writer); - } - - var (rawSymbols, typeStore) = GetSymbols(serviceProvider, xmlDoc); - var rawSymbolsFileRes = context.ParseResult.GetValueForOption(rawSymbolsFile); - if (rawSymbolsFileRes is not null) - { - if (rawSymbolsFileRes.Exists) rawSymbolsFileRes.Delete(); - await using var stream = rawSymbolsFileRes.OpenWrite(); - await JsonSerializer.SerializeAsync(stream, rawSymbols, GetJsonOptions()); - } - - var processedSymbols = ProcessSymbols - ( - serviceProvider, - rawSymbols, - typeStore, - context.ParseResult.GetValueForOption(usedSymbolVisitors) - ); - var processedSymbolsFileRes = context.ParseResult.GetValueForOption(processedSymbolsFile); - if (processedSymbolsFileRes is not null) - { - if (processedSymbolsFileRes.Exists) processedSymbolsFileRes.Delete(); - await using var stream = processedSymbolsFileRes.OpenWrite(); - await JsonSerializer.SerializeAsync(stream, processedSymbols, GetJsonOptions()); - } - - var csharp = GetCSharp(serviceProvider, processedSymbols, typeStore).Select(x => x.ToFullString()) - .Select((x, i) => (x, i.ToString() + ".cs")); - var csharpDirRes = context.ParseResult.GetValueForOption(csharpDir); - if (csharpDirRes is not null) - { - foreach (var (contents, fileName) in csharp) - { - var path = Path.Combine(csharpDirRes.FullName, fileName); - await File.WriteAllTextAsync(path, contents); - } - } - }) - ); - - var generateCSharp = new Command("csharp") - { - processedSymbolsFile, csharpDir, logLevel - }; - generateCSharp.SetHandler - ( - (async static (processedSymbolsFile, csharpDir, logLevel) => - { - var serviceProvider = CreateServiceProvider(logLevel); - Symbol[] symbols; - TypeStore typeStore; - if (processedSymbolsFile is null) - { - symbols = Array.Empty(); - typeStore = new TypeStore(); - } - else - { - var logger = serviceProvider.GetRequiredService>(); - logger.LogInformation("Loading Symbols from File..."); - await using var stream = processedSymbolsFile.OpenRead(); - symbols = await JsonSerializer.DeserializeAsync(stream, GetJsonOptions()) ?? Array.Empty(); - logger.LogInformation("Loaded {count} Symbols from Disk. Restoring Type Store...", symbols.Length); - typeStore = RestoreTypeStore(symbols); - logger.LogInformation("Type Store Restored"); - } - - var csharp = GetCSharp(serviceProvider, symbols, typeStore).Select(x => x.ToFullString()) - .Select((x, i) => (x, i.ToString() + ".cs")); - if (csharpDir is not null) - { - foreach (var (contents, fileName) in csharp) - { - var path = Path.Combine(csharpDir.FullName, fileName); - await File.WriteAllTextAsync(path, contents); - } - } - }), - processedSymbolsFile, - csharpDir, - logLevel - ); - - var generateRawSymbols = new Command("raw-symbols") - { - xmlFile, - rawSymbolsFile, - logLevel - }; - generateRawSymbols.SetHandler( - (Func) - (async static (xmlFile, rawSymbolsFile, logLevel) => - { - var serviceProvider = CreateServiceProvider(logLevel); - Symbol[] symbols; - TypeStore typeStore; - if (xmlFile is null) - { - symbols = Array.Empty(); - typeStore = new TypeStore(); - } - else - { - var logger = serviceProvider.GetRequiredService>(); - var xmlDoc = new XmlDocument(); - await using var stream = xmlFile.OpenRead(); - xmlDoc.Load(stream); - (symbols, typeStore) = GetSymbols(serviceProvider, xmlDoc); - logger.LogTrace("{count} Symbols Scraped from XML", symbols.Length); - } - - if (rawSymbolsFile is not null) - { - if (rawSymbolsFile.Exists) rawSymbolsFile.Delete(); - await using var stream = rawSymbolsFile.OpenWrite(); - await JsonSerializer.SerializeAsync(stream, symbols, GetJsonOptions()); - } - }), xmlFile, rawSymbolsFile, logLevel); - - var generateXML = new Command("xml") - { - xmlFile, - logLevel, - useStandardIncludes, - extraIncludedDirectories, - includedNames, - excludedNames, - definedMacros, - headerFile - }; - generateXML.SetHandler - ( - (async static (xmlFile, logLevel, useStandardIncludes, extraIncludedDirectories, - includedNames, excludedNames, definedMacros, headerFile) => - { - var serviceProvider = CreateServiceProvider(logLevel); - XmlDocument xmlDoc = GetXml - ( - serviceProvider, - useStandardIncludes, - extraIncludedDirectories, - headerFile.FullName, - includedNames, - excludedNames, - definedMacros - ); - if (xmlFile is not null) - { - if (xmlFile.Exists) xmlFile.Delete(); - await using var stream = xmlFile.OpenWrite(); - await using var writer = new XmlTextWriter(stream, Encoding.UTF8); - xmlDoc.WriteTo(writer); - } - }), - xmlFile, - logLevel, - useStandardIncludes, - extraIncludedDirectories, - includedNames, - excludedNames, - definedMacros, - headerFile - ); - - var processSymbols = new Command("process-symbols") - { - logLevel, - rawSymbolsFile, - processedSymbolsFile, - usedSymbolVisitors - }; - processSymbols.SetHandler( - async static (logLevel, rawSymbolsFile, processedSymbolsFile, usedSymbolVisitors) => - { - var serviceProvider = CreateServiceProvider(logLevel); - - Symbol[] rawSymbols; - TypeStore typeStore; - if (rawSymbolsFile is null) - { - rawSymbols = Array.Empty(); - typeStore = new TypeStore(); - } - else - { - var logger = serviceProvider.GetRequiredService>(); - logger.LogInformation("Loading Symbols from File..."); - await using var stream = rawSymbolsFile.OpenRead(); - rawSymbols = await JsonSerializer.DeserializeAsync(stream, GetJsonOptions()) ?? Array.Empty(); - logger.LogInformation("Loaded {count} Symbols from Disk. Restoring Type Store...", rawSymbols.Length); - typeStore = RestoreTypeStore(rawSymbols); - logger.LogInformation("Type Store Restored"); - } - - var processedSymbols = ProcessSymbols(serviceProvider, rawSymbols, typeStore, usedSymbolVisitors); - if (processedSymbolsFile is not null) - { - if (processedSymbolsFile.Exists) processedSymbolsFile.Delete(); - await using var stream = processedSymbolsFile.OpenWrite(); - await JsonSerializer.SerializeAsync(stream, processedSymbols, GetJsonOptions()); - } - - }, logLevel, rawSymbolsFile, processedSymbolsFile, usedSymbolVisitors); - - var generate = new Command("generate") - { - generateBindings, - generateCSharp, - generateRawSymbols, - generateXML, - processSymbols - }; - - var rootCommand = new RootCommand - ("SilkTouch dotnet tool. Use to generate the silkiest bindings you've ever seen!") - { - generate - }; - - return await rootCommand.InvokeAsync(args); - } - - private static IEnumerable ProcessSymbols - (IServiceProvider serviceProvider, IEnumerable symbols, TypeStore typeStore, AvailableSymbolVisitors usedSymbolVisitors) - { - var visitors = new List(); - - if ((usedSymbolVisitors & AvailableSymbolVisitors.PointerTypeResolver) != 0) - { - visitors.Add(ActivatorUtilities.CreateInstance(serviceProvider, typeStore)); - } - - if ((usedSymbolVisitors & AvailableSymbolVisitors.FunctionPointerTypeResolver) != 0) - { - visitors.Add(ActivatorUtilities.CreateInstance(serviceProvider, typeStore)); - } - - if ((usedSymbolVisitors & AvailableSymbolVisitors.InternalTypeResolver) != 0) - { - var typeScopeSymbolVisitor = ActivatorUtilities.CreateInstance - (serviceProvider, typeStore); - visitors.Add(typeScopeSymbolVisitor); - visitors.Add - ( - ActivatorUtilities.CreateInstance - (serviceProvider, typeScopeSymbolVisitor.RootScope, typeStore) - ); - } - - if ((usedSymbolVisitors & AvailableSymbolVisitors.PrimitiveTypeResolver) != 0) - { - visitors.Add(ActivatorUtilities.CreateInstance(serviceProvider, typeStore)); - } - - - foreach (var visitor in visitors) - { - symbols = symbols.Select(visitor.Visit); - } - - return symbols; - } - - private static XmlDocument GetXml - ( - IServiceProvider serviceProvider, - bool useStandardIncludes, - string[] extraIncludedDirectories, - string headerFile, - string[] includedNames, - string[] excludedNames, - string[] definedMacros - ) - { - var scraper = ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider); - var includedDirectories = new List(); - if (useStandardIncludes) - { - includedDirectories.AddRange(scraper.ResolveStandardIncludes()); - } - includedDirectories.AddRange(extraIncludedDirectories); - - var xml = scraper.GenerateXML(headerFile, includedNames, excludedNames, includedDirectories.ToArray(), definedMacros); - - return xml ?? new XmlDocument(); - } - - private static (Symbol[], TypeStore) GetSymbols(IServiceProvider serviceProvider, XmlDocument xml) - { - var scraper = ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider); - var typeStore = new TypeStore(); - var symbols = scraper.ScrapeXML(xml, typeStore).ToArray(); - - return (symbols, typeStore); - } - - private static TypeStore RestoreTypeStore(IEnumerable symbols) - { - var typeStore = new TypeStore(); - var visitor = new TypeStoreRestoreVisitor(typeStore); - - foreach (var symbol in symbols) - { - visitor.Visit(symbol); // discard, we don't care - } - - return typeStore; - } - - private static IEnumerable GetCSharp(IServiceProvider serviceProvider, IEnumerable symbols, TypeStore typeStore) - { - var emitter = ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider); - - return symbols.Select(x => emitter.Transform(x, typeStore)); - } - - - private sealed class TypeStoreRestoreVisitor : SymbolVisitor - { - public TypeStoreRestoreVisitor(TypeStore typeStore) : base(typeStore) - { } - - protected override TypeReference VisitTypeReference(TypeReference typeReference) - { - if (typeReference is UnresolvedTypeReference) return typeReference; - return base.VisitTypeReference(typeReference); - } - } - - - private static IServiceProvider CreateServiceProvider(LogLevel minimum) - { - - var configuration = new ConfigurationBuilder() - .AddEnvironmentVariables(source => source.Prefix = "SILK_DOTNET_") - .Build(); - var serviceProvider = new ServiceCollection() - .AddLogging(builder => - { - builder.AddConsole(); - builder.SetMinimumLevel(minimum); - } - ) - .Configure(configuration.GetSection("Scraper")) - .AddSingleton() - .AddSingleton() - .BuildServiceProvider(); - return serviceProvider; - } - - private static JsonSerializerOptions GetJsonOptions() - { - var opts = new JsonSerializerOptions(); - opts.Converters.Add(new SymbolJsonConverterFactory()); - return opts; - } - - private sealed class SymbolJsonConverterFactory : JsonConverterFactory - { - - public override bool CanConvert - (Type typeToConvert) => typeToConvert.IsAbstract && typeToConvert.IsAssignableTo(typeof(Symbol)); - public override JsonConverter? CreateConverter - (Type typeToConvert, JsonSerializerOptions options) => (JsonConverter?) Activator.CreateInstance - (typeof(SymbolJsonConverter<>).MakeGenericType(typeToConvert)); - } - - private sealed class SymbolJsonConverter - : JsonConverter - where T : Symbol - { - public override bool CanConvert - // If a leaf type (non-abstract) is given, serialize as that - (Type typeToConvert) => typeToConvert.IsAbstract && typeToConvert.IsAssignableTo(typeof(T)); - - public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - using var document = JsonDocument.ParseValue(ref reader); - if (!document.RootElement.TryGetProperty("type", out var typeProp) || typeProp.GetString() is not {} type) - throw new InvalidOperationException("Cannot deserialize symbol without \"type\""); - - var symbolType = typeof(T).Assembly.GetTypes().First(x => x.Name == type); - if (symbolType is null) - throw new InvalidOperationException($"Could not find type {type}"); - - return document.Deserialize(symbolType, options) as T; - } - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) - { - writer.WriteStartObject(); - - var type = value.GetType(); - writer.WritePropertyName("type"); - writer.WriteStringValue(type.Name); - - var element = JsonSerializer.SerializeToElement(value, type, options); - foreach (var prop in element.EnumerateObject()) - { - writer.WritePropertyName(prop.Name); - prop.Value.WriteTo(writer); - } - - writer.WriteEndObject(); - } - } - - [Flags] - private enum AvailableSymbolVisitors - { - None = 0, - PointerTypeResolver = 1 << 1, - InternalTypeResolver = 1 << 2, - PrimitiveTypeResolver = 1 << 3, - FunctionPointerTypeResolver = 1 << 4, - AllTypeResolvers = PointerTypeResolver | InternalTypeResolver | PrimitiveTypeResolver | FunctionPointerTypeResolver, - } - } -} diff --git a/src/generators/Silk.NET.SilkTouch.Emitter/CSharpEmitter.cs b/src/generators/Silk.NET.SilkTouch.Emitter/CSharpEmitter.cs index d710696797..c59f0a408b 100644 --- a/src/generators/Silk.NET.SilkTouch.Emitter/CSharpEmitter.cs +++ b/src/generators/Silk.NET.SilkTouch.Emitter/CSharpEmitter.cs @@ -4,7 +4,6 @@ using System; using System.CodeDom.Compiler; using System.Collections.Generic; -using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis; @@ -27,12 +26,11 @@ public CSharpEmitter() { } - + /// /// Transforms the given into a /// /// The symbol to transform - /// The used /// A syntax node, containing syntax depending on the symbol. The syntax node should produce valid C# code. /// /// The returned syntax node may not be ideal and is not optimized for code size. @@ -41,9 +39,9 @@ public CSharpEmitter() /// The returned node will never contain line comments, but other C# language feature may still rely on whitespace and/or newlines. /// Note that (block) comments will never be used to replace such whitespace, even if this is valid to allow a potential comment stripping to be a simple as possible. /// - public CSharpSyntaxNode Transform(Symbol symbol, TypeStore typeStore) + public CSharpSyntaxNode Transform(Symbol symbol) { - var visitor = new Visitor(Whitespace(" "), typeStore); + var visitor = new Visitor(Whitespace(" ")); visitor.Visit(symbol); // the result is ignored. This allows us to optimize the visitor in some cases. var syntax = visitor.Syntax; if (syntax is null) @@ -63,7 +61,7 @@ private class Visitor : Silk.NET.SilkTouch.Symbols.SymbolVisitor private IEnumerable Indentation => Enumerable.Repeat(_indentation, _indentationCount); private IEnumerable NewLine => Indentation.Prepend(LineFeed); - public Visitor(SyntaxTrivia indentation, TypeStore typeStore) : base(typeStore) + public Visitor(SyntaxTrivia indentation) : base() { _indentation = indentation; } @@ -107,43 +105,6 @@ protected override StructSymbol VisitStruct(StructSymbol structSymbol) return structSymbol; } - protected override ClassSymbol VisitClass(ClassSymbol classSymbol) - { - AssertClearState(); - - VisitIdentifier(classSymbol.Identifier); - if (_syntaxToken is not {} identifierSyntaxToken) - throw new InvalidOperationException("Identifier was not visited correctly"); - ClearState(); - - Indent(); - var members = List - ( - classSymbol.Methods.Select - ( - x => - { - VisitMethod(x); - if (_syntax is not MethodDeclarationSyntax mds) - throw new InvalidOperationException("Method not visited correctly"); - ClearState(); - return ((MemberDeclarationSyntax) mds).WithLeadingTrivia(NewLine); - } - ) - .ToImmutableArray() - ); - Outdent(); - - _syntax = ClassDeclaration(identifierSyntaxToken.WithLeadingTrivia(Space)) - .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))) - .WithKeyword(Token(SyntaxKind.ClassKeyword).WithLeadingTrivia(Space)) - .WithOpenBraceToken(Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(NewLine)) - .WithCloseBraceToken(Token(SyntaxKind.CloseBraceToken).WithLeadingTrivia(NewLine)) - .WithMembers(members); - - return classSymbol; - } - protected override FieldSymbol VisitField(FieldSymbol fieldSymbol) { AssertClearState(); @@ -206,153 +167,6 @@ protected override NamespaceSymbol VisitNamespace(NamespaceSymbol namespaceSymbo return namespaceSymbol; } - protected override InternalTypeReference VisitInternalTypeReference(InternalTypeReference typeReference) - { - AssertClearState(); - - if (!TypeStore.TryResolve(typeReference.ReferencedTypeId, out var type)) - { - throw new NotImplementedException("Cannot handle unresolvable type ID"); - } - - // TODO: Fully resolve types - VisitIdentifier(type!.Identifier); - - return typeReference; - } - - protected override PointerTypeReference VisitPointerTypeReference(PointerTypeReference pointerTypeReference) - { - AssertClearState(); - - VisitTypeReference(pointerTypeReference.Underlying); - if (_syntaxToken is not {} innerToken) - throw new InvalidOperationException("Type Reference was not visited correctly"); - ClearState(); - - _syntaxToken = Identifier(innerToken.Text + "*"); - _syntax = IdentifierName(_syntaxToken.Value); - - return pointerTypeReference; - } - - protected override FunctionPointerTypeReference VisitFunctionPointerTypeReference - (FunctionPointerTypeReference functionPointerTypeReference) - { - AssertClearState(); - - var paramList = functionPointerTypeReference.ParameterTypes - .Append(functionPointerTypeReference.ReturnType) - .Select - ( - (x, i) => - { - VisitTypeReference(x); - if (_syntax is not TypeSyntax typeSyntax) - throw new InvalidOperationException("TypeReference did not return TypeSyntax"); - ClearState(); - - if (i == 0 || i > functionPointerTypeReference.ParameterTypes.Length) - return typeSyntax; - else - return typeSyntax.WithLeadingTrivia(Space); // not ideal, but the easiest way to do this - } - ) - .Select(FunctionPointerParameter) - .ToImmutableArray(); - - _syntax = FunctionPointerType - ( - Token(SyntaxKind.DelegateKeyword), - Token(SyntaxKind.AsteriskToken), - FunctionPointerCallingConvention(Token(SyntaxKind.UnmanagedKeyword)).WithLeadingTrivia(Space), - FunctionPointerParameterList - ( - SeparatedList(paramList) - ) - ); - - return functionPointerTypeReference; - } - - protected override ExternalTypeReference VisitExternalTypeReference(ExternalTypeReference typeReference) - { - AssertClearState(); - - if (typeReference.Namespace is null) - { - // if namespace is null, the reference is just equivalent to the type identifier - VisitIdentifier(typeReference.TypeIdentifier); - } - else - { - VisitIdentifier(typeReference.Namespace); - if (_syntaxToken is not {} @namespace) - throw new InvalidOperationException("Namespace Identifier was not visited correctly"); - ClearState(); - - VisitIdentifier(typeReference.TypeIdentifier); - - if (_syntaxToken is not {} typeIdentifier) - throw new InvalidOperationException("External Type Identifier was not visited correctly"); - ClearState(); - - _syntaxToken = Identifier(@namespace.Text + "." + typeIdentifier.Text); - _syntax = IdentifierName(_syntaxToken.Value); - return typeReference; - } - - return typeReference; - } - - protected override StaticExternalMethodSymbol VisitStaticExternalMethod(StaticExternalMethodSymbol staticExternalMethodSymbol) - { - AssertClearState(); - - VisitTypeReference(staticExternalMethodSymbol.ReturnType); - if (_syntax is not TypeSyntax returnSyntaxToken) - throw new InvalidOperationException("Type Reference not correctly visited"); - ClearState(); - - VisitIdentifier(staticExternalMethodSymbol.Identifier); - if (_syntaxToken is not {} identifierToken) - throw new InvalidOperationException("Type Reference not correctly visited"); - ClearState(); - - var parameters = staticExternalMethodSymbol.Parameters.Select - ( - x => - { - VisitTypeReference(x.TypeReference); - if (_syntax is not TypeSyntax resultToken) - throw new InvalidOperationException("Type Reference not correctly visited"); - ClearState(); - - VisitIdentifier(x.Identifier); - if (_syntaxToken is not {} identifierToken2) - throw new InvalidOperationException("Syntax Token was not correctly visited"); - ClearState(); - - return Parameter(identifierToken2.WithLeadingTrivia(Space)).WithType(resultToken); - } - ).ToImmutableArray(); - - _syntax = MethodDeclaration(returnSyntaxToken.WithLeadingTrivia(Space), identifierToken.WithLeadingTrivia(Space)) - .WithModifiers - ( - TokenList - ( - Token(SyntaxKind.PublicKeyword), - Token(SyntaxKind.StaticKeyword).WithLeadingTrivia(Space), - Token(SyntaxKind.ExternKeyword).WithLeadingTrivia(Space) - ) - ) - .WithParameterList(ParameterList(SeparatedList(parameters))) - .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); - - return staticExternalMethodSymbol; - } - protected override IdentifierSymbol VisitIdentifier(IdentifierSymbol identifierSymbol) { AssertClearState(); diff --git a/src/generators/Silk.NET.SilkTouch.Overloader/Silk.NET.SilkTouch.Overloader.csproj b/src/generators/Silk.NET.SilkTouch.Overloader/Silk.NET.SilkTouch.Overloader.csproj new file mode 100644 index 0000000000..2df0ad1f71 --- /dev/null +++ b/src/generators/Silk.NET.SilkTouch.Overloader/Silk.NET.SilkTouch.Overloader.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/src/generators/Silk.NET.SilkTouch.Roslyn/Silk.NET.SilkTouch.Roslyn.csproj b/src/generators/Silk.NET.SilkTouch.Roslyn/Silk.NET.SilkTouch.Roslyn.csproj new file mode 100644 index 0000000000..621aa85eb3 --- /dev/null +++ b/src/generators/Silk.NET.SilkTouch.Roslyn/Silk.NET.SilkTouch.Roslyn.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + + + + + + + + diff --git a/src/generators/Silk.NET.SilkTouch.Scraper/ClangScraper.cs b/src/generators/Silk.NET.SilkTouch.Scraper/ClangScraper.cs index 72c172c59e..56905af060 100644 --- a/src/generators/Silk.NET.SilkTouch.Scraper/ClangScraper.cs +++ b/src/generators/Silk.NET.SilkTouch.Scraper/ClangScraper.cs @@ -49,9 +49,8 @@ public ClangScraper(ILoggerFactory loggerFactory, IOptions /// A XML Document, the format is assumed to be similar to what ClangSharp would output. - /// A used when creating symbols /// Any number of symbols scraped from the given xml - public IEnumerable ScrapeXML(XmlDocument document, TypeStore typeStore) + public IEnumerable ScrapeXML(XmlDocument document) { var bindings = document.ChildNodes.Cast().OfType().FirstOrDefault(); @@ -60,7 +59,7 @@ public IEnumerable ScrapeXML(XmlDocument document, TypeStore typeStore) return Enumerable.Empty(); } - var visitor = new XmlVisitor(_loggerFactory.CreateLogger(), typeStore); + var visitor = new XmlVisitor(_loggerFactory.CreateLogger()); return visitor.Visit(bindings); } @@ -260,29 +259,8 @@ out var handle try { - if (result == CXErrorCode.CXError_Failure) - { - if (handle.NumDiagnostics > 0) - { - for (uint i = 0; i < handle.NumDiagnostics; i++) - { - var x = handle.GetDiagnostic(i); - - logger.Log(x.Severity switch - { - CXDiagnosticSeverity.CXDiagnostic_Ignored => LogLevel.Trace, - CXDiagnosticSeverity.CXDiagnostic_Note => LogLevel.Debug, - CXDiagnosticSeverity.CXDiagnostic_Warning => LogLevel.Warning, - CXDiagnosticSeverity.CXDiagnostic_Error => LogLevel.Error, - CXDiagnosticSeverity.CXDiagnostic_Fatal => LogLevel.Critical, - _ => throw new ArgumentOutOfRangeException() - }, "{category} {message}", x.CategoryText, x.Format(0)); - } - } - - throw new Exception($"Could not parse translational unit. {Enum.GetName(result)}"); - } - else if (result != CXErrorCode.CXError_Success) + + if (result != CXErrorCode.CXError_Success) { if (handle.NumDiagnostics > 0) { @@ -295,7 +273,7 @@ out var handle } } } - + throw new Exception($"Could not parse translational unit. {Enum.GetName(result)}"); } diff --git a/src/generators/Silk.NET.SilkTouch.Scraper/Silk.NET.SilkTouch.Scraper.csproj b/src/generators/Silk.NET.SilkTouch.Scraper/Silk.NET.SilkTouch.Scraper.csproj index 61ada58695..3384fd7540 100644 --- a/src/generators/Silk.NET.SilkTouch.Scraper/Silk.NET.SilkTouch.Scraper.csproj +++ b/src/generators/Silk.NET.SilkTouch.Scraper/Silk.NET.SilkTouch.Scraper.csproj @@ -8,9 +8,7 @@ - - - + diff --git a/src/generators/Silk.NET.SilkTouch.Scraper/Subagent/VisualStudioResolver.cs b/src/generators/Silk.NET.SilkTouch.Scraper/Subagent/VisualStudioResolver.cs index d70027180c..55c5d6fba9 100644 --- a/src/generators/Silk.NET.SilkTouch.Scraper/Subagent/VisualStudioResolver.cs +++ b/src/generators/Silk.NET.SilkTouch.Scraper/Subagent/VisualStudioResolver.cs @@ -96,8 +96,10 @@ public static bool TryGetVisualStudioInfo([NotNullWhen(true)] out VisualStudioIn Debug.WriteLine(visualStudios.Length + " Visual Studio installation(s)"); // cycle through candidate installations, try and find everything we're looking for. + var hasVs = false; foreach (var visualStudio in visualStudios) { + hasVs = true; Debug.WriteLine ( $"Testing \"{visualStudio.Name}\" v{visualStudio.Version.ToString(3)} at " + @@ -156,8 +158,21 @@ public static bool TryGetVisualStudioInfo([NotNullWhen(true)] out VisualStudioIn return true; } + if (!hasVs) + { + Console.WriteLine("No instance of Visual Studio found whatsoever."); + } + + // if any of it's still null, we couldn't find a candidate. + Console.WriteLine + ( + "Couldn't find a viable Visual Studio installation - ensure you have the Windows 10 SDK and C++ " + + "tools installed. SilkTouch Scraper may not function correctly without Visual Studio or Visual " + + "Studio Build Tools with these workloads." + ); + info = null; _vsInfoKnownError = true; return false; } -} +} \ No newline at end of file diff --git a/src/generators/Silk.NET.SilkTouch.Scraper/XmlVisitor.cs b/src/generators/Silk.NET.SilkTouch.Scraper/XmlVisitor.cs index 98d292e2c3..4416b6d5de 100644 --- a/src/generators/Silk.NET.SilkTouch.Scraper/XmlVisitor.cs +++ b/src/generators/Silk.NET.SilkTouch.Scraper/XmlVisitor.cs @@ -10,7 +10,6 @@ using System.Xml; using Microsoft.Extensions.Logging; using Silk.NET.SilkTouch.Symbols; -using Parameter=Silk.NET.SilkTouch.Symbols.Parameter; using TypeReference=Silk.NET.SilkTouch.Symbols.TypeReference; namespace Silk.NET.SilkTouch.Scraper; @@ -18,16 +17,12 @@ namespace Silk.NET.SilkTouch.Scraper; internal sealed class XmlVisitor { private readonly ILogger _logger; - private readonly TypeStore _typeStore; - public XmlVisitor(ILogger logger, TypeStore typeStore) - { + public XmlVisitor(ILogger logger) { _logger = logger; - _typeStore = typeStore; } public IEnumerable Visit(XmlNode node) { - _logger.LogTrace("Visiting XML Node of kind {name} {inner}", node.Name, node.InnerXml); switch (node) { case XmlElement { Name: "bindings" } bindings: @@ -38,91 +33,13 @@ public IEnumerable Visit(XmlNode node) return VisitStruct(@struct); case XmlElement { Name: "field" } field: return VisitField(field); - case XmlElement { Name: "class" } @class: - return VisitClass(@class); - case XmlElement { Name: "function" } function: - return VisitFunction(function); default: { - _logger.LogWarning("Skipping unknown XML Node of kind {name}", node.Name); - #if DEBUG throw new NotImplementedException(); - #else - return Array.Empty(); - #endif } } } - private IEnumerable VisitClass(XmlElement @class) - { - var name = @class.Attributes["name"]?.Value; - if (name is null) - throw new InvalidOperationException("Class name cannot be null"); - - var members = @class.ChildNodes.Cast() - .SelectMany - ( - x => - { - var results = Visit(x).ToArray(); - if (results.Any(x => x is not MethodSymbol)) - throw new NotImplementedException("Class only supports method members for now"); - return results.OfType(); - } - ); - return new[] - { - new ClassSymbol(TypeId.CreateNew(), new IdentifierSymbol(name), members.ToImmutableArray()) - }; - } - - private IEnumerable VisitFunction(XmlElement function) - { - var name = function.Attributes["name"]?.Value; - if (name is null) - throw new InvalidOperationException("Function name cannot be null"); - - var returnTypeNode = function.ChildNodes.Cast().OfType().FirstOrDefault(x => x.Name == "type"); - if (returnTypeNode is null) - throw new InvalidOperationException("Could not find return type of function"); - - var returnType = VisitType(returnTypeNode).Single(); - if (returnType is not TypeReference rt) - throw new InvalidOperationException("VisitType needs to return single type reference"); - - var parameters = function.ChildNodes.Cast() - .OfType() - .Where(x => x.Name == "param") - .Select - ( - x => - { - var paramName = x.Attributes["name"]?.Value; - if (paramName is null) - throw new InvalidOperationException("Function parameter name cannot be null"); - - var paramTypeNode = x.ChildNodes.Cast() - .OfType() - .SingleOrDefault(x => x.Name == "type"); - if (paramTypeNode is null) - throw new InvalidOperationException("Parameter type cannot be null"); - - var paramType = VisitType(paramTypeNode).Single(); - if (paramType is not TypeReference pt) - throw new InvalidOperationException("VisitType needs to return single type reference"); - - return new Parameter(pt, new IdentifierSymbol(paramName)); - } - ) - .ToImmutableArray(); - - return new[] - { - new StaticExternalMethodSymbol(rt, parameters, new IdentifierSymbol(name)) - }; - } - private IEnumerable VisitField(XmlElement field) { var name = field.Attributes["name"]?.Value; @@ -174,6 +91,25 @@ private IEnumerable VisitField(XmlElement field) new FieldSymbol(finalType, new IdentifierSymbol(name)) }; } + + // TODO: Configurable Type maps + private static readonly Dictionary _typeMap = new() + { + ["int"] = new ExternalTypeReference(null, new IdentifierSymbol("int")) + }; + + private bool TryResolveTypeRef(string text, [NotNullWhen(true)] out TypeReference? reference) + { + if (_typeMap.TryGetValue(text, out reference)) + { + return true; + } + else + { + _logger.LogDebug("Failed to resolve type reference from \"{text}\"", text); + return false; + } + } // NOTE: This does not visit types as in class/struct, but visits *references* to types. Like from methods or fields. private IEnumerable VisitType(XmlElement type) @@ -198,17 +134,13 @@ private IEnumerable VisitStruct(XmlElement @struct) } } } - + return new[] { - StoreType + new StructSymbol ( - new StructSymbol - ( - TypeId.CreateNew(), - new IdentifierSymbol(@struct.Attributes?["name"]?.Value ?? throw new InvalidOperationException()), - fields.ToImmutableArray() - ) + new IdentifierSymbol(@struct.Attributes?["name"]?.Value ?? throw new InvalidOperationException()), + fields.ToImmutableArray() ) }; } @@ -239,10 +171,4 @@ private IEnumerable VisitNamespace(XmlElement @namespace) ) }; } - - private T StoreType(T instance) where T : TypeSymbol - { - _typeStore.Store(instance); - return instance; - } } diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/ClassSymbol.cs b/src/generators/Silk.NET.SilkTouch.Symbols/ClassSymbol.cs deleted file mode 100644 index f85764c36b..0000000000 --- a/src/generators/Silk.NET.SilkTouch.Symbols/ClassSymbol.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; - -namespace Silk.NET.SilkTouch.Symbols; - -/// -/// A representing a class -/// -public sealed record ClassSymbol(TypeId Id, IdentifierSymbol Identifier, ImmutableArray Methods) - : TypeSymbol(Id, Identifier); diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/FunctionPointerTypeReference.cs b/src/generators/Silk.NET.SilkTouch.Symbols/FunctionPointerTypeReference.cs deleted file mode 100644 index ca9a9a38cb..0000000000 --- a/src/generators/Silk.NET.SilkTouch.Symbols/FunctionPointerTypeReference.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; - -namespace Silk.NET.SilkTouch.Symbols; - -/// -/// A representing a function pointer. -/// -public sealed record FunctionPointerTypeReference(TypeReference ReturnType, ImmutableArray ParameterTypes) : TypeReference -{ -} diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/InternalTypeReference.cs b/src/generators/Silk.NET.SilkTouch.Symbols/InternalTypeReference.cs index a840603e11..0e29c327db 100644 --- a/src/generators/Silk.NET.SilkTouch.Symbols/InternalTypeReference.cs +++ b/src/generators/Silk.NET.SilkTouch.Symbols/InternalTypeReference.cs @@ -6,7 +6,7 @@ namespace Silk.NET.SilkTouch.Symbols; /// /// Represents a reference to a type that is also defined as part of this symbol tree. /// -/// The of the referenced. -public sealed record InternalTypeReference(TypeId ReferencedTypeId) : TypeReference() +/// The Type referenced +public sealed record InternalTypeReference(TypeSymbol Referenced) : TypeReference() { } diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/MethodSymbol.cs b/src/generators/Silk.NET.SilkTouch.Symbols/MethodSymbol.cs deleted file mode 100644 index f17a87cbf5..0000000000 --- a/src/generators/Silk.NET.SilkTouch.Symbols/MethodSymbol.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; - -namespace Silk.NET.SilkTouch.Symbols; - -/// -/// A representing a method with a signature. -/// -public abstract record MethodSymbol(TypeReference ReturnType, ImmutableArray Parameters, IdentifierSymbol Identifier) : MemberSymbol; - -/// -/// Represents a Parameter to a -/// -/// The type of this parameter -/// The identifier of this parameter -public sealed record Parameter(TypeReference TypeReference, IdentifierSymbol Identifier); diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/PointerTypeReference.cs b/src/generators/Silk.NET.SilkTouch.Symbols/PointerTypeReference.cs deleted file mode 100644 index 144927da2d..0000000000 --- a/src/generators/Silk.NET.SilkTouch.Symbols/PointerTypeReference.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Silk.NET.SilkTouch.Symbols; - -/// -/// A representing a pointer type -/// -/// A reference to the pointed to type -public sealed record PointerTypeReference(TypeReference Underlying) : TypeReference; diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/Silk.NET.SilkTouch.Symbols.csproj b/src/generators/Silk.NET.SilkTouch.Symbols/Silk.NET.SilkTouch.Symbols.csproj index 02fd2f7770..6cb3c8870a 100644 --- a/src/generators/Silk.NET.SilkTouch.Symbols/Silk.NET.SilkTouch.Symbols.csproj +++ b/src/generators/Silk.NET.SilkTouch.Symbols/Silk.NET.SilkTouch.Symbols.csproj @@ -8,6 +8,5 @@ - diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/StaticExternalMethodSymbol.cs b/src/generators/Silk.NET.SilkTouch.Symbols/StaticExternalMethodSymbol.cs deleted file mode 100644 index 5bb94bf726..0000000000 --- a/src/generators/Silk.NET.SilkTouch.Symbols/StaticExternalMethodSymbol.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; - -namespace Silk.NET.SilkTouch.Symbols; - -/// -/// A static external method symbol. -/// External meaning it must be loaded -/// -public sealed record StaticExternalMethodSymbol - (TypeReference ReturnType, ImmutableArray Parameters, IdentifierSymbol Identifier) - : MethodSymbol(ReturnType, Parameters, Identifier) -{ -} diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/StructSymbol.cs b/src/generators/Silk.NET.SilkTouch.Symbols/StructSymbol.cs index e8696a1e85..4970ebec41 100644 --- a/src/generators/Silk.NET.SilkTouch.Symbols/StructSymbol.cs +++ b/src/generators/Silk.NET.SilkTouch.Symbols/StructSymbol.cs @@ -8,7 +8,6 @@ namespace Silk.NET.SilkTouch.Symbols; /// /// A representing a struct. /// -/// An Identifier used for referencing types globally /// The Identifier of this struct /// The fields of this struct /// @@ -18,5 +17,4 @@ namespace Silk.NET.SilkTouch.Symbols; /// Structs are implicitly sequential in layout. There is no way to provide an offset at which to place a struct. /// For types that would require such behavior there are separate symbols that may be defined. /// -public sealed record StructSymbol - (TypeId Id, IdentifierSymbol Identifier, ImmutableArray Fields) : TypeSymbol(Id, Identifier); +public sealed record StructSymbol(IdentifierSymbol Identifier, ImmutableArray Fields) : TypeSymbol(Identifier); diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/SymbolVisitor.cs b/src/generators/Silk.NET.SilkTouch.Symbols/SymbolVisitor.cs index fab812e421..f76d499a56 100644 --- a/src/generators/Silk.NET.SilkTouch.Symbols/SymbolVisitor.cs +++ b/src/generators/Silk.NET.SilkTouch.Symbols/SymbolVisitor.cs @@ -10,20 +10,6 @@ namespace Silk.NET.SilkTouch.Symbols; /// public abstract class SymbolVisitor { - /// - /// The used by this - /// - protected TypeStore TypeStore { get; } - - /// - /// Creates a with it's dependencies. - /// - /// The to use - public SymbolVisitor(TypeStore typeStore) - { - TypeStore = typeStore; - } - /// /// Visit a . This will call the appropriate method based on the actual type of the /// @@ -50,7 +36,6 @@ public virtual Symbol Visit(Symbol symbol) protected virtual MemberSymbol VisitMember(MemberSymbol memberSymbol) { if (memberSymbol is FieldSymbol fs) return VisitField(fs); - if (memberSymbol is MethodSymbol ms) return VisitMethod(ms); return ThrowUnknownSymbol(memberSymbol); } @@ -61,55 +46,20 @@ protected virtual MemberSymbol VisitMember(MemberSymbol memberSymbol) /// The field symbol to visit /// The rewritten symbol /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. + /// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order. /// protected virtual FieldSymbol VisitField(FieldSymbol fieldSymbol) { return new FieldSymbol(VisitTypeReference(fieldSymbol.Type), VisitIdentifier(fieldSymbol.Identifier)); } - - /// - /// Visit a . Will call the appropriate methods to visit the different parts of the symbol. - /// - /// The method to visit - /// The rewritten symbol - /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. - /// - protected virtual MethodSymbol VisitMethod(MethodSymbol methodSymbol) - { - if (methodSymbol is StaticExternalMethodSymbol stms) return VisitStaticExternalMethod(stms); - return ThrowUnknownSymbol(methodSymbol); - } - - /// - /// Visit a . Will call the appropriate methods to visit the different parts of the symbol. - /// - /// The method to visit - /// The rewritten symbol - /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. - /// - protected virtual StaticExternalMethodSymbol VisitStaticExternalMethod - (StaticExternalMethodSymbol staticExternalMethodSymbol) - { - return new StaticExternalMethodSymbol - ( - VisitTypeReference(staticExternalMethodSymbol.ReturnType), - staticExternalMethodSymbol.Parameters.Select - (x => new Parameter(VisitTypeReference(x.TypeReference), VisitIdentifier(x.Identifier))) - .ToImmutableArray(), - VisitIdentifier(staticExternalMethodSymbol.Identifier) - ); - } - + /// /// Visit a . Will call the appropriate methods to visit the different parts of the symbol. /// /// The type reference to visit /// The rewritten symbol /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. + /// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order. /// /// /// By default visiting will throw. Visitors involved in type resolution should override this method directly. @@ -119,52 +69,20 @@ protected virtual TypeReference VisitTypeReference(TypeReference typeReference) if (typeReference is ExternalTypeReference etr) return VisitExternalTypeReference(etr); if (typeReference is InternalTypeReference itr) return VisitInternalTypeReference(itr); if (typeReference is UnresolvedTypeReference utr) UnresolvedTypeReference.ThrowInvalidSymbol(); - if (typeReference is PointerTypeReference ptr) return VisitPointerTypeReference(ptr); - if (typeReference is FunctionPointerTypeReference fptr) return VisitFunctionPointerTypeReference(fptr); return ThrowUnknownSymbol(typeReference); } - /// - /// Visit a . Will call the appropriate methods to visit the different parts of the symbol. - /// - /// The pointer type reference to visit - /// The rewritten symbol - /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. - /// - protected virtual PointerTypeReference VisitPointerTypeReference(PointerTypeReference pointerTypeReference) - { - return new PointerTypeReference(VisitTypeReference(pointerTypeReference.Underlying)); - } - /// - /// Visit a . Will call the appropriate methods to visit the different parts of the symbol. - /// - /// The function pointer type reference to visit - /// The rewritten symbol - /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. - /// - protected virtual FunctionPointerTypeReference VisitFunctionPointerTypeReference - (FunctionPointerTypeReference functionPointerTypeReference) - { - return new FunctionPointerTypeReference - ( - VisitTypeReference(functionPointerTypeReference.ReturnType), - functionPointerTypeReference.ParameterTypes.Select(VisitTypeReference).ToImmutableArray() - ); - } - /// /// Visit a . Will call the appropriate methods to visit the different parts of the symbol. /// /// The type reference to visit /// The rewritten symbol /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. + /// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order. /// protected virtual InternalTypeReference VisitInternalTypeReference(InternalTypeReference typeReference) { - return new InternalTypeReference(VisitTypeId(typeReference.ReferencedTypeId)); + return new InternalTypeReference(VisitType(typeReference.Referenced)); } /// @@ -173,7 +91,7 @@ protected virtual InternalTypeReference VisitInternalTypeReference(InternalTypeR /// The type reference to visit /// The rewritten symbol /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. + /// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order. /// protected virtual ExternalTypeReference VisitExternalTypeReference(ExternalTypeReference typeReference) { @@ -185,57 +103,18 @@ protected virtual ExternalTypeReference VisitExternalTypeReference(ExternalTypeR } /// - /// Called when a type is referenced by it's Id and should be visited. Implementers may resolve the Id if they to do so. - /// The default implementation does not resolve the Id or call any further into the tree. - /// - /// The Id of the type - /// The new Id that should be used to reference this type - protected virtual TypeId VisitTypeId(TypeId id) - { - return id; - } - - /// - /// Visit a . This will call the appropriate method based on the actual type of the . - /// This will update the with it's return value by default. Implementors overriding this should update the store themselves. + /// Visit a . This will call the appropriate method based on the actual type of the /// /// The type symbol to visit /// The rewritten symbol /// protected virtual TypeSymbol VisitType(TypeSymbol typeSymbol) { - TypeSymbol? result = null; - if (typeSymbol is StructSymbol @struct) result = VisitStruct(@struct); - else if (typeSymbol is ClassSymbol @class) result = VisitClass(@class); - - if (result is not null) - { - TypeStore.Store(result); - return result; - } + if (typeSymbol is StructSymbol @struct) return VisitStruct(@struct); return ThrowUnknownSymbol(typeSymbol); } - /// - /// Visit a . Will call the appropriate methods to visit the different parts of the class. - /// - /// The class symbol to visit - /// The rewritten symbol - /// - /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. - /// - protected virtual ClassSymbol VisitClass(ClassSymbol classSymbol) - { - return new ClassSymbol - ( - classSymbol.Id, - VisitIdentifier(classSymbol.Identifier), - classSymbol.Methods.Select(VisitMethod).ToImmutableArray() - ); - } - /// /// Visit a . Will call the appropriate methods to visit the different parts of the struct. /// @@ -243,13 +122,12 @@ protected virtual ClassSymbol VisitClass(ClassSymbol classSymbol) /// The rewritten symbol /// /// - /// The order in which the parts are visited is kept as an implementation detail. Do not rely on this order. + /// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order. /// protected virtual StructSymbol VisitStruct(StructSymbol structSymbol) { return new StructSymbol ( - structSymbol.Id, VisitIdentifier(structSymbol.Identifier), structSymbol.Fields.Select(VisitField).ToImmutableArray() ); diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/TypeId.cs b/src/generators/Silk.NET.SilkTouch.Symbols/TypeId.cs deleted file mode 100644 index b7e9b960c2..0000000000 --- a/src/generators/Silk.NET.SilkTouch.Symbols/TypeId.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Silk.NET.SilkTouch.Symbols; - -/// -/// The Id of a -/// -[JsonConverter(typeof(TypeId.JsonConverter))] -public readonly struct TypeId : IEquatable -{ - private readonly Guid _guid; - private TypeId(Guid guid) - { - _guid = guid; - } - - /// - /// Creates a new, unique, instance - /// - /// The new instance - public static TypeId CreateNew() => new TypeId(Guid.NewGuid()); - - /// - public bool Equals(TypeId other) => _guid.Equals(other._guid); - - /// - public override bool Equals(object? obj) => obj is TypeId other && Equals(other); - - /// - public override int GetHashCode() => _guid.GetHashCode(); - - /// - public static bool operator ==(TypeId left, TypeId right) => left.Equals(right); - - /// - public static bool operator !=(TypeId left, TypeId right) => !left.Equals(right); - - /// - public override string ToString() - { - return _guid.ToString(); - } - - private sealed class JsonConverter : JsonConverter - { - public override TypeId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (!reader.TryGetGuid(out var guid)) - throw new InvalidOperationException("Could not parse TypeId"); - - return new TypeId(guid); - } - public override void Write(Utf8JsonWriter writer, TypeId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value._guid); - } - } -} diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/TypeStore.cs b/src/generators/Silk.NET.SilkTouch.Symbols/TypeStore.cs deleted file mode 100644 index 19f5ef000f..0000000000 --- a/src/generators/Silk.NET.SilkTouch.Symbols/TypeStore.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Concurrent; - -namespace Silk.NET.SilkTouch.Symbols; - -/// -/// A simple type store to store and reference s by Id -/// -public sealed class TypeStore -{ - private ConcurrentDictionary _dictionary = new(); - - /// - /// Stores the given for later resolution - /// - /// The to store - public void Store(TypeSymbol typeSymbol) - { - _dictionary[typeSymbol.Id] = typeSymbol; - } - - /// - /// Resolves a by it's - /// - /// The Id to use for resolution - /// The found or null - /// Whether a type could be resolved - public bool TryResolve(TypeId id, out TypeSymbol? typeSymbol) - { - return _dictionary.TryGetValue(id, out typeSymbol); - } -} diff --git a/src/generators/Silk.NET.SilkTouch.Symbols/TypeSymbol.cs b/src/generators/Silk.NET.SilkTouch.Symbols/TypeSymbol.cs index b7ebccad81..519870808b 100644 --- a/src/generators/Silk.NET.SilkTouch.Symbols/TypeSymbol.cs +++ b/src/generators/Silk.NET.SilkTouch.Symbols/TypeSymbol.cs @@ -6,7 +6,6 @@ namespace Silk.NET.SilkTouch.Symbols; /// /// A generic representing a named type. /// -/// An Identifier used for referencing types globally /// The identifier of this type /// -public abstract record TypeSymbol(TypeId Id, IdentifierSymbol Identifier) : Symbol; +public abstract record TypeSymbol(IdentifierSymbol Identifier) : Symbol; diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/FunctionPointerTypeResolver.cs b/src/generators/Silk.NET.SilkTouch.TypeResolution/FunctionPointerTypeResolver.cs deleted file mode 100644 index 1a7f4ef33b..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/FunctionPointerTypeResolver.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.Diagnostics; -using System.Text.RegularExpressions; -using Microsoft.Extensions.Logging; -using Silk.NET.SilkTouch.Symbols; - -namespace Silk.NET.SilkTouch.TypeResolution; - -/// -/// A that resolves strings of standard C# form -/// -public class FunctionPointerTypeResolver : SimpleTypeResolverBase -{ - private readonly ILogger _logger; - - /// - public FunctionPointerTypeResolver(ILogger logger, TypeStore typeStore) : base(typeStore) - { - _logger = logger; - } - - /// - protected override bool TryResolve(UnresolvedTypeReference utr, out TypeReference? resolved) - { - int c = 0; - var text = utr.Text; - if (text.Length > "delegate*".Length && text[text.Length - 1] == '>' && text.Substring(c, "delegate*".Length) == "delegate*") - { - _logger.LogTrace("Attempting to resolve {text} to function pointer after passing preliminary tests", utr.Text); - c += "delegate*".Length; - if (text.Substring(c, " unmanaged".Length) == " unmanaged") - { - c += " unmanaged".Length; - if (text[c] == '[') - { - var endOffset = text.AsSpan(c).IndexOf(']'); - - var attributeText = text.Substring(c + 1, endOffset - 1); - _logger.LogDebug("{text} may be a function pointer and has unhandled attributes {attributes}", utr.Text, attributeText); - // TODO: parse out function attributes here - - c += endOffset + 1; - } - var types = new List(); - if (text[c] == '<') - { - c += 1; - while (true) - { - var typeTextEndIndex = text.AsSpan(c).IndexOf(','); - if (typeTextEndIndex != -1) - { - var typeText = text.Substring(c, typeTextEndIndex); - c += typeTextEndIndex + 1; - if (text[c] == ' ') c++; - types.Add(new UnresolvedTypeReference(typeText)); - } - else - { - var l = text.Length - c - 1; - if (l > 0) - { - var typeText = text.Substring(c, l); - types.Add(new UnresolvedTypeReference(typeText)); - } - break; - } - } - } - else - { - _logger.LogDebug("{text} may be a function pointer but generic params are somehow scrambled", utr.Text); - } - - - // at least a return type is required - if (types.Count > 0) - { - resolved = new FunctionPointerTypeReference - (types.Last(), types.Take(types.Count - 1).ToImmutableArray()); - _logger.LogTrace("{text} resolved to function pointer {ptr}", utr.Text, resolved); - return true; - } - } - else - { - _logger.LogDebug("Rejecting {text} as it may be a function pointer, but not unmanaged", utr.Text); - } - } - resolved = null; - return false; - } -} diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/NameResolverSymbolVisitor.cs b/src/generators/Silk.NET.SilkTouch.TypeResolution/NameResolverSymbolVisitor.cs deleted file mode 100644 index 253c707040..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/NameResolverSymbolVisitor.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Diagnostics; -using Microsoft.Extensions.Logging; -using Silk.NET.SilkTouch.Symbols; - -namespace Silk.NET.SilkTouch.TypeResolution; - -/// -/// A used to resolve s. Requires a typically created by -/// -/// -/// This is the "base" type resolver, it is intended to resolve unresolved type refs with a text of a.b.c.d.e where -/// a.b.c.d.e is somewhere in the parent tree. -/// For example, this will handle a tree such as: -/// Type Identifier='a' -/// -> Type Identifier='b' -/// -> Type Identifier='c' -/// -> Type Identifier='d' -/// -> Type Identifier='e' -/// -> Type Identifier='f' -/// Then 'f' references 'd' using 'a.c.d' or, as it itself is a child of 'c', it may also write 'c.d' or, as they are on the same level, just 'd'. -/// Multiple types with the same name in one tree are of course allowed, in such a case we simply use the closest one in the tree that matches. -/// Resolution is done by -/// - checking the current type scope downwards for a matching name (this only considers direct children) -/// - traversing the tree upwards and then checking the new scope downwards for a matching name. -/// -public sealed class NameResolverSymbolVisitor : SymbolVisitor -{ - private readonly ILogger _logger; - private readonly TypeResolutionScope _rootScope; - private TypeResolutionScope _currentScope; - private Stack _seenScopes = new(); - /// - /// Creates the using a scope used as root. - /// - /// A logger used for diagnostic purposes - /// The used as root - /// The used - public NameResolverSymbolVisitor(ILogger logger, TypeResolutionScope rootScope, TypeStore typeStore) : base(typeStore) - { - _logger = logger; - _rootScope = rootScope; - _currentScope = rootScope; - } - - /// - protected override TypeSymbol VisitType(TypeSymbol typeSymbol) - { - var startLength = _seenScopes.Count; - _seenScopes.Push(_currentScope); - _currentScope = _currentScope.ChildTypeScopes[typeSymbol.Id]; - var result = base.VisitType(typeSymbol); - _currentScope = _seenScopes.Pop(); - Debug.Assert(_seenScopes.Count == startLength); - return result; - } - - /// - protected override TypeReference VisitTypeReference(TypeReference typeReference) - { - if (typeReference is UnresolvedTypeReference unresolvedTypeReference) - { - _logger.LogTrace("Attempting to resolve \"{text}\" to an internal reference", unresolvedTypeReference.Text); - if (TryFindMatchingType(_currentScope, unresolvedTypeReference.Text, out var foundDirectChild)) - { - _logger.LogTrace("Resolved to direct child {type}", foundDirectChild); - return new InternalTypeReference(foundDirectChild!.Id); - } - - // note: iterating a stack is ordered, just like repeatedly calling .Pop(), but doesn't disturb contents. - foreach (var scope in _seenScopes) - { - if (TryFindMatchingType(scope, unresolvedTypeReference.Text, out var foundChild)) - { - _logger.LogTrace - ( - "Successfully resolved \"{text}\" to internal type {type}", - unresolvedTypeReference.Text, - foundChild - ); - return new InternalTypeReference(foundChild!.Id); - } - } - - return unresolvedTypeReference; - } - return base.VisitTypeReference(typeReference); - } - - private bool TryFindMatchingType(TypeResolutionScope rootScope, string text, out TypeSymbol? foundChild) - { - // this method "recursively" builds the candidate type names and see if anything matches. - Stack<(string, TypeResolutionScope)> todo = new Stack<(string, TypeResolutionScope)>(); - todo.Push(("", rootScope)); - - while (todo.Count > 0) - { - var (prefix, scope) = todo.Pop(); - - foreach (var v in scope.ChildTypeScopes) - { - var typeId = v.Key; - if (!TypeStore.TryResolve(typeId, out var type)) - { - _logger.LogWarning("Failed to resolve Type ID {id}", typeId); - continue; - } - Debug.Assert(type is not null); - - var fullName = prefix + type!.Identifier.Value; - if (fullName == text) - { - foundChild = type; - return true; - } - - var newPrefix = fullName + "."; - todo.Push((newPrefix, v.Value)); - } - } - - foundChild = null; - return false; - } -} diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/PointerTypeResolver.cs b/src/generators/Silk.NET.SilkTouch.TypeResolution/PointerTypeResolver.cs deleted file mode 100644 index 15750815f9..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/PointerTypeResolver.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; - -namespace Silk.NET.SilkTouch.TypeResolution; - -/// -/// Resolves s with Text like "a*", "a.b.c*" to a with the underlying set to an with text = "a", "a.b.c", etc. -/// -/// -/// -/// -/// Input Tree -/// Output Tree -/// -/// -/// -/// (Text = "a.b.c*") -/// (Underlying = (Text = "a.b.c")) -/// -/// -/// -/// (Text = "int*") -/// (Underlying = (Text = "int")) -/// -/// -/// -/// (Text = "a") -/// (Text = "a") -/// -/// -/// -public sealed class PointerTypeResolver : SimpleTypeResolverBase -{ - - /// - public PointerTypeResolver(TypeStore typeStore) : base(typeStore) - { - } - - /// - protected override bool TryResolve(UnresolvedTypeReference utr, out TypeReference? resolved) - { - if (utr.Text.Length > 1 && utr.Text[utr.Text.Length - 1] == '*') - { - resolved = new PointerTypeReference(new UnresolvedTypeReference(utr.Text.Substring(0, utr.Text.Length - 1))); - return true; - } - resolved = null; - return false; - } -} diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/PrimitiveTypeResolver.cs b/src/generators/Silk.NET.SilkTouch.TypeResolution/PrimitiveTypeResolver.cs deleted file mode 100644 index 82aabed778..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/PrimitiveTypeResolver.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; - -namespace Silk.NET.SilkTouch.TypeResolution; - -/// -/// A simple type resolver to resolve s that refer to primitive types. -/// -public sealed class PrimitiveTypeResolver : SimpleTypeResolverBase -{ - - /// - public PrimitiveTypeResolver(TypeStore typeStore) : base(typeStore) - { - } - - private static ExternalTypeReference CreateExternalTypeRef(string? @namespace, string name) - => new ExternalTypeReference(@namespace is not null ? new IdentifierSymbol(@namespace) : null, new IdentifierSymbol(name)); - private static readonly Dictionary _typeMap = new Dictionary() - { - ["bool"] = CreateExternalTypeRef("System", "Boolean"), - ["byte"] = CreateExternalTypeRef("System", "Byte"), - ["sbyte"] = CreateExternalTypeRef("System", "SByte"), - ["char"] = CreateExternalTypeRef("System", "Char"), - ["decimal"] = CreateExternalTypeRef("System", "Decimal"), - ["double"] = CreateExternalTypeRef("System", "Double"), - ["float"] = CreateExternalTypeRef("System", "Single"), - ["int"] = CreateExternalTypeRef("System", "Int32"), - ["uint"] = CreateExternalTypeRef("System", "UInt32"), - ["nint"] = CreateExternalTypeRef("System", "IntPtr"), - ["nuint"] = CreateExternalTypeRef("System", "UIntPtr"), - ["long"] = CreateExternalTypeRef("System", "Int64"), - ["ulong"] = CreateExternalTypeRef("System", "UInt64"), - ["short"] = CreateExternalTypeRef("System", "Int16"), - ["ushort"] = CreateExternalTypeRef("System", "UInt16"), - ["void"] = CreateExternalTypeRef(null, "void") - }; - - /// - protected override bool TryResolve(UnresolvedTypeReference utr, out TypeReference? resolved) - { - return _typeMap.TryGetValue(utr.Text, out resolved); - } -} diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/Silk.NET.SilkTouch.TypeResolution.csproj b/src/generators/Silk.NET.SilkTouch.TypeResolution/Silk.NET.SilkTouch.TypeResolution.csproj deleted file mode 100644 index 1082b82d57..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/Silk.NET.SilkTouch.TypeResolution.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - netstandard2.0 - enable - enable - - - - - - - - - diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/SimpleTypeResolverBase.cs b/src/generators/Silk.NET.SilkTouch.TypeResolution/SimpleTypeResolverBase.cs deleted file mode 100644 index 20a9cf3905..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/SimpleTypeResolverBase.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; - -namespace Silk.NET.SilkTouch.TypeResolution; - -/// -/// A base to simplify creation of basic type resolvers that only need simple text matching. -/// -public abstract class SimpleTypeResolverBase : SymbolVisitor -{ - /// - protected SimpleTypeResolverBase(TypeStore typeStore) : base(typeStore) - { - } - - /// - protected override TypeReference VisitTypeReference(TypeReference typeSymbol) - { - while (true) - { - if (typeSymbol is UnresolvedTypeReference utr) - { - if (TryResolve(utr, out var result)) - { - typeSymbol = result!; - continue; - } - return utr; - } - return base.VisitTypeReference(typeSymbol); - } - } - - /// - /// Resolve an - /// - /// THe unresolved reference to attempt to resolve - /// The resolved reference. May not be null if true is returned. - /// Whether resolution was successful - /// - /// This method is free to return a partial resolution, and still return true. - /// Partial resolutions are such that do not have a at the root, - /// but have somewhere in the tree. - /// - protected abstract bool TryResolve(UnresolvedTypeReference utr, out TypeReference? resolved); -} diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/TypeResolutionScope.cs b/src/generators/Silk.NET.SilkTouch.TypeResolution/TypeResolutionScope.cs deleted file mode 100644 index c128772356..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/TypeResolutionScope.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; - -namespace Silk.NET.SilkTouch.TypeResolution; - -/// -/// Used to track types and child scopes, used to resolve -/// -/// Mapping of child types to their scopes -public sealed record TypeResolutionScope(Dictionary ChildTypeScopes) -{ -} diff --git a/src/generators/Silk.NET.SilkTouch.TypeResolution/TypeScopeSymbolVisitor.cs b/src/generators/Silk.NET.SilkTouch.TypeResolution/TypeScopeSymbolVisitor.cs deleted file mode 100644 index e07d0e8454..0000000000 --- a/src/generators/Silk.NET.SilkTouch.TypeResolution/TypeScopeSymbolVisitor.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; - -namespace Silk.NET.SilkTouch.TypeResolution; - -/// -/// A used to build a -/// -public sealed class TypeScopeSymbolVisitor : SymbolVisitor -{ - /// - /// The root scope, containing all visited types - /// - public TypeResolutionScope RootScope { get; } - private TypeResolutionScope _currentScope; - private TypeSymbol? _currentParent; - - /// - /// Creates a - /// - /// The used - public TypeScopeSymbolVisitor(TypeStore typeStore) : base(typeStore) - { - RootScope = new(new()); - _currentScope = RootScope; - _currentParent = null; - } - - /// - protected override TypeSymbol VisitType(TypeSymbol typeSymbol) - { - var newScope = new TypeResolutionScope(new()); - var oldScope = _currentScope; - var oldParent = _currentParent; - _currentScope.ChildTypeScopes[typeSymbol.Id] = newScope; - _currentScope = newScope; - _currentParent = typeSymbol; - var result = base.VisitType(typeSymbol); - _currentScope = oldScope; - _currentParent = oldParent; - return result; - } - - /// - protected override TypeReference VisitTypeReference(TypeReference typeReference) - { - if (typeReference is UnresolvedTypeReference) - return typeReference; - - return base.VisitTypeReference(typeReference); - } -} diff --git a/src/generators/SilkTouch/ExitCodes.cs b/src/generators/SilkTouch/ExitCodes.cs new file mode 100644 index 0000000000..c4bfca7601 --- /dev/null +++ b/src/generators/SilkTouch/ExitCodes.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace SilkTouch +{ + internal enum ExitCodes + { + Ok, + SubagentBadArgs, + SubagentFailedToParse, + SubagentFailedToStart, + FailedToGetMSBuild + } +} diff --git a/src/generators/SilkTouch/LogMode.cs b/src/generators/SilkTouch/LogMode.cs new file mode 100644 index 0000000000..010ed44754 --- /dev/null +++ b/src/generators/SilkTouch/LogMode.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace SilkTouch +{ + /// + /// The level of logging to use during generation. + /// + public enum LogMode + { + /// + /// Standard logging. Contains info throughout the generation process and warnings produced. + /// + Standard, + + /// + /// Silent logging. Only logs if there's an error and suppresses the "logo". + /// + Silent, + + /// + /// Verbose logging. Contains trace logs including suppressed diagnostics. Spammier. + /// + Verbose, + + /// + /// Very verbose logging. Contains every log message ever possibly conceived. + /// Spammiest, far too spammy for most uses. + /// + VVerbose + } +} diff --git a/src/generators/SilkTouch/Program.cs b/src/generators/SilkTouch/Program.cs new file mode 100644 index 0000000000..b88784b399 --- /dev/null +++ b/src/generators/SilkTouch/Program.cs @@ -0,0 +1,7 @@ +namespace SilkTouch +{ + internal class Program + { + static void Main(string[] args) { } + } +} diff --git a/src/generators/Silk.NET.SilkTouch.DotnetTool/Silk.NET.SilkTouch.DotnetTool.csproj b/src/generators/SilkTouch/SilkTouch.csproj similarity index 66% rename from src/generators/Silk.NET.SilkTouch.DotnetTool/Silk.NET.SilkTouch.DotnetTool.csproj rename to src/generators/SilkTouch/SilkTouch.csproj index fa9581a595..59f591eb17 100644 --- a/src/generators/Silk.NET.SilkTouch.DotnetTool/Silk.NET.SilkTouch.DotnetTool.csproj +++ b/src/generators/SilkTouch/SilkTouch.csproj @@ -3,24 +3,24 @@ Exe net6.0 + true silktouch - DotnetTool - $(NETCoreSdkRuntimeIdentifier) + - + + + - - diff --git a/src/libraries/Silk.NET.Core/Version32.cs b/src/libraries/Silk.NET.Core/Version32.cs new file mode 100644 index 0000000000..511759222e --- /dev/null +++ b/src/libraries/Silk.NET.Core/Version32.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +namespace Silk.NET.Core +{ + /// + /// A 32-bit version structure. + /// + public readonly struct Version32 + { + /// + /// The underlying Vulkan-compatible 32-bit version integer. + /// + public uint Value { get; } + + /// + /// Creates a Vulkan version structure from the given major, minor, and patch values. + /// + /// The major value. It is a 3-bit integer + /// The major value. It is a 7-bit integer + /// The minor value. It is a 10-bit integer + /// The patch value. It is a 12-bit integer + /// major, minor, or patch were out of the range of valid values + public Version32(uint variant, uint major, uint minor, uint patch) + { + /*The variant is a 3-bit integer packed into bits 31-29. -Donovan/Redhacker1, Why is this not used? + + The major version is a 7-bit integer packed into bits 28-22. 2^7 = 128 + + The minor version number is a 10-bit integer packed into bits 21-12. 2^10 = 1024 + + The patch version number is a 12-bit integer packed into bits 11-0. 2^12 = 4096 + */ + // Sanity check to ensure that the values are correct + if ( (variant & uint.MaxValue - 7) != 0 || (major & uint.MaxValue - 127) != 0 || (minor & uint.MaxValue - 1023) != 0 || (patch & uint.MaxValue - 4095) != 0) + { + throw new ArgumentOutOfRangeException("variant, major, minor and/or patch were out of range, "); + } + + + Value = (variant & 7) << 29 | (major & 127) << 22 | (minor & 1023) << 12 | (patch & 4095); + } + + /// + /// Creates a Vulkan version structure from the given Vulkan-compatible value. + /// + /// The value. + private Version32(uint value) => Value = value; + + /// + /// Gets the variant component of this version structure. + /// + public uint Variant => Value >> 29; + /// + /// Gets the major component of this version structure. + /// + public uint Major => Value >> 22; + /// + /// Gets the minor component of this version structure. + /// + public uint Minor => (Value >> 12) & 0x3ff; + /// + /// Gets the patch component of this version structure. + /// + public uint Patch => Value & 0xfff; + /// + /// Creates a 32-bit version structure from the given 32-bit unsigned integer. + /// + /// The uint value. + /// The 32-bit version structure. + public static explicit operator Version32(uint val) => new Version32(val); + + /// + /// Creates a 32-bit version structure from the given managed version class. + /// + /// The version instance. + /// The 32-bit version structure. + public static implicit operator Version32 + (Version version) => new Version32(0, (uint) version.Major, (uint) version.Minor, (uint) version.Build); + + /// + /// Gets the 32-bit unsigned integer representation for this 32-bit version structure. + /// + /// The 32-bit version structure. + /// The 32-bit unsigned integer. + public static implicit operator uint(Version32 version) => version.Value; + + /// + /// Converts this 32-bit version structure to a managed version class. + /// + /// The 32-bit version structure. + /// The managed representation. + public static implicit operator Version + (Version32 version) => new Version((int) version.Major, (int) version.Minor, (int) version.Patch); + } +} diff --git a/src/libraries/Silk.NET.Maths/Silk.NET.Maths.csproj b/src/libraries/Silk.NET.Maths/Silk.NET.Maths.csproj index d121e59ce5..c6ee69d908 100644 --- a/src/libraries/Silk.NET.Maths/Silk.NET.Maths.csproj +++ b/src/libraries/Silk.NET.Maths/Silk.NET.Maths.csproj @@ -7,12 +7,6 @@ true true 9.0 - - - $(DefineConstants);SSE - $(DefineConstants);BTEC_INTRINSICS;MATHF - $(DefineConstants);POH;AdvSIMD - true true diff --git a/src/libraries/Silk.Net.Windowing/Abstract/ContextFlags.cs b/src/libraries/Silk.Net.Windowing/Abstract/ContextFlags.cs new file mode 100644 index 0000000000..8440f28660 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/ContextFlags.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + +namespace Silk.NET.Windowing +{ + /// + /// Represents flags related to the OpenGL context. + /// + [Flags] + public enum ContextFlags + { + /// + /// No flags enabled. + /// + Default = 0, + + /// + /// Enables debug context; debug contexts provide more debugging info, but can run slower. + /// + Debug = 1, + + /// + /// Enables forward compatability; this context won't support anything marked as deprecated in the current + /// version. + /// + /// On OpenGL contexts older than 3.0, this flag does nothing. + ForwardCompatible = 2 + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/ContextProfile.cs b/src/libraries/Silk.Net.Windowing/Abstract/ContextProfile.cs new file mode 100644 index 0000000000..843792235e --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/ContextProfile.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// Represents the context profile OpenGL should use. + /// + public enum ContextProfile + { + /// + /// Uses a core OpenGL context, which removes some deprecated functionality. + /// + Core = 0, + + /// + /// Uses a compatability OpenGL context, allowing for some deprecated functionality. This should only ever be + /// used for maintaining legacy code; no newly-written software should use this. + /// + Compatability + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/Delegates.cs b/src/libraries/Silk.Net.Windowing/Abstract/Delegates.cs new file mode 100644 index 0000000000..967ccdaac2 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/Delegates.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using Silk.NET.Maths; +using Silk.NET.Windowing; + +//TODO: Copy proposal explanation as to why we are doing this, also other than Vector2DAction these names are HIGHLY specialized for no apparently good reason, I am not a fan. +/// +/// An action that takes a +/// +public delegate void Vector2DAction(Vector2D newValue); + +/// +/// An action that takes a double as a parameter +/// +public delegate void DeltaAction(double deltaTime); +/// +/// An action that takes a +/// +public delegate void WindowStateAction(WindowState newState); +/// +/// An action that takes a list of strings as a parameter, intended for file path callbacks +/// +public delegate void FilePathsAction(string[] filePaths); +/// +/// An action that takes a bool as a parameter, intended for a callback when things are toggled. +/// +public delegate void ToggleAction(bool newValue); diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IDesktopSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IDesktopSurface.cs new file mode 100644 index 0000000000..50daddd1f6 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IDesktopSurface.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; +using Silk.NET.Core; +using Silk.NET.Maths; + +namespace Silk.NET.Windowing +{ + /// + /// A surface which wraps a Desktop Window. + /// + public interface IDesktopSurface : ISurface + { + /// + /// Whether or not the window is visible. + /// + bool IsVisible { get; set; } + + /// + /// The position of the window. If set to -1, use the backend default. + /// + Vector2D Position { get; set; } + + /// + /// The size of the window in pixels. + /// + new Vector2D Size { get; set; } + + /// + /// The window title. + /// + string Title { get; set; } + + /// + /// The window state. + /// + WindowState WindowState { get; set; } + + /// + /// The window border. + /// + WindowBorder WindowBorder { get; set; } + + /// + /// The video mode. + /// + VideoMode VideoMode { get; set; } + + /// + /// Gets the screen on which this window is active. + /// + IScreen? CurrentScreen { get; set; } + + /// + /// Gets the available screens for this surface. + /// + IEnumerable? AvailableScreens { get; } + + /// + /// Gets or sets whether the window waits for an event to be posted before existing . + /// + bool IsEventDriven { get; set; } + + /// + /// Gets or sets whether the window has been requested to close. + /// + bool IsCloseRequested { get; set; } + + /// + /// Gets whether the window is focused or not. + /// + bool IsFocused { get; } + + /// + /// Gets the distances in screen coordinates from the edges of the content area to the corresponding edges of + /// the full window. + /// + /// + /// Because these are distances and not coordinates, they are always zero or positive. + /// + /// + Rectangle BorderSize { get; } + + /// + /// Raised when the window has been requested to close. + /// + event Action CloseRequested; + + /// + /// Raised when the window is moved. + /// + event Vector2DAction? Move; + + /// + /// Raised when the window state is changed. + /// + event WindowStateAction? StateChanged; + + /// + /// Raised when the user drops files onto the window. + /// + event FilePathsAction? FileDrop; + + /// + /// Raised when the window focus changes. + /// + event ToggleAction? FocusChanged; + + /// + /// Sets the window icons. + /// + /// Either a collection of window icons, or null to set to the default icon. + void SetWindowIcon(ReadOnlySpan icons); + + /// + /// When using = true, wakes the main thread from + /// its blocking wait on incoming events. Can be called from any thread. + /// + void ContinueEvents(); + + /// + /// Converts this point to client coordinates. + /// + /// The point to transform. + /// The transformed point. + /// Expects screen coordinates as input. + Vector2D PointToClient(Vector2D point); + + /// + /// Converts this point to screen coordinates. + /// + /// The point to transform. + /// The transformed point. + /// Expects client coordinates as input. + Vector2D PointToScreen(Vector2D point); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IGLDesktopSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IGLDesktopSurface.cs new file mode 100644 index 0000000000..f024ed15a9 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IGLDesktopSurface.cs @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// An interface that defines a desktop surface with the ability to create a desktop GL Context + /// + public interface IGLDesktopSurface : IDesktopSurface, IGLSurface { } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IGLSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IGLSurface.cs new file mode 100644 index 0000000000..07e9d75b1a --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IGLSurface.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// A surface that can have a desktop GL context. + /// + public interface IGLSurface : INativeGLSurface + { + /// + /// The flags the context was created with + /// + ContextFlags ContextFlags { get; set; } + /// + /// The profile of the specified context. + /// + ContextProfile ContextProfile { get; set; } + /// + /// The surface representing the context to use. + /// + IGLSurface? SharedContext { get; set; } // Redhacker1/Donovan: DAFUQ? What exactly is supposed to be going on here + + /// + /// Enables OpenGL support for this surface. This will create a surface upon initialization. + /// + bool TryEnableOpenGL(); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IGLTransparentFramebufferSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IGLTransparentFramebufferSurface.cs new file mode 100644 index 0000000000..90157a7d37 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IGLTransparentFramebufferSurface.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// Represents a GL Surface with a transparent Framebuffer + /// + // Is GLFW making this an optional feature worth adding this? -Donovan/Redhacker1 + public interface IGLTransparentFramebuffer : INativeGLSurface + { + /// + /// Whether the buffer can be actually transparent + /// + bool TransparentFramebuffer { get; set; } + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IGlesDesktopSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IGlesDesktopSurface.cs new file mode 100644 index 0000000000..76253f9e0f --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IGlesDesktopSurface.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// A Desktop Surface with the ability to create a GLES surface + /// + public interface IGlesDesktopSurface : IDesktopSurface, IGlesSurface + { + + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IGlesSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IGlesSurface.cs new file mode 100644 index 0000000000..73dcaa930e --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IGlesSurface.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// Defines a surface that can have a GLES context attatched + /// + public interface IGlesSurface : INativeGLSurface + { + /// + /// The surface representing the context to use. + /// + IGlesSurface? SharedContext { get; set; } // Donovan/Redhacker1: How on earth is this supposed to work? + /// + /// Enables OpenGLES support for this surface. This will create a surface upon initialization. + /// + bool TryEnableOpenGLES(); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/INativeGLSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/INativeGLSurface.cs new file mode 100644 index 0000000000..056545ab77 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/INativeGLSurface.cs @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using Silk.NET.Core; +using Silk.NET.Maths; + +namespace Silk.NET.Windowing +{ + public interface INativeGLSurface : ISurface + { + /// + /// the GL Handle + /// + nint Handle { get; } + /// + /// Whether this is the currently running context on this thread + /// + bool IsContextCurrent { get; set; } + /// + /// Should the buffers swap immediately upon completion? + /// + bool ShouldSwapAutomatically { get; set; } + + /// + /// Sets the number of vertical blanks to wait between calling and presenting the image, + /// a.k.a vertical synchronization (V-Sync). Set to 1 to enable V-Sync. + /// + /// + /// Due to platform restrictions, this value can only be set and not retrieved. + /// + int SwapInterval { set; } + + /// + /// Preferred depth buffer bits of the window's framebuffer. + /// + /// + /// Pass null or -1 to use the system default. + /// + int? PreferredDepthBufferBits { get; set; } + + /// + /// Preferred stencil buffer bits of the window's framebuffer. + /// + /// + /// Pass null or -1 to use the system default. + /// + int? PreferredStencilBufferBits { get; set; } + + /// + /// Preferred red, green, blue, and alpha bits of the window's framebuffer. + /// + /// + /// Pass null or -1 for any of the channels to use the system default. + /// + Vector4D? PreferredBitDepth { get; set; } + + /// + /// The API version to use. + /// + Version32? ApiVersion { get; set; } + + nint? GetProcAddress(string proc); + void SwapBuffers(); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IScreen.cs b/src/libraries/Silk.Net.Windowing/Abstract/IScreen.cs new file mode 100644 index 0000000000..c81da687df --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IScreen.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; +using Silk.NET.Maths; + +namespace Silk.NET.Windowing +{ + /// + /// An interface representing a screen + /// + public interface IScreen + { + /// + /// The name of this screen. + /// + string Name { get; } + + /// + /// The index of this screen. + /// + int Index { get; } + + /// + /// The workarea of this screen. + /// + Rectangle WorkArea { get; } + + /// + /// The current video mode of this monitor. + /// + VideoMode VideoMode { get; } + + /// + /// This screen's gamma correction. + /// + float Gamma { get; set; } + + /// + /// Get all video modes that this screen supports. + /// + /// An array of all video modes. + IEnumerable GetAllVideoModes(); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/ISurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/ISurface.cs new file mode 100644 index 0000000000..cf35541fef --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/ISurface.cs @@ -0,0 +1,144 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using Silk.NET.Core; +using Silk.NET.Maths; + +namespace Silk.NET.Windowing +{ + /// + /// Represents a surface with a framebuffer on which to draw on. + /// + public interface ISurface : IWindowHandlesSource, IDisposable + { + /// + /// Determines whether the surface is being destroyed by the platform. + /// + bool IsTerminating { get; } + + /// + /// Determines whether the surface is being paused by the platform. + /// + bool IsPausing { get; } + + /// + /// Elapsed time in seconds since the Run method last started. + /// + double Time { get; } + + /// + /// The size of the surface's inner framebuffer. May differ from the surface size. + /// + // NB: This is not OpenGL specific and is valid in any case where there's a high DPI monitor. + Vector2D FramebufferSize { get; } + + /// + /// The size of the surface. + /// + Vector2D Size { get; } + + /// + /// The number of rendering operations to run every second. + /// + double FramesPerSecond { get; set; } + + /// + /// The number of update operations to run every second. + /// + double UpdatesPerSecond { get; set; } + + /// + /// Raised when the surface is resized. + /// + event Vector2DAction? Resize; + + /// + /// Raised when the surface's framebuffer is resized. + /// + event Vector2DAction? FramebufferResize; + + /// + /// Raised when the surface is being terminated. + /// + event Action? Terminating; + + /// + /// Raised when the surface is running low on memory. + /// + event Action? LowMemory; + + /// + /// Raised when the surface is about to pause. This is a good indicator that the Run method is about to exit, though this may not necessarily be the case, but the surface isn't terminating yet. + /// + event Action? Pausing; + + /// + /// Raised when the surface is about to resume. This is a good indicator to expect the entry point to be called again, though this may not necessarily be the case. + /// + event Action? Resuming; + + /// + /// Raised when the surface is initialized for the first time. + /// + event Action? Created; + + /// + /// Raised just before the Update event is raised. + /// + event Action? PreUpdate; + + /// + /// Raised when an update should be run. + /// + event DeltaAction? Update; + + /// + /// Raised when a frame should be rendered. + /// + event DeltaAction? Render; + + /// + /// Creates the surface on the underlying platform. + /// + void Initialize(); + + /// + /// Calls the Render event. + /// + void DoRender(); + + /// + /// Calls the Update event. + /// + void DoUpdate(); + + /// + /// Polls the underlying platform for events. + /// + void DoEvents(); + + /// + /// Unloads the surface on the underlying platform. + /// + void Reset(); + + /// + /// Terminates this surface. + /// + void Terminate(); + + /// + /// Converts this point to framebuffer coordinates. + /// + /// The point to transform. + /// The transformed point. + /// Expects client coordinates as input. + Vector2D PointToFramebuffer(Vector2D point); + + /// + /// Initiates a render loop in which the given callback is called as fast as the underlying platform can manage. + /// + /// The callback to run each frame. + void Run(Action onFrame); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IVkDesktopSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IVkDesktopSurface.cs new file mode 100644 index 0000000000..1aeb549a91 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IVkDesktopSurface.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// Represents a surface with Vulkan support + /// + public interface IVkSurface : ISurface + { + /// Enables Vulkan support for this surface. + bool TryEnableVulkan(); + + /// + /// Create a Vulkan surface. + /// + /// The Vulkan instance to create a surface for. + /// A custom Vulkan allocator. Can be omitted by passing null. + /// A handle to the Vulkan surface created + unsafe ulong Create(nint instance, void* allocator); + + /// + /// Get the extensions required for Vulkan to work on this platform. + /// + /// The number of extensions in the returned array + /// An array of strings, containing names for all required extensions + unsafe byte** GetRequiredExtensions(out uint count); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IVkSurface.cs b/src/libraries/Silk.Net.Windowing/Abstract/IVkSurface.cs new file mode 100644 index 0000000000..be3056d659 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IVkSurface.cs @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// Represents a desktop surface with Vulkan support + /// + public interface IVkDesktopSurface : IDesktopSurface, IVkSurface { } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/IWindowHandlesSource.cs b/src/libraries/Silk.Net.Windowing/Abstract/IWindowHandlesSource.cs new file mode 100644 index 0000000000..3dab0d04e8 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/IWindowHandlesSource.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Core +{ + /// + /// Represents something that has access to a window handle + /// + public interface IWindowHandlesSource + { + /// + /// The native handles this window could possibly have, the .Net foundation reserves the right to append to this list as they see fit + /// + WindowHandles Native { get; } + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/RawImage.cs b/src/libraries/Silk.Net.Windowing/Abstract/RawImage.cs new file mode 100644 index 0000000000..9ae1a5b028 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/RawImage.cs @@ -0,0 +1,84 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + +namespace Silk.NET.Core +{ + /// + /// Represents loaded, uncompressed, processed image data. + /// + public readonly struct RawImage : IEquatable + { + /// + /// Creates a given pixel data and pixel dimensions. + /// + /// The width of the image. + /// The height of the image. + /// The image daqta. + public RawImage(int width, int height, ReadOnlyMemory rgbaPixels) + { + Pixels = rgbaPixels; + Width = width; + Height = height; + } + + /// + /// The width of the image in pixels + /// + public int Width { get; } + /// + /// The height of the image in pixels. + /// + public int Height { get; } + + /// + /// The image data. + /// + public ReadOnlyMemory Pixels { get; } + + /// + /// Checks whether the two given s are equal. + /// + /// The first raw image. + /// The second raw image to compare the first against. + /// True if they are equal, false otherwise. + /// + /// This does not check whether the byte arrays are equal, only whether their references are the same. + /// + public static bool operator ==(RawImage left, RawImage right) => left.Equals(right); + + /// + /// Checks whether the two given s are not equal. + /// + /// The first raw image. + /// The second raw image to compare the first against. + /// True if they are not equal, false otherwise. + /// + /// This does not check whether the byte arrays are equal, only whether their references are the same. + /// + public static bool operator !=(RawImage left, RawImage right) => !(left == right); + + /// + /// Checks whether the given is equal to this one. + /// + /// The raw image to compare this raw image against. + /// True if they are equal, false otherwise. + /// + /// This does not check whether the byte arrays have equal, only whether their references are the same. + /// + public bool Equals(RawImage other) + { + // Apparently it is not needed to compare height? IDK, kai said not to. + return Width == other.Width && Equals(Pixels, other.Pixels); + } + + /// + public override bool Equals(object? obj) + { + return obj is RawImage other && Equals(other); + } + + /// + public override int GetHashCode() => HashCode.Combine(Width, Height, Pixels); + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/Surface.cs b/src/libraries/Silk.Net.Windowing/Abstract/Surface.cs new file mode 100644 index 0000000000..1a9b7deb4e --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/Surface.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +namespace Silk.NET.Windowing +{ + /// + /// A factory that creates and/or gets surfaces. + /// + public static class Surface + { + /// + /// Whether the platform is supported by any backend of of Silk.Net.Windowing. + /// + /// + public static bool IsPlatformSupported { get => throw new NotImplementedException(); } + + /// + /// Gets a surface if a surface already exist, if it does then return said surface. + /// + /// an object. + // Does this return null on IsPlatformSupported is false? Does it throw? Should it return a bool indicating whether it returned an existing surface or created a new one? + public static ISurface GetOrCreate() + { + throw new NotImplementedException(); + } + /// + /// Creates an regardless as to whether one already exists + /// + /// an object. + // Does this return null on IsPlatformSupported is false? Does it throw? Should it return a bool indicating whether it returned an existing surface or created a new one? + public static ISurface CreateNew() + { + throw new NotImplementedException(); + } + + /// + /// Clears the contexts of ALL objects. + /// + public static void ClearCurrentContexts() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/SurfaceExtensions.cs b/src/libraries/Silk.Net.Windowing/Abstract/SurfaceExtensions.cs new file mode 100644 index 0000000000..56a1dc6887 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/SurfaceExtensions.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using Silk.NET.Core; +using Silk.NET.Maths; + +namespace Silk.NET.Windowing +{ + /// + /// Extensions for ISurface + /// + public static class SurfaceExtensions + { + /// + /// Start the default event loop on this surface. + /// + /// The surface to begin the loop on. + public static void Run(this ISurface surface) + { + throw new NotImplementedException(); + } + + /// + /// Gets the full size of the given window including its borders. + /// + /// The window to get size information from. + /// The full size of the window (including both content area and borders) + public static Vector2D GetFullSize(this IDesktopSurface window) + { + throw new NotImplementedException(); + } + + /// + /// Centers this window to the given monitor or, if null, the current monitor the window's on. + /// + /// The window to center. + /// The specific screen to center the window to, if any. + public static void Center(this IDesktopSurface window, IScreen? screen = null) + { + throw new NotImplementedException(); + } + + /// + /// Sets the window icon to default on the given window. + /// + /// The window. + public static void SetDefaultIcon(this IDesktopSurface window) + { + throw new NotImplementedException(); + } + + /// + /// Sets a single window icon on the given window. + /// + /// The window. + /// The icon to set. + public static void SetWindowIcon(this IDesktopSurface window, RawImage icon) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/VideoMode.cs b/src/libraries/Silk.Net.Windowing/Abstract/VideoMode.cs new file mode 100644 index 0000000000..7a3a18d24b --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/VideoMode.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using Silk.NET.Maths; + +namespace Silk.NET.Windowing +{ + /// + /// Represents a screens supported refresh rate and resolution + /// + public readonly struct VideoMode + { + /// + /// Creates a with a resolution and refreshRate parameter. + /// + /// The dimensions of the VideoMode in question + /// How many times per second the screen refreshes + public VideoMode(Vector2D? resolution = null, int? refreshRate = null) + { + throw new NotImplementedException(); + } + + /// + /// Creates a with a refreshRate parameter. + /// + /// How many times per second the screen refreshes + public VideoMode(int? refreshRate) + { + throw new NotImplementedException(); + } + + /// + /// Resolution of the full screen window. + /// + public Vector2D? Resolution { get; init; } + + /// + /// Refresh rate of the full screen window in Hz. + /// + public int? RefreshRate { get; init; } + + /// + /// The default video mode. This uses the window size for resolution and doesn't care about other values. + /// + public static VideoMode Default { get; } + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/WindowBorder.cs b/src/libraries/Silk.Net.Windowing/Abstract/WindowBorder.cs new file mode 100644 index 0000000000..d29db0e943 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/WindowBorder.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// Represents the window border. + /// + public enum WindowBorder + { + /// + /// The window can be resized by clicking and dragging its border. + /// + Resizable = 0, + + /// + /// The window border is visible, but cannot be resized. All window-resizings must happen solely in the code. + /// + Fixed, + + /// + /// The window border is hidden. + /// + Hidden + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/WindowHandles.cs b/src/libraries/Silk.Net.Windowing/Abstract/WindowHandles.cs new file mode 100644 index 0000000000..63d5c1839d --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/WindowHandles.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.InteropServices; + +namespace Silk.NET.Core +{ + /// + /// A struct of potential WindowHandles, represented by nullables + /// + [StructLayout(LayoutKind.Auto)] + public struct WindowHandles + { + /// Probably redundant? Not sure + public bool IsSupported { get; } + // ... + } +} diff --git a/src/libraries/Silk.Net.Windowing/Abstract/WindowState.cs b/src/libraries/Silk.Net.Windowing/Abstract/WindowState.cs new file mode 100644 index 0000000000..44894c1819 --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Abstract/WindowState.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +namespace Silk.NET.Windowing +{ + /// + /// Represents the current state of the window. + /// + public enum WindowState + { + /// + /// The window is in its regular configuration. + /// + Normal = 0, + + /// + /// The window has been minimized to the task bar. + /// + Minimized, + + /// + /// The window has been maximized, covering the entire desktop, but not the taskbar. + /// + Maximized, + + /// + /// The window has been fullscreened, covering the entire surface of the monitor. + /// + Fullscreen + } +} diff --git a/src/libraries/Silk.Net.Windowing/Implementations/GLFW/GLFWSurface.cs b/src/libraries/Silk.Net.Windowing/Implementations/GLFW/GLFWSurface.cs new file mode 100644 index 0000000000..cc8c0d875c --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Implementations/GLFW/GLFWSurface.cs @@ -0,0 +1,435 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; +using Silk.NET.Core; +using Silk.NET.Maths; + +namespace Silk.NET.Windowing.Implementations.GLFW +{ + /// + /// A Desktop surface backed by GLFW + /// + public class GLFWSurface : IGLTransparentFramebuffer, IGlesDesktopSurface, IVkDesktopSurface, IGLDesktopSurface + { + private IGlesSurface? _sharedContext; + private IGLSurface? _sharedContext1; + + + /// + /// + /// + public WindowHandles Native { get; } + + /// + /// + /// + public void Dispose() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public bool IsTerminating { get; } + + /// + /// + /// + public bool IsPausing { get; } + + /// + /// + /// + public double Time { get; } + + /// + /// + /// + public Vector2D FramebufferSize { get; } + + /// + /// + /// + public bool IsVisible { get; set; } + + /// + /// + /// + public Vector2D Position { get; set; } + + /// + /// + /// + public Vector2D Size { get; set; } + + /// + /// + /// + public string Title { get; set; } = null!; + + /// + /// + /// + public WindowState WindowState { get; set; } + + /// + /// + /// + public WindowBorder WindowBorder { get; set; } + + /// + /// + /// + public VideoMode VideoMode { get; set; } + + /// + /// + /// + public IScreen? CurrentScreen { get; set; } + + /// + /// + /// + public IEnumerable? AvailableScreens { get; } + + /// + /// + /// + public bool IsEventDriven { get; set; } + + /// + /// + /// + public bool IsCloseRequested { get; set; } + + /// + /// + /// + public bool IsFocused { get; } + + /// + /// + /// + public Rectangle BorderSize { get; } + + /// + /// + /// + public event Action? CloseRequested; + + /// + /// + /// + public event Vector2DAction? Move; + + /// + /// + /// + public event WindowStateAction? StateChanged; + + /// + /// + /// + public event FilePathsAction? FileDrop; + + /// + /// + /// + public event ToggleAction? FocusChanged; + + /// + /// + /// + public void SetWindowIcon(ReadOnlySpan icons) + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void ContinueEvents() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public Vector2D PointToClient(Vector2D point) + { + throw new NotImplementedException(); + } + + /// + /// + /// + public Vector2D PointToScreen(Vector2D point) + { + throw new NotImplementedException(); + } + + + /// + /// + /// + public double FramesPerSecond { get; set; } + + /// + /// + /// + public double UpdatesPerSecond { get; set; } + + /// + /// + /// + public event Vector2DAction? Resize; + + /// + /// + /// + public event Vector2DAction? FramebufferResize; + + /// + /// + /// + public event Action? Terminating; + + /// + /// + /// + public event Action? LowMemory; + + /// + /// + /// + public event Action? Pausing; + + /// + /// + /// + public event Action? Resuming; + + /// + /// + /// + public event Action? Created; + + /// + /// + /// + public event Action? PreUpdate; + + /// + /// + /// + public event DeltaAction? Update; + + /// + /// + /// + public event DeltaAction? Render; + + /// + /// + /// + public void Initialize() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void DoRender() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void DoUpdate() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void DoEvents() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void Reset() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void Terminate() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public Vector2D PointToFramebuffer(Vector2D point) + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void Run(Action onFrame) + { + throw new NotImplementedException(); + } + + /// + /// + /// + public nint Handle { get; } + + /// + /// + /// + public bool IsContextCurrent { get; set; } + + /// + /// + /// + public bool ShouldSwapAutomatically { get; set; } + + /// + /// + /// + public int SwapInterval { get; set; } + + /// + /// + /// + public int? PreferredDepthBufferBits { get; set; } + + /// + /// + /// + public int? PreferredStencilBufferBits { get; set; } + + /// + /// + /// + public Vector4D? PreferredBitDepth { get; set; } + + /// + /// + /// + public Version32? ApiVersion { get; set; } + + /// + /// + /// + public nint? GetProcAddress(string proc) + { + throw new NotImplementedException(); + } + + /// + /// + /// + public void SwapBuffers() + { + throw new NotImplementedException(); + } + + /// + /// + /// + public bool TransparentFramebuffer { get; set; } + + + /// + /// + /// + public ContextFlags ContextFlags { get; set; } + + + /// + /// + /// + public ContextProfile ContextProfile { get; set; } + + /// + /// + /// + IGLSurface? IGLSurface.SharedContext + { + get => _sharedContext1; + set => _sharedContext1 = value; + } + + /// + /// + /// + public bool TryEnableOpenGL() + { + throw new NotImplementedException(); + } + + + /// + /// + /// + IGlesSurface? IGlesSurface.SharedContext + { + get => _sharedContext; + set => _sharedContext = value; + } + + + /// + /// + /// + public bool TryEnableOpenGLES() + { + throw new NotImplementedException(); + } + + + /// + /// + /// + public bool TryEnableVulkan() + { + throw new NotImplementedException(); + } + + + /// + /// + /// + public unsafe ulong Create(nint instance, void* allocator) + { + throw new NotImplementedException(); + } + + + /// + /// + /// + public unsafe byte** GetRequiredExtensions(out uint count) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/libraries/Silk.Net.Windowing/Silk.Net.Windowing.csproj b/src/libraries/Silk.Net.Windowing/Silk.Net.Windowing.csproj new file mode 100644 index 0000000000..54b3e83c5c --- /dev/null +++ b/src/libraries/Silk.Net.Windowing/Silk.Net.Windowing.csproj @@ -0,0 +1,19 @@ + + + + $(SilkTargetFramework) + + enable + true + true + true + 9.0 + + true + + + + + + + diff --git a/tests/Silk.NET.Core.Tests/Program.cs b/tests/Silk.NET.Core.Tests/Program.cs new file mode 100644 index 0000000000..3f8d6e11d4 --- /dev/null +++ b/tests/Silk.NET.Core.Tests/Program.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using Xunit; +using Silk.NET.Core; + +namespace Silk.NET.Core.Tests +{ + public class Tests + { + //Gets an IEnumerable with Offsets of 0 + private static IEnumerable<(uint, uint, uint, uint)> Range => Sample(); + /// + /// Tests within the range of valid for > if any of them throw, fail the test + /// + [Theory, MemberData(nameof(Range))] + public void InRangeTest(uint variant, uint major, uint minor, uint patch) + { + try + { + new Version32(variant, major, minor, patch); + } + catch (ArgumentOutOfRangeException) + { + Assert.True(false, $"In range test failed with values: Variant: {variant} Major: {major}, Minor: {minor}, Patch: {patch}"); + } + } + + /// + /// An integer with numberOfBits turned on starting at the low-order bit. Ex: CalcNumBits(4) == 15 (2^4)-1 + /// + /// The number of bits to "light up" or turn on. + /// An integer with numberOfBits turned on + public static int CalcNumBits(int numberOfBits) + { + return ~(~0 << numberOfBits); + } + + + public static IEnumerable<(uint, uint, uint, uint)> Sample() + { + for (uint variant = 0; variant <= CalcNumBits(3); variant++) + for(uint major = 0; major <= CalcNumBits(7); major++) + for(uint minor = 0; minor <= CalcNumBits(10); minor++) + for (uint patch = 0; patch <= CalcNumBits(12); patch++) + { + yield return (variant,major,minor,patch); + } + + } + + + /// + /// Tests outside the range of valid for . If any of them throw, fail the test + /// + [Theory, MemberData(nameof(Range))] + public void OutsideRangeTest(uint variant, uint major, uint minor, uint patch) + { + try + { + new Version32(variant + (uint)CalcNumBits(3) + 1u, major + (uint)CalcNumBits(7) + 1u, minor+ (uint)CalcNumBits(10) + 1u, patch + (uint)CalcNumBits(12) + 1u); + } + catch (ArgumentOutOfRangeException) + { + return; + } + Assert.True(false , $"Out of range test failed with values: {major}, {minor}, {patch}"); + } + } +} diff --git a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/Silk.NET.SilkTouch.TypeResolution.Tests.csproj b/tests/Silk.NET.Core.Tests/Silk.NET.Core.Tests.csproj similarity index 59% rename from tests/Silk.NET.SilkTouch.TypeResolution.Tests/Silk.NET.SilkTouch.TypeResolution.Tests.csproj rename to tests/Silk.NET.Core.Tests/Silk.NET.Core.Tests.csproj index 2f2e681cdb..61811682bc 100644 --- a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/Silk.NET.SilkTouch.TypeResolution.Tests.csproj +++ b/tests/Silk.NET.Core.Tests/Silk.NET.Core.Tests.csproj @@ -1,25 +1,23 @@ - + net6.0 - enable - false + + true + + + + - runtime; build; native; contentfiles; analyzers; buildtransitive all + runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - diff --git a/tests/Silk.NET.Maths.Tests/Vector2Tests.cs b/tests/Silk.NET.Maths.Tests/Vector2Tests.cs index a3fe0665b8..c7e6d4086b 100644 --- a/tests/Silk.NET.Maths.Tests/Vector2Tests.cs +++ b/tests/Silk.NET.Maths.Tests/Vector2Tests.cs @@ -815,8 +815,8 @@ public void Vector2ConstructorTest2() public void Vector2ConstructorTest3() { Vector2D target = new Vector2D(float.NaN, float.MaxValue); - Assert.Equal(float.NaN, target.X); - Assert.Equal(float.MaxValue, target.Y); + Assert.Equal(target.X, float.NaN); + Assert.Equal(target.Y, float.MaxValue); } // A test for Vector2f (float) diff --git a/tests/Silk.NET.Maths.Tests/Vector3Tests.cs b/tests/Silk.NET.Maths.Tests/Vector3Tests.cs index dc5ca3f457..d6fce1e012 100644 --- a/tests/Silk.NET.Maths.Tests/Vector3Tests.cs +++ b/tests/Silk.NET.Maths.Tests/Vector3Tests.cs @@ -27,7 +27,7 @@ public void Vector3CopyToTest() Assert.Throws(() => v1.CopyTo(null, 0)); Assert.Throws(() => v1.CopyTo(a, -1)); Assert.Throws(() => v1.CopyTo(a, a.Length)); - Assert.Throws(() => v1.CopyTo(a, a.Length - 2)); + Assert.Throws(null, () => v1.CopyTo(a, a.Length - 2)); v1.CopyTo(a, 1); v1.CopyTo(b); diff --git a/tests/Silk.NET.Maths.Tests/Vector4Tests.cs b/tests/Silk.NET.Maths.Tests/Vector4Tests.cs index 219971926f..1bb373ae31 100644 --- a/tests/Silk.NET.Maths.Tests/Vector4Tests.cs +++ b/tests/Silk.NET.Maths.Tests/Vector4Tests.cs @@ -27,7 +27,7 @@ public void Vector4CopyToTest() Assert.Throws(() => v1.CopyTo(null, 0)); Assert.Throws(() => v1.CopyTo(a, -1)); Assert.Throws(() => v1.CopyTo(a, a.Length)); - Assert.Throws(() => v1.CopyTo(a, a.Length - 2)); + Assert.Throws(null, () => v1.CopyTo(a, a.Length - 2)); v1.CopyTo(a, 1); v1.CopyTo(b); diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/ClassSymbolTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/ClassSymbolTests.cs deleted file mode 100644 index c4916f263c..0000000000 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/ClassSymbolTests.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.Emitter.Tests; - -public sealed class ClassSymbolTests : EmitterTest -{ - [Fact, Trait("Category", "Symbols"), Trait("Target Language", "C#")] - public void StringTestNoMethods() - { - var symbol = new ClassSymbol(TypeId.CreateNew(), new IdentifierSymbol("C"), ImmutableArray.Empty); - - var result = Transform(symbol); - - Assert.Equal("public class C\n" + "{\n" + "}", result.ToFullString()); - } - - [Fact, Trait("Category", "Symbols"), Trait("Target Language", "C#")] - public void StringTestWithMethods() - { - var method = new StaticExternalMethodSymbol - ( - new ExternalTypeReference(null, new IdentifierSymbol("int")), - ImmutableArray.Empty, - new IdentifierSymbol("M") - ); - var symbol = new ClassSymbol - ( - TypeId.CreateNew(), - new IdentifierSymbol("C"), - new MethodSymbol[] - { - method - }.ToImmutableArray() - ); - - - - var result = Transform(symbol); - - Assert.Equal("public class C\n" + "{" + "\n public static extern int M();" + "\n}", result.ToFullString()); - } -} diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterNamespaceMemberTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterNamespaceMemberTests.cs index 329ff72cfc..6a76b8ba93 100644 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterNamespaceMemberTests.cs +++ b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterNamespaceMemberTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Syntax; using Silk.NET.SilkTouch.Symbols; @@ -17,18 +16,10 @@ public class EmitterNamespaceMemberTests : EmitterTest Trait("Target Language", "C#")] public void SingleMemberIntegration() { - var syntax = Transform - ( - new NamespaceSymbol - ( - new IdentifierSymbol("Test"), - new[] - { - (TypeSymbol) new StructSymbol - (TypeId.CreateNew(), new IdentifierSymbol("Test2"), ImmutableArray.Empty) - }.ToImmutableArray() - ) - ); + var syntax = Transform(new NamespaceSymbol(new IdentifierSymbol("Test"), new [] + { + (TypeSymbol)new StructSymbol(new IdentifierSymbol("Test2"), ImmutableArray.Empty) + }.ToImmutableArray())); var result = syntax.ToFullString(); Assert.Equal(@"namespace Test @@ -45,20 +36,11 @@ public struct Test2 Trait("Target Language", "C#")] public void MultipleMembersIntegration() { - var syntax = Transform - ( - new NamespaceSymbol - ( - new IdentifierSymbol("Test"), - new[] - { - (TypeSymbol) new StructSymbol - (TypeId.CreateNew(), new IdentifierSymbol("Test2"), ImmutableArray.Empty), - (TypeSymbol) new StructSymbol - (TypeId.CreateNew(), new IdentifierSymbol("Test3"), ImmutableArray.Empty) - }.ToImmutableArray() - ) - ); + var syntax = Transform(new NamespaceSymbol(new IdentifierSymbol("Test"), new [] + { + (TypeSymbol)new StructSymbol(new IdentifierSymbol("Test2"), ImmutableArray.Empty), + (TypeSymbol)new StructSymbol(new IdentifierSymbol("Test3"), ImmutableArray.Empty) + }.ToImmutableArray())); var result = syntax.ToFullString(); Assert.Equal(@"namespace Test diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructMemberFieldsTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructMemberFieldsTests.cs index 1a45f62c00..6f4cb11fa4 100644 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructMemberFieldsTests.cs +++ b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructMemberFieldsTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Immutable; using Silk.NET.SilkTouch.Symbols; using Xunit; @@ -22,7 +21,6 @@ public void SingleFieldIntegration() ( new StructSymbol ( - TypeId.CreateNew(), new IdentifierSymbol("Test"), new[] { new FieldSymbol @@ -54,7 +52,6 @@ public void MultipleFieldsIntegration() ( new StructSymbol ( - TypeId.CreateNew(), new IdentifierSymbol("Test"), new[] { new FieldSymbol diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructTests.cs index b8508828d3..d2c91ee891 100644 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructTests.cs +++ b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Syntax; using Silk.NET.SilkTouch.Symbols; @@ -18,7 +17,7 @@ public sealed class EmitterStructTests : EmitterTest Trait("Target Language", "C#")] public void StructSyntax() { - var syntax = Transform(new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("Test"), ImmutableArray.Empty)); + var syntax = Transform(new StructSymbol(new IdentifierSymbol("Test"), ImmutableArray.Empty)); Assert.IsType(syntax); } @@ -28,7 +27,7 @@ public void StructSyntax() Trait("Target Language", "C#")] public void StructKeyword() { - var syntax = Transform(new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("Test"), ImmutableArray.Empty)) as StructDeclarationSyntax; + var syntax = Transform(new StructSymbol(new IdentifierSymbol("Test"), ImmutableArray.Empty)) as StructDeclarationSyntax; Assert.Equal("struct", syntax!.Keyword.Text); } @@ -38,7 +37,7 @@ public void StructKeyword() Trait("Target Language", "C#")] public void CorrectIdentifier() { - var syntax = Transform(new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("Test"), ImmutableArray.Empty)) as StructDeclarationSyntax; + var syntax = Transform(new StructSymbol(new IdentifierSymbol("Test"), ImmutableArray.Empty)) as StructDeclarationSyntax; Assert.Equal("Test", syntax!.Identifier.Text); } @@ -48,7 +47,7 @@ public void CorrectIdentifier() Trait("Target Language", "C#")] public void IsOnlyPublic() { - var syntax = Transform(new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("Test"), ImmutableArray.Empty)) as StructDeclarationSyntax; + var syntax = Transform(new StructSymbol(new IdentifierSymbol("Test"), ImmutableArray.Empty)) as StructDeclarationSyntax; var @public = Assert.Single(syntax!.Modifiers); Assert.Equal("public", @public.Text); } @@ -62,6 +61,6 @@ public void IntegrationEmptyStruct() // Note that this test also covers trivia, which is not checked otherwise. Assert.Equal(@"public struct Test { -}", Transform(new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("Test"), ImmutableArray.Empty)).ToFullString()); +}", Transform(new StructSymbol(new IdentifierSymbol("Test"), ImmutableArray.Empty)).ToFullString()); } } diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterTest.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterTest.cs index 7d387ee3bb..57c6b83f07 100644 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterTest.cs +++ b/tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterTest.cs @@ -13,8 +13,8 @@ protected CSharpEmitter CreateEmitter() return new CSharpEmitter(); } - protected CSharpSyntaxNode Transform(Symbol symbol, TypeStore? typeStore = null) + protected CSharpSyntaxNode Transform(Symbol symbol) { - return CreateEmitter().Transform(symbol, typeStore ?? new TypeStore()); + return CreateEmitter().Transform(symbol); } } diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/ExternalTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/ExternalTypeReferenceTests.cs deleted file mode 100644 index 3ec08dbb6f..0000000000 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/ExternalTypeReferenceTests.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Security.Cryptography.X509Certificates; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.Emitter.Tests; - -public class ExternalTypeReferenceTests : EmitterTest -{ - [Fact, Trait("Category", "Symbols"), - Trait("Target Language", "C#")] - public void StringTestNoNamespace() - { - var symbol = new ExternalTypeReference(null, new IdentifierSymbol("ETR1")); - - var transformed = Transform(symbol); - - Assert.Equal("ETR1", transformed.ToFullString()); - } - - [Fact, Trait("Category", "Symbols"), - Trait("Target Language", "C#")] - public void StringTestWithNamespace() - { - var symbol = new ExternalTypeReference(new IdentifierSymbol("Namespace"), new IdentifierSymbol("ETR1")); - - var transformed = Transform(symbol); - - Assert.Equal("Namespace.ETR1", transformed.ToFullString()); - } -} diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/FunctionPointerTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/FunctionPointerTypeReferenceTests.cs deleted file mode 100644 index 832514c30a..0000000000 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/FunctionPointerTypeReferenceTests.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.Emitter.Tests; - -public class FunctionPointerTypeReferenceTests : EmitterTest -{ - [Fact, Trait("Category", "Symbols"), - Trait("Target Language", "C#")] - public void StringTestNoParams() - { - var symbol = new FunctionPointerTypeReference - (new ExternalTypeReference(null, new IdentifierSymbol("Ret")), ImmutableArray.Empty); - - var transformed = Transform(symbol); - - Assert.Equal("delegate* unmanaged", transformed.ToFullString()); - } - - [Fact, Trait("Category", "Symbols"), - Trait("Target Language", "C#")] - public void StringTestWithParams() - { - var symbol = new FunctionPointerTypeReference - (new ExternalTypeReference(null, new IdentifierSymbol("Ret")), new TypeReference[] - { - new ExternalTypeReference(null, new IdentifierSymbol("Param1")), - new ExternalTypeReference(null, new IdentifierSymbol("Param2")), - }.ToImmutableArray()); - - var transformed = Transform(symbol); - - Assert.Equal("delegate* unmanaged", transformed.ToFullString()); - } -} diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierSymbolTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierTests.cs similarity index 60% rename from tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierSymbolTests.cs rename to tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierTests.cs index 4ba0dcbcba..d66038ac48 100644 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierSymbolTests.cs +++ b/tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierTests.cs @@ -1,30 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.ComponentModel; using Silk.NET.SilkTouch.Symbols; using Xunit; namespace Silk.NET.SilkTouch.Emitter.Tests; -public class IdentifierSymbolTests : EmitterTest +public sealed class IdentifierTests : EmitterTest { - [Theory, Trait("Category", "Symbols"), - Trait("Target Language", "C#")] - [InlineData("a", "a")] - [InlineData("int", "int")] - [InlineData("using", "using")] - [InlineData("veryLongIdentifierName", "veryLongIdentifierName")] - [InlineData("this is invalid # /**/", "this is invalid # /**/")] - public void StringTest(string identifierText, string csharp) - { - var symbol = new IdentifierSymbol(identifierText); - - var transformed = Transform(symbol); - - Assert.Equal(csharp, transformed.ToFullString()); - } - [Fact, Trait("Category", "Emitter"), Trait("Target Language", "C#")] @@ -46,4 +29,14 @@ public void IdentifierHasNoTrailingTrivia() Assert.Empty(node.GetTrailingTrivia()); Assert.False(node.HasTrailingTrivia); } + + [Fact, + Trait("Category", "Emitter"), + Trait("Target Language", "C#")] + public void IdentifierIntegration() + { + var node = Transform(new IdentifierSymbol("Test")); + + Assert.Equal("Test", node.ToFullString()); + } } diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/InternalTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/InternalTypeReferenceTests.cs deleted file mode 100644 index a5b76a1279..0000000000 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/InternalTypeReferenceTests.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.ComponentModel; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.Emitter.Tests; - -public class InternalTypeReferenceTests : EmitterTest -{ - [Fact, Trait("Category", "Type Resolution"), Trait("Category", "Symbols")] - public void StringTest() - { - var typeStore = new TypeStore(); - - var typeId = TypeId.CreateNew(); - var actualType = new StructSymbol - (typeId, new IdentifierSymbol("Identifier"), ImmutableArray.Empty); - typeStore.Store(actualType); - var symbol = new InternalTypeReference(typeId); - - var transformed = Transform(symbol, typeStore); - - Assert.Equal("Identifier", transformed.ToFullString()); - } -} diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/PointerTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/PointerTypeReferenceTests.cs deleted file mode 100644 index f33981d95e..0000000000 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/PointerTypeReferenceTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.Emitter.Tests; - -public class PointerTypeReferenceTests : EmitterTest -{ - [Fact, Trait("Category", "Symbols")] - public void StringTest() - { - var symbol = new PointerTypeReference(new ExternalTypeReference(null, new IdentifierSymbol("ETR1"))); - - var transformed = Transform(symbol); - - Assert.Equal("ETR1*", transformed.ToFullString()); - } -} diff --git a/tests/Silk.NET.SilkTouch.Emitter.Tests/StaticExternalMethodSymbolTests.cs b/tests/Silk.NET.SilkTouch.Emitter.Tests/StaticExternalMethodSymbolTests.cs deleted file mode 100644 index f08c92d581..0000000000 --- a/tests/Silk.NET.SilkTouch.Emitter.Tests/StaticExternalMethodSymbolTests.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.Emitter.Tests; - -public class StaticExternalMethodSymbolTests : EmitterTest -{ - [Fact, Trait("Category", "Symbols")] - public void StringTestNoParameters() - { - var symbol = new StaticExternalMethodSymbol - ( - new ExternalTypeReference(null, new IdentifierSymbol("int")), - ImmutableArray.Empty, - new IdentifierSymbol("M") - ); - - var transformed = Transform(symbol); - - Assert.Equal("public static extern int M();", transformed.ToFullString()); - } -} diff --git a/tests/Silk.NET.SilkTouch.IntegrationTests/Silk.NET.SilkTouch.IntegrationTests.csproj b/tests/Silk.NET.SilkTouch.IntegrationTests/Silk.NET.SilkTouch.IntegrationTests.csproj index 3a41f39a8e..a850c871b9 100644 --- a/tests/Silk.NET.SilkTouch.IntegrationTests/Silk.NET.SilkTouch.IntegrationTests.csproj +++ b/tests/Silk.NET.SilkTouch.IntegrationTests/Silk.NET.SilkTouch.IntegrationTests.csproj @@ -28,7 +28,6 @@ - diff --git a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test1.verified.txt b/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test1.verified.txt index fea687fc30..be84d7c0fb 100644 --- a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test1.verified.txt +++ b/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test1.verified.txt @@ -6,7 +6,7 @@ namespace LIBRARY_NAMESPACE { public struct Test { - public System.Int32 f1; - public System.Int32 f2; + public int f1; + public int f2; } -} \ No newline at end of file +} diff --git a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test10.verified.txt b/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test10.verified.txt deleted file mode 100644 index 3623d32d16..0000000000 --- a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test10.verified.txt +++ /dev/null @@ -1,11 +0,0 @@ - - -/* -------------------------- NEW OUTPUT -------------------------- */ - -namespace LIBRARY_NAMESPACE -{ - public class Methods - { - public static extern System.Int32 test(System.Int32* pointer); - } -} \ No newline at end of file diff --git a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test11.verified.txt b/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test11.verified.txt deleted file mode 100644 index 9812b3699a..0000000000 --- a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test11.verified.txt +++ /dev/null @@ -1,11 +0,0 @@ - - -/* -------------------------- NEW OUTPUT -------------------------- */ - -namespace LIBRARY_NAMESPACE -{ - public struct Test - { - public System.Int32*** f1; - } -} \ No newline at end of file diff --git a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test9.verified.txt b/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test9.verified.txt deleted file mode 100644 index 3623d32d16..0000000000 --- a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.Test9.verified.txt +++ /dev/null @@ -1,11 +0,0 @@ - - -/* -------------------------- NEW OUTPUT -------------------------- */ - -namespace LIBRARY_NAMESPACE -{ - public class Methods - { - public static extern System.Int32 test(System.Int32* pointer); - } -} \ No newline at end of file diff --git a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.cs b/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.cs index 8eb2930be6..bab6755609 100644 --- a/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.cs +++ b/tests/Silk.NET.SilkTouch.IntegrationTests/StructIntegrationTests.cs @@ -10,7 +10,7 @@ namespace Silk.NET.SilkTouch.IntegrationTests; [UsesVerify] public class StructIntegrationTests { - [Fact, + [Fact(Skip = "TODO: Reenable after proper type support"), Trait("Category", "Integration"), Trait("Source Language", "C++"), Trait("Target Language", "C#"), @@ -66,7 +66,7 @@ struct { long k, l; } w; return Verifier.Verify(result); } - [Fact, + [Fact(Skip = "TODO: Reenable after proper type support"), Trait("Category", "Integration"), Trait("Source Language", "C++"), Trait("Target Language", "C#"), @@ -156,7 +156,7 @@ struct S return Verifier.Verify(result); } - [Fact(Skip = "Nested Types?!"), + [Fact(Skip = "TODO: Reenable after proper type support"), Trait("Category", "Integration"), Trait("Source Language", "C++"), Trait("Target Language", "C#"), @@ -172,49 +172,4 @@ struct x *p; };"); return Verifier.Verify(result); } - - [Fact(Skip = "__declspec is windows only"), - Trait("Category", "Integration"), - Trait("Source Language", "C++"), - Trait("Target Language", "C#"), - Trait("Feature", "Functions")] - public Task Test9() - { - var result = TestHelper.GetCSharpOutputFromCpp(@" -#define GLFWAPI __declspec(dllexport) -GLFWAPI int test(int* pointer); -"); - return Verifier.Verify(result); - } - - [Fact, - Trait("Category", "Integration"), - Trait("Source Language", "C++"), - Trait("Target Language", "C#"), - Trait("Feature", "Functions")] - public Task Test10() - { - var result = TestHelper.GetCSharpOutputFromCpp(@" -#define GLFWAPI __attribute__((visibility(""default""))) -GLFWAPI int test(int* pointer); -"); - return Verifier.Verify(result); - } - - [Fact, - Trait("Category", "Integration"), - Trait("Source Language", "C++"), - Trait("Target Language", "C#"), - Trait("Feature", "Structs"), - Trait("Feature", "Fields")] - public Task Test11() - { - var result = TestHelper.GetCSharpOutputFromCpp(@" -#include - -typedef struct { - int32_t*** f1; -} Test;"); - return Verifier.Verify(result); - } } diff --git a/tests/Silk.NET.SilkTouch.IntegrationTests/TestHelper.cs b/tests/Silk.NET.SilkTouch.IntegrationTests/TestHelper.cs index 2b41031905..0f1c4acc97 100644 --- a/tests/Silk.NET.SilkTouch.IntegrationTests/TestHelper.cs +++ b/tests/Silk.NET.SilkTouch.IntegrationTests/TestHelper.cs @@ -10,8 +10,6 @@ using Microsoft.Extensions.Logging; using Silk.NET.SilkTouch.Emitter; using Silk.NET.SilkTouch.Scraper; -using Silk.NET.SilkTouch.Symbols; -using Silk.NET.SilkTouch.TypeResolution; using Xunit; namespace Silk.NET.SilkTouch.IntegrationTests; @@ -48,28 +46,9 @@ public static string GetCSharpOutputFromCpp(string cpp) Assert.NotNull(xml); - var typeStore = new TypeStore(); - var symbols = scraper.ScrapeXML(xml!, typeStore).ToArray(); - - var typeScopeSymbolVisitor = ActivatorUtilities.CreateInstance(serviceProvider, typeStore); - var processors = new SymbolVisitor[] - { - ActivatorUtilities.CreateInstance(serviceProvider, typeStore), - ActivatorUtilities.CreateInstance(serviceProvider, typeStore), - ActivatorUtilities.CreateInstance(serviceProvider, typeStore), - - typeScopeSymbolVisitor, - ActivatorUtilities.CreateInstance - (serviceProvider, typeScopeSymbolVisitor.RootScope, typeStore) - }; - - foreach (var processor in processors) - { - symbols = symbols.Select(processor.Visit).ToArray(); - } - + var symbols = scraper.ScrapeXML(xml!); var emitter = new CSharpEmitter(); - var outputs = symbols.Select(x => emitter.Transform(x, typeStore)); + var outputs = symbols.Select(x => emitter.Transform(x)); return outputs.Aggregate ( "", diff --git a/tests/Silk.NET.SilkTouch.Scraper.Tests/FieldScrapingTests.cs b/tests/Silk.NET.SilkTouch.Scraper.Tests/FieldScrapingTests.cs index dea71f6ccb..50f7aec998 100644 --- a/tests/Silk.NET.SilkTouch.Scraper.Tests/FieldScrapingTests.cs +++ b/tests/Silk.NET.SilkTouch.Scraper.Tests/FieldScrapingTests.cs @@ -17,7 +17,7 @@ public void FieldSymbol() var doc = new XmlDocument(); doc.LoadXml(@"int"); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var field = Assert.IsType(symbol); @@ -31,7 +31,7 @@ public void CorrectIdentifier() var doc = new XmlDocument(); doc.LoadXml(@"int"); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var field = Assert.IsType(symbol); @@ -46,7 +46,7 @@ public void CorrectType() var doc = new XmlDocument(); doc.LoadXml(@"int"); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var field = Assert.IsType(symbol); diff --git a/tests/Silk.NET.SilkTouch.Scraper.Tests/IdentityScrapingTests.cs b/tests/Silk.NET.SilkTouch.Scraper.Tests/IdentityScrapingTests.cs index caf22932c8..f4f1a92789 100644 --- a/tests/Silk.NET.SilkTouch.Scraper.Tests/IdentityScrapingTests.cs +++ b/tests/Silk.NET.SilkTouch.Scraper.Tests/IdentityScrapingTests.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Xml; -using Silk.NET.SilkTouch.Symbols; using Xunit; namespace Silk.NET.SilkTouch.Scraper.Tests; @@ -16,7 +15,7 @@ public void GeneratesNoSymbols() { var doc = new XmlDocument(); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); Assert.Empty(symbols); } @@ -30,7 +29,7 @@ public void BindingsGeneratesNoSymbols() "); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); Assert.Empty(symbols); } diff --git a/tests/Silk.NET.SilkTouch.Scraper.Tests/NamespaceScrapingTests.cs b/tests/Silk.NET.SilkTouch.Scraper.Tests/NamespaceScrapingTests.cs index 473ffb5f5d..c27deb787c 100644 --- a/tests/Silk.NET.SilkTouch.Scraper.Tests/NamespaceScrapingTests.cs +++ b/tests/Silk.NET.SilkTouch.Scraper.Tests/NamespaceScrapingTests.cs @@ -21,7 +21,7 @@ public void NamespaceSymbol() "); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var @namespace = Assert.IsType(symbol); @@ -42,7 +42,7 @@ public void NamespaceMember() "); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var @namespace = Assert.IsType(symbol); @@ -68,7 +68,7 @@ public void MultipleNamespaceMembers() "); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var @namespace = Assert.IsType(symbol); diff --git a/tests/Silk.NET.SilkTouch.Scraper.Tests/StructMemberScrapingTests.cs b/tests/Silk.NET.SilkTouch.Scraper.Tests/StructMemberScrapingTests.cs index 6cd5d2ca4a..44cb47c6a6 100644 --- a/tests/Silk.NET.SilkTouch.Scraper.Tests/StructMemberScrapingTests.cs +++ b/tests/Silk.NET.SilkTouch.Scraper.Tests/StructMemberScrapingTests.cs @@ -18,7 +18,7 @@ public void SingleMember() var doc = new XmlDocument(); doc.LoadXml(@"int"); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var @struct = Assert.IsType(symbol); @@ -43,7 +43,7 @@ public void MultipleMembers() @"intint" ); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var @struct = Assert.IsType(symbol); diff --git a/tests/Silk.NET.SilkTouch.Scraper.Tests/StructScrapingTests.cs b/tests/Silk.NET.SilkTouch.Scraper.Tests/StructScrapingTests.cs index 8315c1df35..b29d174d7a 100644 --- a/tests/Silk.NET.SilkTouch.Scraper.Tests/StructScrapingTests.cs +++ b/tests/Silk.NET.SilkTouch.Scraper.Tests/StructScrapingTests.cs @@ -17,7 +17,7 @@ public void StructSymbol() var doc = new XmlDocument(); doc.LoadXml(@""); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var @struct = Assert.IsType(symbol); @@ -31,7 +31,7 @@ public void CorrectIdentifier() var doc = new XmlDocument(); doc.LoadXml(@""); - var symbols = Helpers.CreateScraper().ScrapeXML(doc, new TypeStore()); + var symbols = Helpers.CreateScraper().ScrapeXML(doc); var symbol = Assert.Single(symbols); var @struct = Assert.IsType(symbol); diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/MockSymbolVisitor.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/MockSymbolVisitor.cs deleted file mode 100644 index 6aa4b198a6..0000000000 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/MockSymbolVisitor.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Silk.NET.SilkTouch.Symbols.Tests; - -public class MockSymbolVisitor : SymbolVisitor -{ - public MockSymbolVisitor() : base(new TypeStore()) - { - } -} diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ClassSymbolTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ClassSymbolTests.cs deleted file mode 100644 index 1827240265..0000000000 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ClassSymbolTests.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using Moq; -using Moq.Protected; -using Xunit; - -namespace Silk.NET.SilkTouch.Symbols.Tests.SymbolVisitorTests; - -public class ClassSymbolTests -{ - [Fact, Trait("Category", "Symbols")] - public void IsVisitedAsSelf() - { - var symbol = new ClassSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - - var visitor = new Mock { CallBase = true }; - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify("VisitClass", Times.Once(), ItExpr.IsAny()); - } - - [Fact, Trait("Category", "Symbols")] - public void IsVisitedAsType() - { - var symbol = new ClassSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - - var visitor = new Mock { CallBase = true }; - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify("VisitType", Times.Once(), ItExpr.IsAny()); - } -} diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs index ba7ca16cae..6d6b86f815 100644 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs +++ b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs @@ -14,7 +14,11 @@ public class ExternalTypeReferenceTests public void RefIsVisitedAsRef() { var symbol = new ExternalTypeReference(null, new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -26,7 +30,11 @@ public void RefIsVisitedAsRef() public void RefIsVisitedAsGenericRef() { var symbol = new ExternalTypeReference(null, new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -38,7 +46,11 @@ public void RefIsVisitedAsGenericRef() public void RefTypeIdentifierIsVisitedAsIdentifier() { var symbol = new ExternalTypeReference(null, new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -50,7 +62,11 @@ public void RefTypeIdentifierIsVisitedAsIdentifier() public void RefNamespaceIsVisitedAsIdentifier() { var symbol = new ExternalTypeReference(new IdentifierSymbol(""), new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs index 7af2066829..7822eedae9 100644 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs +++ b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs @@ -16,7 +16,11 @@ public class FieldTests public void FieldIsVisitedAsField() { var symbol = new FieldSymbol(new ExternalTypeReference(null, new IdentifierSymbol("")), new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -29,7 +33,11 @@ public void FieldIsVisitedAsField() public void FieldIsVisitedAsMember() { var symbol = new FieldSymbol(new ExternalTypeReference(null, new IdentifierSymbol("")), new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -42,7 +50,11 @@ public void FieldIsVisitedAsMember() public void FieldTypeIsVisited() { var symbol = new FieldSymbol(new ExternalTypeReference(null, new IdentifierSymbol("")), new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -55,7 +67,11 @@ public void FieldTypeIsVisited() public void FieldIdentifierIsVisited() { var symbol = new FieldSymbol(new ExternalTypeReference(null, new IdentifierSymbol("")), new IdentifierSymbol("")); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FunctionPointerTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FunctionPointerTypeReferenceTests.cs deleted file mode 100644 index a6eca9d576..0000000000 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FunctionPointerTypeReferenceTests.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using Moq; -using Moq.Protected; -using Xunit; - -namespace Silk.NET.SilkTouch.Symbols.Tests.SymbolVisitorTests; - -public class FunctionPointerTypeReferenceTests -{ - [Fact, Trait("Category", "Symbols")] - public void VisitedAsSelf() - { - var symbol = new FunctionPointerTypeReference(new InternalTypeReference(TypeId.CreateNew()), ImmutableArray.Empty); - var visitor = new Mock { CallBase = true }; - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitFunctionPointerTypeReference", Times.Once(), ItExpr.IsAny()); - } - - [Fact, Trait("Category", "Symbols")] - public void VisitedAsRef() - { - var symbol = new FunctionPointerTypeReference(new InternalTypeReference(TypeId.CreateNew()), ImmutableArray.Empty); - var visitor = new Mock { CallBase = true }; - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitTypeReference", Times.Once(), ItExpr.Is(x => ReferenceEquals(x, symbol))); - } -} diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/IdentifierTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/IdentifierTests.cs index 518f837b1a..4b966473ef 100644 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/IdentifierTests.cs +++ b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/IdentifierTests.cs @@ -15,7 +15,11 @@ public class IdentifierTests public void IdentifierIsVisitedAsIdentifier() { var symbol = new IdentifierSymbol(""); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/InternalTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/InternalTypeReferenceTests.cs deleted file mode 100644 index 25b9156b1f..0000000000 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/InternalTypeReferenceTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using Moq; -using Moq.Protected; -using Xunit; - -namespace Silk.NET.SilkTouch.Symbols.Tests.SymbolVisitorTests; - -public class InternalTypeReferenceTests -{ - [Fact, Trait("Category", "Symbols")] - public void VisitedAsSelf() - { - var symbol = new InternalTypeReference(TypeId.CreateNew()); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitInternalTypeReference", Times.Once(), ItExpr.IsAny()); - } - - [Fact, Trait("Category", "Symbols")] - public void VisitedAsParent() - { - var symbol = new InternalTypeReference(TypeId.CreateNew()); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitTypeReference", Times.Once(), ItExpr.IsAny()); - } - - - [Fact, Trait("Category", "Symbols")] - public void TypeIdIsVisited() - { - var id = TypeId.CreateNew(); - var symbol = new InternalTypeReference(id); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected().Verify("VisitTypeId", Times.Once(), ItExpr.Is(x => x == id)); - } -} diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/NamespaceTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/NamespaceTests.cs index 26ece099dd..0cf502f7a1 100644 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/NamespaceTests.cs +++ b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/NamespaceTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Immutable; using Moq; using Moq.Protected; @@ -17,8 +16,12 @@ public class NamespaceTests public void NamespaceIdentifierIsVisited() { var symbol = new NamespaceSymbol(new IdentifierSymbol(""), ImmutableArray.Empty); + + var visitor = new Mock + { + CallBase = true + }; - var visitor = new Mock { CallBase = true }; visitor.Object.Visit(symbol); visitor.Protected() @@ -33,10 +36,14 @@ public void NamespaceMemberIsVisited() { var symbol = new NamespaceSymbol(new IdentifierSymbol(""), new [] { - (TypeSymbol)new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty) + (TypeSymbol)new StructSymbol(new IdentifierSymbol(""), ImmutableArray.Empty) }.ToImmutableArray()); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/PointerTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/PointerTypeReferenceTests.cs deleted file mode 100644 index 44adcbb56e..0000000000 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/PointerTypeReferenceTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Moq; -using Moq.Protected; -using Xunit; - -namespace Silk.NET.SilkTouch.Symbols.Tests.SymbolVisitorTests; - -public class PointerTypeReferenceTests -{ - [Fact, Trait("Category", "Symbols")] - public void RefIsVisitedAsSelf() - { - var symbol = new PointerTypeReference(new InternalTypeReference(TypeId.CreateNew())); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitPointerTypeReference", Times.Once(), ItExpr.IsAny()); - } - - [Fact, Trait("Category", "Symbols")] - public void RefIsVisitedAsRef() - { - var symbol = new PointerTypeReference(new InternalTypeReference(TypeId.CreateNew())); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitTypeReference", Times.Once(), ItExpr.Is(x => ReferenceEquals(x, symbol))); - } - - [Fact, Trait("Category", "Symbols")] - public void RefUnderlyingIsVisitedAsRef() - { - var underlying = new InternalTypeReference(TypeId.CreateNew()); - var symbol = new PointerTypeReference(underlying); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitTypeReference", Times.Once(), ItExpr.Is(x => ReferenceEquals(x, underlying))); - } -} diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StaticExternalMethodSymbolTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StaticExternalMethodSymbolTests.cs deleted file mode 100644 index 556410225d..0000000000 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StaticExternalMethodSymbolTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using Moq; -using Moq.Protected; -using Xunit; - -namespace Silk.NET.SilkTouch.Symbols.Tests.SymbolVisitorTests; - -public class StaticExternalMethodSymbolTests -{ - [Fact, Trait("Category", "Symbols")] - public void VisitedAsSelf() - { - var symbol = new StaticExternalMethodSymbol - (new InternalTypeReference(TypeId.CreateNew()), ImmutableArray.Empty, new IdentifierSymbol("")); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitStaticExternalMethod", Times.Once(), ItExpr.IsAny()); - } - - [Fact, Trait("Category", "Symbols")] - public void VisitedAsMethod() - { - var symbol = new StaticExternalMethodSymbol - (new InternalTypeReference(TypeId.CreateNew()), ImmutableArray.Empty, new IdentifierSymbol("")); - - var visitor = new Mock { CallBase = true }; - - visitor.Object.Visit(symbol); - - visitor.Protected() - .Verify - ("VisitMethod", Times.Once(), ItExpr.IsAny()); - } -} diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StructTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StructTests.cs index 96a8c2a043..b84b718fa0 100644 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StructTests.cs +++ b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StructTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Immutable; using Moq; using Moq.Protected; @@ -16,8 +15,12 @@ public class StructTests Trait("Feature", "Structs")] public void StructSymbolIsVisitedAsType() { - var symbol = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - var visitor = new Mock { CallBase = true }; + var symbol = new StructSymbol(new IdentifierSymbol(""), ImmutableArray.Empty); + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -29,8 +32,12 @@ public void StructSymbolIsVisitedAsType() Trait("Feature", "Structs")] public void StructSymbolIsVisitedAsStruct() { - var symbol = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - var visitor = new Mock { CallBase = true }; + var symbol = new StructSymbol(new IdentifierSymbol(""), ImmutableArray.Empty); + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -42,8 +49,12 @@ public void StructSymbolIsVisitedAsStruct() Trait("Feature", "Structs")] public void StructIdentifierIsVisitedAsIdentifier() { - var symbol = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - var visitor = new Mock { CallBase = true }; + var symbol = new StructSymbol(new IdentifierSymbol(""), ImmutableArray.Empty); + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -57,11 +68,15 @@ public void StructIdentifierIsVisitedAsIdentifier() public void StructFieldIsVisited() { var member = new FieldSymbol(new ExternalTypeReference(null, new IdentifierSymbol("int")), new IdentifierSymbol("Test1")); - var symbol = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("Test"), new[] + var symbol = new StructSymbol(new IdentifierSymbol("Test"), new[] { member }.ToImmutableArray()); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() @@ -77,11 +92,15 @@ public void StructFieldsAreVisited() { var member1 = new FieldSymbol(new ExternalTypeReference(null, new IdentifierSymbol("int")), new IdentifierSymbol("Test1")); var member2 = new FieldSymbol(new ExternalTypeReference(null, new IdentifierSymbol("int")), new IdentifierSymbol("Test2")); - var symbol = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("Test"), new[] + var symbol = new StructSymbol(new IdentifierSymbol("Test"), new[] { member1, member2 }.ToImmutableArray()); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + visitor.Object.Visit(symbol); visitor.Protected() diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/UnresolvedTypeReferenceTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/UnresolvedTypeReferenceTests.cs index a2cbaf7ecc..3c358315e3 100644 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/UnresolvedTypeReferenceTests.cs +++ b/tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/UnresolvedTypeReferenceTests.cs @@ -14,7 +14,11 @@ public class UnresolvedTypeReferenceTests public void VisitingUnresolvedRefThrows() { var symbol = new UnresolvedTypeReference(""); - var visitor = new Mock { CallBase = true }; + var visitor = new Mock + { + CallBase = true + }; + Assert.Throws(() => visitor.Object.Visit(symbol)); } } diff --git a/tests/Silk.NET.SilkTouch.Symbols.Tests/TypeStoreTests.cs b/tests/Silk.NET.SilkTouch.Symbols.Tests/TypeStoreTests.cs deleted file mode 100644 index 0cc7ba7a34..0000000000 --- a/tests/Silk.NET.SilkTouch.Symbols.Tests/TypeStoreTests.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; -using System.ComponentModel; -using Xunit; - -namespace Silk.NET.SilkTouch.Symbols.Tests; - -public class TypeStoreTests -{ - [Fact, Trait("Category", "Symbols"), Trait("Category", "TypeStore")] - public void EmptyStoreDoesNotResolve() - { - var store = new TypeStore(); - - var result = store.TryResolve(TypeId.CreateNew(), out var ts); - - Assert.False(result); - Assert.Null(ts); - } - - [Fact, Trait("Category", "Symbols"), Trait("Category", "TypeStore")] - public void StoreResolvesSingleEntry() - { - var store = new TypeStore(); - var typeSymbol = new StructSymbol - (TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - store.Store(typeSymbol); - - var result = store.TryResolve(typeSymbol.Id, out var ts); - - Assert.True(result); - Assert.StrictEqual(typeSymbol, ts); - } - - [Fact, Trait("Category", "Symbols"), Trait("Category", "TypeStore")] - public void StoreResolvesMultipleEntries() - { - var store = new TypeStore(); - var typeSymbol1 = new StructSymbol - (TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - store.Store(typeSymbol1); - var typeSymbol2 = new StructSymbol - (TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - store.Store(typeSymbol2); - - var result1 = store.TryResolve(typeSymbol1.Id, out var ts1); - var result2 = store.TryResolve(typeSymbol2.Id, out var ts2); - - Assert.True(result1); - Assert.StrictEqual(typeSymbol1, ts1); - Assert.True(result2); - Assert.StrictEqual(typeSymbol2, ts2); - } -} diff --git a/tests/Silk.NET.SilkTouch.TestFramework/SilkTouchTestFramework.cs b/tests/Silk.NET.SilkTouch.TestFramework/SilkTouchTestFramework.cs index 9c32e43bd2..99a0be6b83 100644 --- a/tests/Silk.NET.SilkTouch.TestFramework/SilkTouchTestFramework.cs +++ b/tests/Silk.NET.SilkTouch.TestFramework/SilkTouchTestFramework.cs @@ -21,7 +21,6 @@ public class SilkTouchTestFramework : XunitTestFramework ["Nested Types"] = true, ["Structs"] = true, ["Unions"] = false, - ["Functions"] = true }; public SilkTouchTestFramework(IMessageSink messageSink) @@ -74,7 +73,7 @@ ITestFrameworkDiscoveryOptions discoveryOptions foreach (var (name, value) in traits) { if (name is "Category" && - value is not "Integration" and not "Scraper" and not "Symbols" and not "Emitter" and not "TypeStore" and not "Type Resolution") + value is not "Integration" and not "Scraper" and not "Symbols" and not "Emitter") { return this.ReportDiscoveredTestCase ( diff --git a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/FunctionPointerTypeResolverTests.cs b/tests/Silk.NET.SilkTouch.TypeResolution.Tests/FunctionPointerTypeResolverTests.cs deleted file mode 100644 index 7abfe54a4f..0000000000 --- a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/FunctionPointerTypeResolverTests.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Linq; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.TypeResolution.Tests; - -public class FunctionPointerTypeResolverTests -{ - [Theory, Trait("Category", "Type Resolution"), - InlineData("delegate* unmanaged", "A", new string[0]), - InlineData("delegate* unmanaged", "C", new[] { "A", "B"}), - InlineData("delegate* unmanaged[Cdecl]", "A", new string[0]), - InlineData("delegate* unmanaged[Cdecl]", "C", new[] { "A", "B"}), - InlineData("delegate* unmanaged", "C", new[] { "A", "B"}), - InlineData("delegate* unmanaged[Cdecl]", "C", new[] { "A", "B"}), - InlineData("delegate* unmanaged[Cdecl, SupressGCTransition]", "A", new string[0]), - InlineData("delegate* unmanaged[Cdecl, SupressGCTransition]", "C", new[] { "A", "B"}), - ] - public void ShouldMatch(string text, string returnString, string[] parameters) - { - var serviceProvider = Helpers.CreateServiceProvider(); - var result = new FunctionPointerTypeResolver - (serviceProvider.GetRequiredService>(), new TypeStore()).Visit - (new UnresolvedTypeReference(text)); - - var fptr = Assert.IsType(result); - Assert.Equal(returnString, Assert.IsType(fptr.ReturnType).Text); - Assert.Collection - ( - fptr.ParameterTypes, - parameters.Select - ( - x => new Action(r => Assert.Equal(x, Assert.IsType(r).Text)) - ) - .ToArray() - ); - } - - - [Theory, Trait("Category", "Type Resolution"), - InlineData(""), - InlineData("a"), - InlineData("*"), - InlineData("a.b.c"), - InlineData("longType"), - InlineData("int"), - InlineData("using"), - InlineData("delegate*"), - InlineData("delegate* unmanaged<>"), - ] - public void ShouldNotMatch(string text) - { - var serviceProvider = Helpers.CreateServiceProvider(); - var result = new FunctionPointerTypeResolver - (serviceProvider.GetRequiredService>(), new TypeStore()).Visit - (new UnresolvedTypeReference(text)); - - Assert.IsNotType(result); - } -} diff --git a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/Helpers.cs b/tests/Silk.NET.SilkTouch.TypeResolution.Tests/Helpers.cs deleted file mode 100644 index 2571b783e4..0000000000 --- a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/Helpers.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace Silk.NET.SilkTouch.TypeResolution.Tests; - -public class Helpers -{ - public static IServiceProvider CreateServiceProvider() - { - var serviceProvider = new ServiceCollection() - .AddLogging(builder => - { - builder.AddConsole(); - builder.SetMinimumLevel(LogLevel.Trace); - } - ) - .BuildServiceProvider(); - - return serviceProvider; - } -} diff --git a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/NameResolverSymbolVisitorTests.cs b/tests/Silk.NET.SilkTouch.TypeResolution.Tests/NameResolverSymbolVisitorTests.cs deleted file mode 100644 index b6ba35d2f1..0000000000 --- a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/NameResolverSymbolVisitorTests.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.TypeResolution.Tests; - -public class NameResolverSymbolVisitorTests -{ - [Fact, Trait("Category", "Type Resolution")] - public void SelfTypeIsResolvedCorrectly() - { - var testType = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("a"), new FieldSymbol[] - { - new(new UnresolvedTypeReference("a"), new IdentifierSymbol("someField")) - }.ToImmutableArray()); - var typeStore = new TypeStore(); - typeStore.Store(testType); - var resolutionScope = new TypeResolutionScope - ( - new Dictionary - { - [testType.Id] = new TypeResolutionScope(new()) - } - ); - var serviceProvider = Helpers.CreateServiceProvider(); - var visitor = new NameResolverSymbolVisitor - ( - serviceProvider.GetRequiredService().CreateLogger(), - resolutionScope, - typeStore - ); - - var resultType = visitor.Visit(testType); - - var @struct = Assert.IsType(resultType); - Assert.StrictEqual(testType.Identifier, @struct.Identifier); - var field = Assert.Single(@struct.Fields); - Assert.StrictEqual(testType.Fields[0].Identifier, @field.Identifier); - var reference = Assert.IsType(field.Type); - Assert.StrictEqual(@struct.Id, reference.ReferencedTypeId); - } -} diff --git a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/PointerResolverTests.cs b/tests/Silk.NET.SilkTouch.TypeResolution.Tests/PointerResolverTests.cs deleted file mode 100644 index 171358cb12..0000000000 --- a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/PointerResolverTests.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.TypeResolution.Tests; - -public sealed class PointerResolverTests -{ - [Theory, Trait("Category", "Type Resolution"), - InlineData("a*"), - InlineData("a.b.c*"), - InlineData("int*") - ] - public void ShouldResolve(string text) - { - var symbol = new UnresolvedTypeReference(text); - var output = new PointerTypeResolver(new TypeStore()); - - var finalSymbol = output.Visit(symbol); - Assert.IsType(finalSymbol); - } - - [Theory, Trait("Category", "Type Resolution"), - InlineData(""), - InlineData("a"), - InlineData("*"), - InlineData("a.b.c"), - InlineData("longType"), - InlineData("int"), - InlineData("using") - ] - public void ShouldNotResolve(string text) - { - var symbol = new UnresolvedTypeReference(text); - var output = new PointerTypeResolver(new TypeStore()); - - var finalSymbol = output.Visit(symbol); - Assert.IsNotType(finalSymbol); - } - - [Fact, Trait("Category", "Type Resolution")] - public void MultiPointer() - { - var symbol = new UnresolvedTypeReference("int***"); - var output = new PointerTypeResolver(new TypeStore()); - - var finalSymbol = output.Visit(symbol); - var outer = Assert.IsType(finalSymbol); - var middle = Assert.IsType(outer.Underlying); - var inner = Assert.IsType(middle.Underlying); - Assert.IsNotType(inner.Underlying); - } -} diff --git a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/PrimitiveTypeResolverTests.cs b/tests/Silk.NET.SilkTouch.TypeResolution.Tests/PrimitiveTypeResolverTests.cs deleted file mode 100644 index 0156eb63b3..0000000000 --- a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/PrimitiveTypeResolverTests.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.TypeResolution.Tests; - -public sealed class PrimitiveTypeResolverTests -{ - [Theory, Trait("Category", "Type Resolution"), - InlineData("bool", "System", "Boolean"), - InlineData("byte", "System", "Byte"), - InlineData("sbyte", "System", "SByte"), - InlineData("char", "System", "Char"), - InlineData("decimal", "System", "Decimal"), - InlineData("double", "System", "Double"), - InlineData("float", "System", "Single"), - InlineData("int", "System", "Int32"), - InlineData("uint", "System", "UInt32"), - InlineData("nint", "System", "IntPtr"), - InlineData("nuint", "System", "UIntPtr"), - InlineData("long", "System", "Int64"), - InlineData("ulong", "System", "UInt64"), - InlineData("short", "System", "Int16"), - InlineData("ushort", "System", "UInt16"), - InlineData("void", null, "void"), - ] - public void ShouldResolve(string text, string? @namespace, string identifier) - { - var symbol = new UnresolvedTypeReference(text); - var output = new PrimitiveTypeResolver(new TypeStore()); - - var finalSymbol = output.Visit(symbol); - var @ref = Assert.IsType(finalSymbol); - Assert.Equal(@namespace, @ref.Namespace?.Value); - Assert.Equal(identifier, @ref.TypeIdentifier.Value); - } - - [Theory, Trait("Category", "Type Resolution"), - InlineData(""), - InlineData("a"), - InlineData("*"), - InlineData("a.b.c"), - InlineData("longType"), - InlineData("using") - ] - public void ShouldNotResolve(string text) - { - var symbol = new UnresolvedTypeReference(text); - var output = new PrimitiveTypeResolver(new TypeStore()); - - var finalSymbol = output.Visit(symbol); - Assert.IsNotType(finalSymbol); - } -} diff --git a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/TypeScopeSymbolVisitorTests.cs b/tests/Silk.NET.SilkTouch.TypeResolution.Tests/TypeScopeSymbolVisitorTests.cs deleted file mode 100644 index 10025021cb..0000000000 --- a/tests/Silk.NET.SilkTouch.TypeResolution.Tests/TypeScopeSymbolVisitorTests.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Immutable; -using Silk.NET.SilkTouch.Symbols; -using Xunit; - -namespace Silk.NET.SilkTouch.TypeResolution.Tests; - -public sealed class TypeScopeSymbolVisitorTests -{ - [Fact, Trait("Category", "Type Resolution")] - public void RootScopeContainsSingleRootType() - { - var testType = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - var visitor = new TypeScopeSymbolVisitor(new TypeStore()); - - visitor.Visit(testType); - - var rootScope = visitor.RootScope; - var single = Assert.Single(rootScope.ChildTypeScopes); - Assert.StrictEqual(testType.Id, single.Key); - var associatedScope = single.Value; - Assert.Empty(associatedScope.ChildTypeScopes); - } - - [Fact, Trait("Category", "Type Resolution")] - public void RootScopeEmptyWithEmptyNamespace() - { - var @namespace = new NamespaceSymbol(new IdentifierSymbol(""), ImmutableArray.Empty); - var visitor = new TypeScopeSymbolVisitor(new TypeStore()); - - visitor.Visit(@namespace); - - var rootScope = visitor.RootScope; - Assert.Empty(rootScope.ChildTypeScopes); - } - - [Fact, Trait("Category", "Type Resolution")] - public void RootScopeContainsSingleNamespacedType() - { - var testType = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol(""), ImmutableArray.Empty); - var @namespace = new NamespaceSymbol - ( - new IdentifierSymbol(""), - new[] - { - (TypeSymbol) testType - }.ToImmutableArray() - ); - var visitor = new TypeScopeSymbolVisitor(new TypeStore()); - - visitor.Visit(@namespace); - - var rootScope = visitor.RootScope; - var single = Assert.Single(rootScope.ChildTypeScopes); - Assert.StrictEqual(testType.Id, single.Key); - var associatedScope = single.Value; - Assert.Empty(associatedScope.ChildTypeScopes); - } - - [Fact, Trait("Category", "Type Resolution")] - public void RootScopeContainsMultipleNamespacedTypes() - { - var testType1 = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("T1"), ImmutableArray.Empty); - var testType2 = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("T2"), ImmutableArray.Empty); - var testType3 = new StructSymbol(TypeId.CreateNew(), new IdentifierSymbol("T3"), ImmutableArray.Empty); - var @namespace = new NamespaceSymbol - ( - new IdentifierSymbol(""), - new TypeSymbol[] - { - testType1, - testType2, - testType3 - }.ToImmutableArray() - ); - var visitor = new TypeScopeSymbolVisitor(new TypeStore()); - - visitor.Visit(@namespace); - - var rootScope = visitor.RootScope; - Assert.Collection - ( - rootScope.ChildTypeScopes, - (kv) => - { - Assert.StrictEqual(testType1.Id, kv.Key); - var associatedScope = kv.Value; - Assert.Empty(associatedScope.ChildTypeScopes); - }, - (kv) => - { - Assert.StrictEqual(testType2.Id, kv.Key); - var associatedScope = kv.Value; - Assert.Empty(associatedScope.ChildTypeScopes); - }, - (kv) => - { - Assert.StrictEqual(testType3.Id, kv.Key); - var associatedScope = kv.Value; - Assert.Empty(associatedScope.ChildTypeScopes); - } - ); - } -}