Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C# 8.0 nullable reference types #1425

Merged
merged 22 commits into from
Mar 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7a058f6
First attempt at integrating C# nullable reference types into the typ…
dgrunwald Feb 14, 2019
166b7de
Fix NRE in ApplyAttributeTypeVisitor.VisitTypeDefinition()
dgrunwald Feb 14, 2019
bbbfe81
Nullability of type parameters "where T : class?"
dgrunwald Feb 16, 2019
06cf9c1
Avoid exceptions on IType->ArrayType or IType->ITypeParameter casts d…
dgrunwald Feb 16, 2019
2f35374
Support "where T : unmanaged" constraints.
dgrunwald Feb 24, 2019
0238e64
Fix [DecimalConstant] parameters
dgrunwald Feb 24, 2019
45ae1ed
Merge branch 'origin/master' into nullable-reference-types
dgrunwald Feb 24, 2019
113acd4
Improve decompiler behavior is System.ValueTuple exists in multiple r…
dgrunwald Feb 24, 2019
b7b697f
Only reference Microsoft.VisualBasic.dll in VB-related tests.
dgrunwald Feb 24, 2019
be1ef7d
Re-generate the IL for test cases with Roslyn 2.10.0.
dgrunwald Feb 24, 2019
3fac3c0
Upgrade Roslyn for tests to 3.0.0-beta3.
dgrunwald Feb 24, 2019
482da77
Reenable LiftedOperators tests.
dgrunwald Feb 24, 2019
af69c03
Enable ValueTypes.cs pretty test
dgrunwald Feb 24, 2019
67124b3
Adjust tests to sorted top-level-types.
dgrunwald Feb 24, 2019
72508b5
Add test for C# 8 nullable reference types; and fix some bugs.
dgrunwald Feb 24, 2019
d42cf99
Fix dynamic transforms because https://github.com/dotnet/roslyn/issue…
siegfriedpammer Feb 25, 2019
e45ffc1
Update to Roslyn 3.0.0-beta4
dgrunwald Feb 28, 2019
80bc89f
Fix SwitchOnStringTransform.SimplifyCascadingIfStatements to handle n…
siegfriedpammer Mar 2, 2019
9c62f11
Add new switch(string) pattern for Roslyn.
siegfriedpammer Mar 2, 2019
6e49efd
Extend ILInlining to work with StringToInt instructions inside Switch…
siegfriedpammer Mar 2, 2019
7671ac6
Fix switch on nullable for Roslyn. Ignore switch on bool because it i…
siegfriedpammer Mar 2, 2019
32bc246
Set VersionName = "preview1"
siegfriedpammer Mar 2, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ void RunCS([CallerMemberName] string testName = null, CompilerOptions options =

void RunVB([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug)
{
options |= CompilerOptions.ReferenceVisualBasic;
string testFileName = testName + ".vb";
string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe";
CompilerResults outputFile = null, decompiledOutputFile = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ public void Run(AstNode rootNode, TransformContext context)
}
}

public class RemoveEmbeddedAtttributes : DepthFirstAstVisitor, IAstTransform
public class RemoveEmbeddedAttributes : DepthFirstAstVisitor, IAstTransform
{
HashSet<string> attributeNames = new HashSet<string>() {
"System.Runtime.CompilerServices.IsReadOnlyAttribute",
"System.Runtime.CompilerServices.IsByRefLikeAttribute",
"System.Runtime.CompilerServices.IsUnmanagedAttribute",
"System.Runtime.CompilerServices.NullableAttribute",
"Microsoft.CodeAnalysis.EmbeddedAttribute",
};

Expand Down
10 changes: 8 additions & 2 deletions ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ public static CompilerResults CompileVB(string sourceFileName, CompilerOptions f
if (flags.HasFlag(CompilerOptions.UseRoslyn)) {
var parseOptions = new VisualBasicParseOptions(preprocessorSymbols: preprocessorSymbols, languageVersion: LanguageVersion.Latest);
var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f));
var references = defaultReferences.Value;
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic)) {
references = references.Concat(visualBasic.Value);
}
var compilation = VisualBasicCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName),
syntaxTrees, defaultReferences.Value,
syntaxTrees, references,
new VisualBasicCompilationOptions(
flags.HasFlag(CompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(CompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
Expand Down Expand Up @@ -65,7 +69,9 @@ public static CompilerResults CompileVB(string sourceFileName, CompilerOptions f
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Core.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic)) {
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
}
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray());
if (results.Errors.Cast<CompilerError>().Any(e => !e.IsWarning)) {
StringBuilder b = new StringBuilder("Compiler error:");
Expand Down
34 changes: 25 additions & 9 deletions ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public enum CompilerOptions
Library = 0x8,
UseRoslyn = 0x10,
UseMcs = 0x20,
ReferenceVisualBasic = 0x40,
}

[Flags]
Expand Down Expand Up @@ -181,10 +182,11 @@ private static string ReplacePrivImplDetails(string il)
return Regex.Replace(il, @"'<PrivateImplementationDetails>\{[0-9A-F-]+\}'", "'<PrivateImplementationDetails>'");
}

