Browse Source

Added support for ConditionalAttribute

pull/728/merge
Siegfried Pammer 9 years ago
parent
commit
d8a2d41e83
  1. 23
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 4
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs
  3. 6
      ICSharpCode.Decompiler/Tests/CorrectnessTestRunner.cs
  4. 1
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  5. 26
      ICSharpCode.Decompiler/Tests/TestCases/Correctness/ConditionalAttr.cs

23
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -44,6 +44,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -44,6 +44,7 @@ namespace ICSharpCode.Decompiler.CSharp
{
readonly DecompilerTypeSystem typeSystem;
readonly DecompilerSettings settings;
private SyntaxTree syntaxTree;
List<IILTransform> ilTransforms = GetILTransforms();
@ -229,7 +230,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -229,7 +230,7 @@ namespace ICSharpCode.Decompiler.CSharp
public SyntaxTree DecompileModuleAndAssemblyAttributes()
{
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly);
SyntaxTree syntaxTree = new SyntaxTree();
syntaxTree = new SyntaxTree();
DoDecompileModuleAndAssemblyAttributes(decompilationContext, syntaxTree);
RunTransforms(syntaxTree, decompilationContext);
return syntaxTree;
@ -275,7 +276,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -275,7 +276,7 @@ namespace ICSharpCode.Decompiler.CSharp
public SyntaxTree DecompileWholeModuleAsSingleFile()
{
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly);
SyntaxTree syntaxTree = new SyntaxTree();
syntaxTree = new SyntaxTree();
DoDecompileModuleAndAssemblyAttributes(decompilationContext, syntaxTree);
DoDecompileTypes(typeSystem.ModuleDefinition.Types, decompilationContext, syntaxTree);
RunTransforms(syntaxTree, decompilationContext);
@ -293,7 +294,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -293,7 +294,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (types == null)
throw new ArgumentNullException(nameof(types));
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly);
SyntaxTree syntaxTree = new SyntaxTree();
syntaxTree = new SyntaxTree();
DoDecompileTypes(types, decompilationContext, syntaxTree);
RunTransforms(syntaxTree, decompilationContext);
return syntaxTree;
@ -307,7 +308,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -307,7 +308,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (definitions == null)
throw new ArgumentNullException(nameof(definitions));
ITypeDefinition parentTypeDef = null;
var syntaxTree = new SyntaxTree();
syntaxTree = new SyntaxTree();
foreach (var def in definitions) {
if (def == null)
throw new ArgumentException("definitions contains null element");
@ -594,11 +595,23 @@ namespace ICSharpCode.Decompiler.CSharp @@ -594,11 +595,23 @@ namespace ICSharpCode.Decompiler.CSharp
transform.Run(function, context);
function.CheckInvariant(ILPhase.Normal);
}
AddDefinesForConditionalAttributes(function);
var statementBuilder = new StatementBuilder(specializingTypeSystem, decompilationContext, method);
entityDecl.AddChild(statementBuilder.ConvertAsBlock(function.Body), Roles.Body);
}
void AddDefinesForConditionalAttributes(ILFunction function)
{
foreach (var call in function.Descendants.OfType<CallInstruction>()) {
var attr = call.Method.GetAttribute(new TopLevelTypeName("System.Diagnostics", nameof(ConditionalAttribute)));
var symbolName = attr?.PositionalArguments.FirstOrDefault()?.ConstantValue as string;
if (symbolName == null)
continue;
syntaxTree.InsertChildAfter(null, new PreProcessorDirective(PreProcessorDirectiveType.Define, symbolName), Roles.PreProcessorDirective);
}
}
EntityDeclaration DoDecompile(FieldDefinition fieldDefinition, IField field, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == field);

4
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs

@ -43,6 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -43,6 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
requiredImports.ImportedNamespaces.Add("System"); // always import System, even when not necessary
var usingScope = new UsingScope();
var insertionPoint = compilationUnit.Children.LastOrDefault(n => n is PreProcessorDirective p && p.Type == PreProcessorDirectiveType.Define);
// Now add using declarations for those namespaces:
foreach (string ns in requiredImports.ImportedNamespaces.OrderByDescending(n => n)) {
@ -58,7 +60,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -58,7 +60,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (reference != null)
usingScope.Usings.Add(reference);
}
compilationUnit.InsertChildAfter(null, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);
compilationUnit.InsertChildAfter(insertionPoint, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);
}
if (!FullyQualifyAmbiguousTypeNames)

6
ICSharpCode.Decompiler/Tests/CorrectnessTestRunner.cs

@ -145,6 +145,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -145,6 +145,12 @@ namespace ICSharpCode.Decompiler.Tests
RunCS(options: options);
}
[Test]
public void ConditionalAttr([ValueSource("defaultOptions")] CompilerOptions options)
{
RunCS(options: options);
}
void RunCS([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug)
{
string testFileName = testName + ".cs";

1
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -128,6 +128,7 @@ @@ -128,6 +128,7 @@
<Compile Include="PrettyTestRunner.cs" />
<Compile Include="RoundtripAssembly.cs" />
<Compile Include="TestCases\Correctness\CompoundAssignment.cs" />
<Compile Include="TestCases\Correctness\ConditionalAttr.cs" />
<Compile Include="TestCases\Correctness\ControlFlow.cs" />
<Compile Include="TestCases\Correctness\Conversions.cs" />
<Compile Include="TestCases\Correctness\DecimalFields.cs" />

26
ICSharpCode.Decompiler/Tests/TestCases/Correctness/ConditionalAttr.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
#define PRINT
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
class ConditionalAttr
{
[Conditional("PRINT")]
static void Print()
{
Console.WriteLine("Text!");
}
static void Main()
{
Print();
}
}
}
Loading…
Cancel
Save