static readonly Lazy<IEnumerable<MetadataReference>> defaultReferences = new Lazy<IEnumerable<MetadataReference>>(delegate {
string refAsmPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
static readonly string refAsmPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
@"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2");
string thisAsmPath = Path.GetDirectoryName(typeof(Tester).Assembly.Location);
static readonly string thisAsmPath = Path.GetDirectoryName(typeof(Tester).Assembly.Location);

static readonly Lazy<IEnumerable<MetadataReference>> defaultReferences = new Lazy<IEnumerable<MetadataReference>>(delegate {
return new[]
{
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "mscorlib.dll")),
Expand All @@ -194,12 +196,17 @@ private static string ReplacePrivImplDetails(string il)
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, @"Facades\System.Runtime.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "System.Xml.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Microsoft.CSharp.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Microsoft.VisualBasic.dll")),
MetadataReference.CreateFromFile(typeof(ValueTuple).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Span<>).Assembly.Location),
};
});

static readonly Lazy<IEnumerable<MetadataReference>> visualBasic = new Lazy<IEnumerable<MetadataReference>>(delegate {
return new[] {
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Microsoft.VisualBasic.dll"))
};
});

public static List<string> GetPreprocessorSymbols(CompilerOptions flags)
{
var preprocessorSymbols = new List<string>();
Expand Down Expand Up @@ -238,10 +245,17 @@ public static CompilerResults CompileCSharp(string sourceFileName, CompilerOptio
var preprocessorSymbols = GetPreprocessorSymbols(flags);

if (flags.HasFlag(CompilerOptions.UseRoslyn)) {
var parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols.ToArray(), languageVersion: Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest);
var parseOptions = new CSharpParseOptions(
preprocessorSymbols: preprocessorSymbols.ToArray(),
languageVersion: Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8
);
var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f));
var references = defaultReferences.Value;
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic)) {
references = references.Concat(visualBasic.Value);
}
var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName),
syntaxTrees, defaultReferences.Value,
syntaxTrees, references,
new CSharpCompilationOptions(
flags.HasFlag(CompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(CompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
Expand Down Expand Up @@ -328,7 +342,9 @@ public static CompilerResults CompileCSharp(string sourceFileName, CompilerOptio
options.ReferencedAssemblies.Add("System.Core.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic)) {
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
}
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray());
if (results.Errors.Cast<CompilerError>().Any(e => !e.IsWarning)) {
StringBuilder b = new StringBuilder("Compiler error:");
Expand Down Expand Up @@ -433,10 +449,10 @@ public static string DecompileCSharp(string assemblyFileName, DecompilerSettings
resolver.AddSearchDirectory(Path.GetDirectoryName(typeof(Span<>).Assembly.Location));
var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings);
decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAtttributes());
decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAttributes());
decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();
var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(sortTypes: true);

StringWriter output = new StringWriter();
var visitor = new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop());
Expand Down
13 changes: 9 additions & 4 deletions ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,19 @@
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG;NET46;ROSLYN;CS60;CS70</DefineConstants>
<DefineConstants>TRACE;DEBUG;NET46;ROSLYN;CS60;CS70;CS71;CS72;CS73</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE;NET46;ROSLYN;CS60;CS70;CS71;CS72;CS73</DefineConstants>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DiffLib" Version="2017.7.26.1241" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.10.0" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="2.10.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.0.0-beta4-final" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="3.0.0-beta4-final" />
<PackageReference Include="Microsoft.DiaSymReader.Converter.Xml" Version="1.1.0-beta1-63314-01" />
<PackageReference Include="NUnit3TestAdapter" Version="3.11.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="System.Memory" Version="4.5.1" />
Expand Down Expand Up @@ -81,6 +85,7 @@
<Compile Include="TestCases\ILPretty\Issue1323.cs" />
<Compile Include="TestCases\Pretty\CustomAttributes2.cs" />
<Compile Include="TestCases\Pretty\EnumTests.cs" />
<None Include="TestCases\Pretty\NullableRefTypes.cs" />
<Compile Include="TestCases\Pretty\TypeMemberTests.cs" />
<Compile Include="TestCases\Pretty\ValueTypes.cs" />
<None Include="TestCases\ILPretty\Issue1389.il" />
Expand Down
36 changes: 20 additions & 16 deletions ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ public void FixProxyCalls([Values(CompilerOptions.None, CompilerOptions.Optimize
}

[Test]
[Ignore("Special cases not implemented in new decompiler.")]
public void ValueTypes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
Expand Down Expand Up @@ -288,6 +287,12 @@ public void AsyncMain([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions c
Run(cscOptions: cscOptions);
}

[Test]
public void NullableRefTypes([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}

[Test]
public void NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{
Expand Down Expand Up @@ -433,26 +438,25 @@ void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions a

void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
var ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".il";
var csFile = Path.Combine(TestCasePath, testName + ".cs");
var exeFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".exe";
if (cscOptions.HasFlag(CompilerOptions.Library)) {
exeFile = Path.ChangeExtension(exeFile, ".dll");
}

if (!File.Exists(ilFile)) {
// re-create .il file if necessary
CompilerResults output = null;
try {
string outputFile = Path.ChangeExtension(ilFile,
cscOptions.HasFlag(CompilerOptions.Library) ? ".dll" : ".exe");
output = Tester.CompileCSharp(csFile, cscOptions, outputFile);
Tester.Disassemble(output.PathToAssembly, ilFile, asmOptions);
} finally {
if (output != null)
output.TempFiles.Delete();
}
// 1. Compile
CompilerResults output = null;
try {
output = Tester.CompileCSharp(csFile, cscOptions, exeFile);
} finally {
if (output != null)
output.TempFiles.Delete();
}

var executable = Tester.AssembleIL(ilFile, asmOptions);
var decompiled = Tester.DecompileCSharp(executable, decompilerSettings ?? Tester.GetSettings(cscOptions));
// 2. Decompile
var decompiled = Tester.DecompileCSharp(exeFile, decompilerSettings ?? Tester.GetSettings(cscOptions));

// 3. Compile
CodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).ToArray());
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// C:\Users\Siegfried\Documents\Visual Studio 2017\Projects\ConsoleApp13\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe
// ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// Global type: <Module>
Expand Down Expand Up @@ -170,10 +169,10 @@ public static int main(string[] argv)
}
namespace _003CStartupCode_0024ConsoleApplication1_003E
{
internal static class _0024Program
internal static class _0024AssemblyInfo
{
}
internal static class _0024AssemblyInfo
internal static class _0024Program
{
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ public static int main(string[] argv)
}
namespace _003CStartupCode_0024ConsoleApplication1_003E
{
internal static class _0024Program
internal static class _0024AssemblyInfo
{
}
internal static class _0024AssemblyInfo
internal static class _0024Program
{
}
}
Expand Down
47 changes: 23 additions & 24 deletions ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1325.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,7 @@
[assembly: TargetFramework(".NETCoreApp,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
namespace Microsoft.VisualBasic
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class, Inherited = false)]
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[Embedded]
internal sealed class Embedded : Attribute
{
}
}

namespace Issue1325
{
[StandardModule]
Expand All @@ -40,19 +31,7 @@ public static void TestCode(Test t, int i)
t.Unparameterized = str + "asdf";
}
}
}
namespace Microsoft.VisualBasic.CompilerServices
{
[EditorBrowsable(EditorBrowsableState.Never)]
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
[CompilerGenerated]
[Embedded]
internal sealed class StandardModuleAttribute : Attribute
{
}
}
namespace Issue1325
{

internal class Test
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Expand All @@ -71,4 +50,24 @@ public string Unparameterized {
set;
}
}
}
}
namespace Microsoft.VisualBasic
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class, Inherited = false)]
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[Embedded]
internal sealed class Embedded : Attribute
{
}
}
namespace Microsoft.VisualBasic.CompilerServices
{
[EditorBrowsable(EditorBrowsableState.Never)]
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
[CompilerGenerated]
[Embedded]
internal sealed class StandardModuleAttribute : Attribute
{
}
}
Loading