Browse Source

Re-enable IntroduceUsingDeclarations

pull/728/head
Daniel Grunwald 11 years ago
parent
commit
08a5e81517
  1. 80
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 13
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 8
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  4. 4
      ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs
  5. 43
      ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
  6. 2
      ICSharpCode.Decompiler/CSharp/Transforms/IAstTransform.cs
  7. 2
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs
  8. 67
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs
  9. 2
      ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs
  10. 53
      ICSharpCode.Decompiler/CSharp/Transforms/TransformContext.cs
  11. 2
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs
  12. 30
      ICSharpCode.Decompiler/DecompilerTypeSystem.cs
  13. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  14. 2
      ICSharpCode.Decompiler/IL/BlockBuilder.cs
  15. 10
      ICSharpCode.Decompiler/IL/ILReader.cs
  16. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs
  17. 34
      NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

80
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -18,6 +18,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -36,8 +37,22 @@ namespace ICSharpCode.Decompiler.CSharp
public class CSharpDecompiler public class CSharpDecompiler
{ {
readonly DecompilerTypeSystem typeSystem; readonly DecompilerTypeSystem typeSystem;
TypeSystemAstBuilder typeSystemAstBuilder; List<IAstTransform> astTransforms = new List<IAstTransform> {
List<IAstTransform> astTransforms; //new PushNegation(),
//new DelegateConstruction(context),
//new PatternStatementTransform(context),
new ReplaceMethodCallsWithOperators(),
new IntroduceUnsafeModifier(),
new AddCheckedBlocks(),
//new DeclareVariables(context), // should run after most transforms that modify statements
new ConvertConstructorCallIntoInitializer(), // must run after DeclareVariables
//new DecimalConstantTransform(),
new IntroduceUsingDeclarations(),
//new IntroduceExtensionMethods(context), // must run after IntroduceUsingDeclarations
//new IntroduceQueryExpressions(context), // must run after IntroduceExtensionMethods
//new CombineQueryExpressions(context),
//new FlattenSwitchBlocks(),
};
public CancellationToken CancellationToken { get; set; } public CancellationToken CancellationToken { get; set; }
@ -58,38 +73,27 @@ namespace ICSharpCode.Decompiler.CSharp
if (typeSystem == null) if (typeSystem == null)
throw new ArgumentNullException("typeSystem"); throw new ArgumentNullException("typeSystem");
this.typeSystem = typeSystem; this.typeSystem = typeSystem;
}
astTransforms = new List<IAstTransform> { TypeSystemAstBuilder CreateAstBuilder(ITypeResolveContext decompilationContext)
//new PushNegation(), {
//new DelegateConstruction(context), var typeSystemAstBuilder = new TypeSystemAstBuilder();
//new PatternStatementTransform(context),
new ReplaceMethodCallsWithOperators(),
new IntroduceUnsafeModifier(),
new AddCheckedBlocks(),
//new DeclareVariables(context), // should run after most transforms that modify statements
new ConvertConstructorCallIntoInitializer(typeSystem), // must run after DeclareVariables
//new DecimalConstantTransform(),
//new IntroduceUsingDeclarations(context),
//new IntroduceExtensionMethods(context), // must run after IntroduceUsingDeclarations
//new IntroduceQueryExpressions(context), // must run after IntroduceExtensionMethods
//new CombineQueryExpressions(context),
//new FlattenSwitchBlocks(),
};
typeSystemAstBuilder = new TypeSystemAstBuilder();
typeSystemAstBuilder.AlwaysUseShortTypeNames = true; typeSystemAstBuilder.AlwaysUseShortTypeNames = true;
typeSystemAstBuilder.AddAnnotations = true; typeSystemAstBuilder.AddResolveResultAnnotations = true;
return typeSystemAstBuilder;
} }
void RunTransforms(AstNode rootNode) void RunTransforms(AstNode rootNode, ITypeResolveContext decompilationContext)
{ {
var context = new TransformContext(typeSystem, decompilationContext);
foreach (var transform in astTransforms) foreach (var transform in astTransforms)
transform.Run(rootNode); transform.Run(rootNode, context);
rootNode.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); rootNode.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
} }
public SyntaxTree DecompileWholeModuleAsSingleFile() public SyntaxTree DecompileWholeModuleAsSingleFile()
{ {
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly);
SyntaxTree syntaxTree = new SyntaxTree(); SyntaxTree syntaxTree = new SyntaxTree();
foreach (var g in typeSystem.Compilation.MainAssembly.TopLevelTypeDefinitions.GroupBy(t => t.Namespace)) { foreach (var g in typeSystem.Compilation.MainAssembly.TopLevelTypeDefinitions.GroupBy(t => t.Namespace)) {
AstNode groupNode; AstNode groupNode;
@ -104,11 +108,11 @@ namespace ICSharpCode.Decompiler.CSharp
foreach (var typeDef in g) { foreach (var typeDef in g) {
if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0) if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0)
continue; continue;
var typeDecl = DoDecompile(typeDef); var typeDecl = DoDecompile(typeDef, decompilationContext.WithCurrentTypeDefinition(typeDef));
groupNode.AddChild(typeDecl, SyntaxTree.MemberRole); groupNode.AddChild(typeDecl, SyntaxTree.MemberRole);
} }
} }
RunTransforms(syntaxTree); RunTransforms(syntaxTree, decompilationContext);
return syntaxTree; return syntaxTree;
} }
@ -116,16 +120,19 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
if (typeDefinition == null) if (typeDefinition == null)
throw new ArgumentNullException("typeDefinition"); throw new ArgumentNullException("typeDefinition");
ITypeDefinition typeDef = typeSystem.GetType(typeDefinition).GetDefinition(); ITypeDefinition typeDef = typeSystem.Resolve(typeDefinition).GetDefinition();
if (typeDef == null) if (typeDef == null)
throw new InvalidOperationException("Could not find type definition in NR type system"); throw new InvalidOperationException("Could not find type definition in NR type system");
var decl = DoDecompile(typeDef); var decompilationContext = new SimpleTypeResolveContext(typeDef);
RunTransforms(decl); var decl = DoDecompile(typeDef, decompilationContext);
RunTransforms(decl, decompilationContext);
return decl; return decl;
} }
EntityDeclaration DoDecompile(ITypeDefinition typeDef) EntityDeclaration DoDecompile(ITypeDefinition typeDef, ITypeResolveContext decompilationContext)
{ {
Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef);
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
var entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef); var entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef);
var typeDecl = entityDecl as TypeDeclaration; var typeDecl = entityDecl as TypeDeclaration;
if (typeDecl == null) { if (typeDecl == null) {
@ -135,7 +142,7 @@ namespace ICSharpCode.Decompiler.CSharp
foreach (var method in typeDef.Methods) { foreach (var method in typeDef.Methods) {
var methodDef = typeSystem.GetCecil(method) as MethodDefinition; var methodDef = typeSystem.GetCecil(method) as MethodDefinition;
if (methodDef != null) { if (methodDef != null) {
var memberDecl = DoDecompile(methodDef, method); var memberDecl = DoDecompile(methodDef, method, decompilationContext.WithCurrentMember(method));
typeDecl.Members.Add(memberDecl); typeDecl.Members.Add(memberDecl);
} }
} }
@ -146,16 +153,19 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
if (methodDefinition == null) if (methodDefinition == null)
throw new ArgumentNullException("methodDefinition"); throw new ArgumentNullException("methodDefinition");
var method = typeSystem.GetMethod(methodDefinition); var method = typeSystem.Resolve(methodDefinition);
if (method == null) if (method == null)
throw new InvalidOperationException("Could not find method in NR type system"); throw new InvalidOperationException("Could not find method in NR type system");
var decl = DoDecompile(methodDefinition, method); var decompilationContext = new SimpleTypeResolveContext(method);
RunTransforms(decl); var decl = DoDecompile(methodDefinition, method, decompilationContext);
RunTransforms(decl, decompilationContext);
return decl; return decl;
} }
EntityDeclaration DoDecompile(MethodDefinition methodDefinition, IMethod method) EntityDeclaration DoDecompile(MethodDefinition methodDefinition, IMethod method, ITypeResolveContext decompilationContext)
{ {
Debug.Assert(decompilationContext.CurrentMember == method);
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
var entityDecl = typeSystemAstBuilder.ConvertEntity(method); var entityDecl = typeSystemAstBuilder.ConvertEntity(method);
if (methodDefinition.HasBody) { if (methodDefinition.HasBody) {
var ilReader = new ILReader(typeSystem); var ilReader = new ILReader(typeSystem);
@ -163,7 +173,7 @@ namespace ICSharpCode.Decompiler.CSharp
function.CheckInvariant(); function.CheckInvariant();
function.Body = function.Body.AcceptVisitor(new TransformingVisitor()); function.Body = function.Body.AcceptVisitor(new TransformingVisitor());
function.CheckInvariant(); function.CheckInvariant();
var statementBuilder = new StatementBuilder(method); var statementBuilder = new StatementBuilder(decompilationContext);
var body = statementBuilder.ConvertAsBlock(function.Body); var body = statementBuilder.ConvertAsBlock(function.Body);
// insert variables at start of body // insert variables at start of body

13
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Diagnostics; using System.Diagnostics;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ExpressionType = System.Linq.Expressions.ExpressionType; using ExpressionType = System.Linq.Expressions.ExpressionType;
using ICSharpCode.NRefactory.CSharp.Refactoring; using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.Resolver;
@ -41,12 +42,14 @@ namespace ICSharpCode.Decompiler.CSharp
internal readonly CSharpResolver resolver; internal readonly CSharpResolver resolver;
internal readonly TypeSystemAstBuilder astBuilder; internal readonly TypeSystemAstBuilder astBuilder;
public ExpressionBuilder(ICompilation compilation) public ExpressionBuilder(ITypeResolveContext decompilationContext)
{ {
Debug.Assert(compilation != null); Debug.Assert(decompilationContext != null);
this.compilation = compilation; this.compilation = decompilationContext.Compilation;
this.resolver = new CSharpResolver(compilation); this.resolver = new CSharpResolver(new CSharpTypeResolveContext(compilation.MainAssembly, null, decompilationContext.CurrentTypeDefinition, decompilationContext.CurrentMember));
this.astBuilder = new TypeSystemAstBuilder(resolver); this.astBuilder = new TypeSystemAstBuilder(resolver);
this.astBuilder.AlwaysUseShortTypeNames = true;
this.astBuilder.AddResolveResultAnnotations = true;
} }
public AstType ConvertType(IType type) public AstType ConvertType(IType type)
@ -145,7 +148,7 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
return new NullReferenceExpression() return new NullReferenceExpression()
.WithILInstruction(inst) .WithILInstruction(inst)
.WithRR(new ConstantResolveResult(SpecialType.UnknownType, null)); .WithRR(new ConstantResolveResult(SpecialType.NullType, null));
} }
protected internal override TranslatedExpression VisitLogicNot(LogicNot inst) protected internal override TranslatedExpression VisitLogicNot(LogicNot inst)

8
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Diagnostics;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
@ -32,10 +33,11 @@ namespace ICSharpCode.Decompiler.CSharp
readonly ExpressionBuilder exprBuilder; readonly ExpressionBuilder exprBuilder;
readonly IMethod currentMethod; readonly IMethod currentMethod;
public StatementBuilder(IMethod method) public StatementBuilder(ITypeResolveContext decompilationContext)
{ {
this.exprBuilder = new ExpressionBuilder(method.Compilation); Debug.Assert(decompilationContext != null && decompilationContext.CurrentMember is IMethod);
this.currentMethod = method; this.exprBuilder = new ExpressionBuilder(decompilationContext);
this.currentMethod = (IMethod)decompilationContext.CurrentMember;
} }
public Statement Convert(ILInstruction inst) public Statement Convert(ILInstruction inst)

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

@ -234,12 +234,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
#endregion #endregion
public void Run(AstNode node) public void Run(AstNode node, TransformContext context)
{ {
BlockStatement block = node as BlockStatement; BlockStatement block = node as BlockStatement;
if (block == null) { if (block == null) {
for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) { for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) {
Run(child); Run(child, context);
} }
} else { } else {
Result r = GetResultFromBlock(block); Result r = GetResultFromBlock(block);

43
ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs

@ -18,6 +18,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
@ -30,15 +31,29 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
/// <summary> /// <summary>
/// If the first element of a constructor is a chained constructor call, convert it into a constructor initializer. /// If the first element of a constructor is a chained constructor call, convert it into a constructor initializer.
/// </summary> /// </summary>
public class ConvertConstructorCallIntoInitializer : DepthFirstAstVisitor, IAstTransform public class ConvertConstructorCallIntoInitializer : IAstTransform
{ {
readonly DecompilerTypeSystem typeSystem; public void Run(AstNode node, TransformContext context)
{
var visitor = new ConvertConstructorCallIntoInitializerVisitor(context);
// If we're viewing some set of members (fields are direct children of SyntaxTree),
// we also need to handle those:
visitor.HandleInstanceFieldInitializers(node.Children);
visitor.HandleStaticFieldInitializers(node.Children);
public ConvertConstructorCallIntoInitializer(DecompilerTypeSystem typeSystem) node.AcceptVisitor(visitor);
}
}
sealed class ConvertConstructorCallIntoInitializerVisitor : DepthFirstAstVisitor
{ {
if (typeSystem == null) readonly TransformContext context;
throw new ArgumentNullException("typeSystem");
this.typeSystem = typeSystem; public ConvertConstructorCallIntoInitializerVisitor(TransformContext context)
{
Debug.Assert(context != null);
this.context = context;
} }
public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
@ -96,7 +111,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
HandleStaticFieldInitializers(typeDeclaration.Members); HandleStaticFieldInitializers(typeDeclaration.Members);
} }
void HandleInstanceFieldInitializers(IEnumerable<AstNode> members) internal void HandleInstanceFieldInitializers(IEnumerable<AstNode> members)
{ {
var instanceCtors = members.OfType<ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); var instanceCtors = members.OfType<ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray();
var instanceCtorsNotChainingWithThis = instanceCtors.Where(ctor => !thisCallPattern.IsMatch(ctor.Body.Statements.FirstOrDefault())).ToArray(); var instanceCtorsNotChainingWithThis = instanceCtors.Where(ctor => !thisCallPattern.IsMatch(ctor.Body.Statements.FirstOrDefault())).ToArray();
@ -150,13 +165,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
} }
void HandleStaticFieldInitializers(IEnumerable<AstNode> members) internal void HandleStaticFieldInitializers(IEnumerable<AstNode> members)
{ {
// Translate static constructor into field initializers if the class is BeforeFieldInit // Translate static constructor into field initializers if the class is BeforeFieldInit
var staticCtor = members.OfType<ConstructorDeclaration>().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static); var staticCtor = members.OfType<ConstructorDeclaration>().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static);
if (staticCtor != null) { if (staticCtor != null) {
IMethod ctorMethod = staticCtor.GetSymbol() as IMethod; IMethod ctorMethod = staticCtor.GetSymbol() as IMethod;
MethodDefinition ctorMethodDef = typeSystem.GetCecil(ctorMethod) as MethodDefinition; MethodDefinition ctorMethodDef = context.TypeSystem.GetCecil(ctorMethod) as MethodDefinition;
if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsBeforeFieldInit) { if (ctorMethodDef != null && ctorMethodDef.DeclaringType.IsBeforeFieldInit) {
while (true) { while (true) {
ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement; ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement;
@ -179,15 +194,5 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
} }
} }
public void Run(AstNode node)
{
// If we're viewing some set of members (fields are direct children of CompilationUnit),
// we also need to handle those:
HandleInstanceFieldInitializers(node.Children);
HandleStaticFieldInitializers(node.Children);
node.AcceptVisitor(this);
}
} }
} }

2
ICSharpCode.Decompiler/CSharp/Transforms/IAstTransform.cs

@ -25,6 +25,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
public interface IAstTransform public interface IAstTransform
{ {
void Run(AstNode rootNode); void Run(AstNode rootNode, TransformContext context);
} }
} }

2
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs

@ -27,7 +27,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
sealed class PointerArithmetic {} sealed class PointerArithmetic {}
public void Run(AstNode compilationUnit) public void Run(AstNode compilationUnit, TransformContext context)
{ {
compilationUnit.AcceptVisitor(this); compilationUnit.AcceptVisitor(this);
} }

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

@ -20,7 +20,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil; using ICSharpCode.NRefactory.Semantics;
namespace ICSharpCode.Decompiler.CSharp.Transforms namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
@ -29,25 +29,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
/// </summary> /// </summary>
public class IntroduceUsingDeclarations : IAstTransform public class IntroduceUsingDeclarations : IAstTransform
{ {
DecompilerContext context; public bool FullyQualifyAmbiguousTypeNames = true;
public IntroduceUsingDeclarations(DecompilerContext context) public void Run(AstNode compilationUnit, TransformContext context)
{ {
this.context = context;
}
public void Run(AstNode compilationUnit)
{
if (!context.Settings.UsingDeclarations)
return;
// First determine all the namespaces that need to be imported: // First determine all the namespaces that need to be imported:
compilationUnit.AcceptVisitor(new FindRequiredImports(this), null); var requiredImports = new FindRequiredImports(context);
compilationUnit.AcceptVisitor(requiredImports);
importedNamespaces.Add("System"); // always import System, even when not necessary requiredImports.ImportedNamespaces.Add("System"); // always import System, even when not necessary
// Now add using declarations for those namespaces: // Now add using declarations for those namespaces:
foreach (string ns in importedNamespaces.OrderByDescending(n => n)) { foreach (string ns in requiredImports.ImportedNamespaces.OrderByDescending(n => n)) {
// we go backwards (OrderByDescending) through the list of namespaces because we insert them backwards // we go backwards (OrderByDescending) through the list of namespaces because we insert them backwards
// (always inserting at the start of the list) // (always inserting at the start of the list)
string[] parts = ns.Split('.'); string[] parts = ns.Split('.');
@ -58,9 +51,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
compilationUnit.InsertChildAfter(null, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole); compilationUnit.InsertChildAfter(null, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);
} }
if (!context.Settings.FullyQualifyAmbiguousTypeNames) if (!FullyQualifyAmbiguousTypeNames)
return; return;
/*
FindAmbiguousTypeNames(context.CurrentModule, internalsVisible: true); FindAmbiguousTypeNames(context.CurrentModule, internalsVisible: true);
foreach (AssemblyNameReference r in context.CurrentModule.AssemblyReferences) { foreach (AssemblyNameReference r in context.CurrentModule.AssemblyReferences) {
AssemblyDefinition d = context.CurrentModule.AssemblyResolver.Resolve(r); AssemblyDefinition d = context.CurrentModule.AssemblyResolver.Resolve(r);
@ -69,25 +63,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
// verify that the SimpleTypes refer to the correct type (no ambiguities) // verify that the SimpleTypes refer to the correct type (no ambiguities)
compilationUnit.AcceptVisitor(new FullyQualifyAmbiguousTypeNamesVisitor(this), null); compilationUnit.AcceptVisitor(new FullyQualifyAmbiguousTypeNamesVisitor(this), null);*/
} }
readonly HashSet<string> declaredNamespaces = new HashSet<string>() { string.Empty };
readonly HashSet<string> importedNamespaces = new HashSet<string>();
// Note that we store type names with `n suffix, so we automatically disambiguate based on number of type parameters. // Note that we store type names with `n suffix, so we automatically disambiguate based on number of type parameters.
readonly HashSet<string> availableTypeNames = new HashSet<string>(); //readonly HashSet<string> availableTypeNames = new HashSet<string>();
readonly HashSet<string> ambiguousTypeNames = new HashSet<string>(); //readonly HashSet<string> ambiguousTypeNames = new HashSet<string>();
sealed class FindRequiredImports : DepthFirstAstVisitor<object, object> sealed class FindRequiredImports : DepthFirstAstVisitor
{ {
readonly IntroduceUsingDeclarations transform;
string currentNamespace; string currentNamespace;
public FindRequiredImports(IntroduceUsingDeclarations transform) public readonly HashSet<string> DeclaredNamespaces = new HashSet<string>() { string.Empty };
public readonly HashSet<string> ImportedNamespaces = new HashSet<string>();
public FindRequiredImports(TransformContext context)
{ {
this.transform = transform; this.currentNamespace = context.DecompiledTypeDefinition != null ? context.DecompiledTypeDefinition.Namespace : string.Empty;
this.currentNamespace = transform.context.CurrentType != null ? transform.context.CurrentType.Namespace : string.Empty;
} }
bool IsParentOfCurrentNamespace(string ns) bool IsParentOfCurrentNamespace(string ns)
@ -103,28 +96,28 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return false; return false;
} }
public override object VisitSimpleType(SimpleType simpleType, object data) public override void VisitSimpleType(SimpleType simpleType)
{ {
TypeReference tr = simpleType.Annotation<TypeReference>(); var trr = simpleType.Annotation<TypeResolveResult>();
if (tr != null && !IsParentOfCurrentNamespace(tr.Namespace)) { if (trr != null && !IsParentOfCurrentNamespace(trr.Type.Namespace)) {
transform.importedNamespaces.Add(tr.Namespace); ImportedNamespaces.Add(trr.Type.Namespace);
} }
return base.VisitSimpleType(simpleType, data); // also visit type arguments base.VisitSimpleType(simpleType); // also visit type arguments
} }
public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
{ {
string oldNamespace = currentNamespace; string oldNamespace = currentNamespace;
foreach (Identifier ident in namespaceDeclaration.Identifiers) { foreach (string ident in namespaceDeclaration.Identifiers) {
currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident.Name); currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident);
transform.declaredNamespaces.Add(currentNamespace); DeclaredNamespaces.Add(currentNamespace);
} }
base.VisitNamespaceDeclaration(namespaceDeclaration, data); base.VisitNamespaceDeclaration(namespaceDeclaration);
currentNamespace = oldNamespace; currentNamespace = oldNamespace;
return null;
} }
} }
/*
void FindAmbiguousTypeNames(ModuleDefinition module, bool internalsVisible) void FindAmbiguousTypeNames(ModuleDefinition module, bool internalsVisible)
{ {
foreach (TypeDefinition type in module.Types) { foreach (TypeDefinition type in module.Types) {
@ -355,6 +348,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return false; return false;
return transform.ambiguousTypeNames.Contains(name); return transform.ambiguousTypeNames.Contains(name);
} }
} }*/
} }
} }

2
ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

@ -345,7 +345,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
} }
void IAstTransform.Run(AstNode node) void IAstTransform.Run(AstNode node, TransformContext context)
{ {
node.AcceptVisitor(this); node.AcceptVisitor(this);
} }

53
ICSharpCode.Decompiler/CSharp/Transforms/TransformContext.cs

@ -0,0 +1,53 @@
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Transforms
{
/// <summary>
/// Parameters for IAstTransform.
/// </summary>
public class TransformContext
{
public readonly DecompilerTypeSystem TypeSystem;
readonly ITypeResolveContext decompilationContext;
/// <summary>
/// Returns the member that is being decompiled; or null if a whole type or assembly is being decompiled.
/// </summary>
public IMember DecompiledMember {
get { return decompilationContext.CurrentMember; }
}
/// <summary>
/// Returns the type definition that is being decompiled; or null if an assembly is being decompiled.
/// </summary>
public ITypeDefinition DecompiledTypeDefinition {
get { return decompilationContext.CurrentTypeDefinition; }
}
internal TransformContext(DecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext)
{
this.TypeSystem = typeSystem;
this.decompilationContext = decompilationContext;
}
}
}

2
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -194,7 +194,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else if (Type.Kind == TypeKind.Pointer) { } else if (Type.Kind == TypeKind.Pointer) {
var nullRef = new NullReferenceExpression() var nullRef = new NullReferenceExpression()
.WithoutILInstruction() .WithoutILInstruction()
.WithRR(new ConstantResolveResult(this.Type, null)); .WithRR(new ConstantResolveResult(SpecialType.NullType, null));
return new BinaryOperatorExpression(Expression, BinaryOperatorType.InEquality, nullRef.Expression) return new BinaryOperatorExpression(Expression, BinaryOperatorType.InEquality, nullRef.Expression)
.WithoutILInstruction() .WithoutILInstruction()
.WithRR(new OperatorResolveResult(boolType, System.Linq.Expressions.ExpressionType.NotEqual, .WithRR(new OperatorResolveResult(boolType, System.Linq.Expressions.ExpressionType.NotEqual,

30
ICSharpCode.Decompiler/DecompilerTypeSystem.cs

@ -56,13 +56,15 @@ namespace ICSharpCode.Decompiler
context = new SimpleTypeResolveContext(compilation.MainAssembly); context = new SimpleTypeResolveContext(compilation.MainAssembly);
} }
public ICompilation Compilation public ICompilation Compilation {
{
get { return compilation; } get { return compilation; }
} }
public ModuleDefinition ModuleDefinition public IAssembly MainAssembly {
{ get { return compilation.MainAssembly; }
}
public ModuleDefinition ModuleDefinition {
get { return moduleDefinition; } get { return moduleDefinition; }
} }
@ -113,7 +115,7 @@ namespace ICSharpCode.Decompiler
/// <summary> /// <summary>
/// Retrieves a type definition for a type defined in the compilation's main assembly. /// Retrieves a type definition for a type defined in the compilation's main assembly.
/// </summary> /// </summary>
public IType GetType(TypeReference typeReference) public IType Resolve(TypeReference typeReference)
{ {
if (typeReference == null) if (typeReference == null)
return SpecialType.UnknownType; return SpecialType.UnknownType;
@ -125,7 +127,7 @@ namespace ICSharpCode.Decompiler
#endregion #endregion
#region Resolve Field #region Resolve Field
public IField GetField(FieldReference fieldReference) public IField Resolve(FieldReference fieldReference)
{ {
if (fieldReference == null) if (fieldReference == null)
throw new ArgumentNullException("fieldReference"); throw new ArgumentNullException("fieldReference");
@ -135,7 +137,7 @@ namespace ICSharpCode.Decompiler
field = FindNonGenericField(fieldReference); field = FindNonGenericField(fieldReference);
if (fieldReference.DeclaringType.IsGenericInstance) { if (fieldReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)fieldReference.DeclaringType; var git = (GenericInstanceType)fieldReference.DeclaringType;
var typeArguments = git.GenericArguments.SelectArray(GetType); var typeArguments = git.GenericArguments.SelectArray(Resolve);
field = (IField)field.Specialize(new TypeParameterSubstitution(typeArguments, null)); field = (IField)field.Specialize(new TypeParameterSubstitution(typeArguments, null));
} }
fieldLookupCache.Add(fieldReference, field); fieldLookupCache.Add(fieldReference, field);
@ -146,7 +148,7 @@ namespace ICSharpCode.Decompiler
IField FindNonGenericField(FieldReference fieldReference) IField FindNonGenericField(FieldReference fieldReference)
{ {
ITypeDefinition typeDef = GetType(fieldReference.DeclaringType).GetDefinition(); ITypeDefinition typeDef = Resolve(fieldReference.DeclaringType).GetDefinition();
if (typeDef == null) if (typeDef == null)
return CreateFakeField(fieldReference); return CreateFakeField(fieldReference);
foreach (IField field in typeDef.Fields) foreach (IField field in typeDef.Fields)
@ -157,7 +159,7 @@ namespace ICSharpCode.Decompiler
IField CreateFakeField(FieldReference fieldReference) IField CreateFakeField(FieldReference fieldReference)
{ {
var declaringType = GetType(fieldReference.DeclaringType); var declaringType = Resolve(fieldReference.DeclaringType);
var f = new DefaultUnresolvedField(); var f = new DefaultUnresolvedField();
f.Name = fieldReference.Name; f.Name = fieldReference.Name;
f.ReturnType = typeReferenceCecilLoader.ReadTypeReference(fieldReference.FieldType); f.ReturnType = typeReferenceCecilLoader.ReadTypeReference(fieldReference.FieldType);
@ -182,7 +184,7 @@ namespace ICSharpCode.Decompiler
#endregion #endregion
#region Resolve Method #region Resolve Method
public IMethod GetMethod(MethodReference methodReference) public IMethod Resolve(MethodReference methodReference)
{ {
if (methodReference == null) if (methodReference == null)
throw new ArgumentNullException("methodReference"); throw new ArgumentNullException("methodReference");
@ -195,11 +197,11 @@ namespace ICSharpCode.Decompiler
IList<IType> methodTypeArguments = null; IList<IType> methodTypeArguments = null;
if (methodReference.IsGenericInstance) { if (methodReference.IsGenericInstance) {
var gim = ((GenericInstanceMethod)methodReference); var gim = ((GenericInstanceMethod)methodReference);
methodTypeArguments = gim.GenericArguments.SelectArray(GetType); methodTypeArguments = gim.GenericArguments.SelectArray(Resolve);
} }
if (methodReference.DeclaringType.IsGenericInstance) { if (methodReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)methodReference.DeclaringType; var git = (GenericInstanceType)methodReference.DeclaringType;
classTypeArguments = git.GenericArguments.SelectArray(GetType); classTypeArguments = git.GenericArguments.SelectArray(Resolve);
} }
method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments)); method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments));
} }
@ -211,7 +213,7 @@ namespace ICSharpCode.Decompiler
IMethod FindNonGenericMethod(MethodReference methodReference) IMethod FindNonGenericMethod(MethodReference methodReference)
{ {
ITypeDefinition typeDef = GetType(methodReference.DeclaringType).GetDefinition(); ITypeDefinition typeDef = Resolve(methodReference.DeclaringType).GetDefinition();
if (typeDef == null) if (typeDef == null)
return CreateFakeMethod(methodReference); return CreateFakeMethod(methodReference);
IEnumerable<IMethod> methods; IEnumerable<IMethod> methods;
@ -227,7 +229,7 @@ namespace ICSharpCode.Decompiler
if (GetCecil(method) == methodReference) if (GetCecil(method) == methodReference)
return method; return method;
} }
var parameterTypes = methodReference.Parameters.SelectArray(p => GetType(p.ParameterType)); var parameterTypes = methodReference.Parameters.SelectArray(p => Resolve(p.ParameterType));
foreach (var method in methods) { foreach (var method in methods) {
if (CompareSignatures(method.Parameters, parameterTypes)) if (CompareSignatures(method.Parameters, parameterTypes))
return method; return method;

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -63,6 +63,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CSharp\Annotations.cs" /> <Compile Include="CSharp\Annotations.cs" />
<Compile Include="CSharp\Transforms\IntroduceUsingDeclarations.cs" />
<Compile Include="CSharp\Transforms\TransformContext.cs" />
<Compile Include="CSharp\TranslatedExpression.cs" /> <Compile Include="CSharp\TranslatedExpression.cs" />
<Compile Include="CSharp\CSharpDecompiler.cs" /> <Compile Include="CSharp\CSharpDecompiler.cs" />
<Compile Include="CSharp\ExpressionBuilder.cs" /> <Compile Include="CSharp\ExpressionBuilder.cs" />

2
ICSharpCode.Decompiler/IL/BlockBuilder.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL
tryInstructionList.Add(tryCatch); tryInstructionList.Add(tryCatch);
} }
var variable = new ILVariable(VariableKind.Exception, typeSystem.GetType(eh.CatchType), handlerBlock.ILRange.Start); var variable = new ILVariable(VariableKind.Exception, typeSystem.Resolve(eh.CatchType), handlerBlock.ILRange.Start);
variable.Name = "ex"; variable.Name = "ex";
handlerBlock.EntryPoint.Instructions.Add(new LdLoc(variable)); handlerBlock.EntryPoint.Instructions.Add(new LdLoc(variable));

10
ICSharpCode.Decompiler/IL/ILReader.cs

@ -93,21 +93,21 @@ namespace ICSharpCode.Decompiler.IL
{ {
var token = ReadMetadataToken(ref reader); var token = ReadMetadataToken(ref reader);
var typeReference = body.LookupToken(token) as TypeReference; var typeReference = body.LookupToken(token) as TypeReference;
return typeSystem.GetType(typeReference); return typeSystem.Resolve(typeReference);
} }
IMethod ReadAndDecodeMethodReference() IMethod ReadAndDecodeMethodReference()
{ {
var token = ReadMetadataToken(ref reader); var token = ReadMetadataToken(ref reader);
var methodReference = body.LookupToken(token) as MethodReference; var methodReference = body.LookupToken(token) as MethodReference;
return typeSystem.GetMethod(methodReference); return typeSystem.Resolve(methodReference);
} }
IField ReadAndDecodeFieldReference() IField ReadAndDecodeFieldReference()
{ {
var token = ReadMetadataToken(ref reader); var token = ReadMetadataToken(ref reader);
var fieldReference = body.LookupToken(token) as FieldReference; var fieldReference = body.LookupToken(token) as FieldReference;
return typeSystem.GetField(fieldReference); return typeSystem.Resolve(fieldReference);
} }
void InitParameterVariables() void InitParameterVariables()
@ -123,7 +123,7 @@ namespace ICSharpCode.Decompiler.IL
ILVariable CreateILVariable(Cil.VariableDefinition v) ILVariable CreateILVariable(Cil.VariableDefinition v)
{ {
var ilVar = new ILVariable(VariableKind.Local, typeSystem.GetType(v.VariableType), v.Index); var ilVar = new ILVariable(VariableKind.Local, typeSystem.Resolve(v.VariableType), v.Index);
if (string.IsNullOrEmpty(v.Name)) if (string.IsNullOrEmpty(v.Name))
ilVar.Name = "V_" + v.Index; ilVar.Name = "V_" + v.Index;
else else
@ -134,7 +134,7 @@ namespace ICSharpCode.Decompiler.IL
ILVariable CreateILVariable(ParameterDefinition p) ILVariable CreateILVariable(ParameterDefinition p)
{ {
var variableKind = p.Index == -1 ? VariableKind.This : VariableKind.Parameter; var variableKind = p.Index == -1 ? VariableKind.This : VariableKind.Parameter;
var ilVar = new ILVariable(variableKind, typeSystem.GetType(p.ParameterType), p.Index); var ilVar = new ILVariable(variableKind, typeSystem.Resolve(p.ParameterType), p.Index);
ilVar.StoreCount = 1; // count the initial store when the method is called with an argument ilVar.StoreCount = 1; // count the initial store when the method is called with an argument
if (variableKind == VariableKind.This) if (variableKind == VariableKind.This)
ilVar.Name = "this"; ilVar.Name = "this";

2
NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs

@ -171,7 +171,7 @@ namespace ICSharpCode.NRefactory.CSharp
TypeSystemAstBuilder CreateAstBuilder() TypeSystemAstBuilder CreateAstBuilder()
{ {
TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(); TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder();
astBuilder.AddAnnotations = true; astBuilder.AddTypeReferenceAnnotations = true;
astBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers; astBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers;
astBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility; astBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility;
astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) != ConversionFlags.UseFullyQualifiedTypeNames; astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) != ConversionFlags.UseFullyQualifiedTypeNames;

34
NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

@ -77,7 +77,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// Specifies whether the ast builder should add annotations to type references. /// Specifies whether the ast builder should add annotations to type references.
/// The default value is <c>false</c>. /// The default value is <c>false</c>.
/// </summary> /// </summary>
public bool AddAnnotations { get; set; } public bool AddTypeReferenceAnnotations { get; set; }
/// <summary>
/// Specifies whether the ast builder should add ResolveResult annotations to AST nodes.
/// The default value is <c>false</c>.
/// </summary>
public bool AddResolveResultAnnotations { get; set; }
/// <summary> /// <summary>
/// Controls the accessibility modifiers are shown. /// Controls the accessibility modifiers are shown.
@ -159,8 +165,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (type == null) if (type == null)
throw new ArgumentNullException("type"); throw new ArgumentNullException("type");
AstType astType = ConvertTypeHelper(type); AstType astType = ConvertTypeHelper(type);
if (AddAnnotations) if (AddTypeReferenceAnnotations)
astType.AddAnnotation(type); astType.AddAnnotation(type);
if (AddResolveResultAnnotations)
astType.AddAnnotation(new TypeResolveResult(type));
return astType; return astType;
} }
@ -417,7 +425,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} }
if (rr is TypeOfResolveResult) { if (rr is TypeOfResolveResult) {
return new TypeOfExpression(ConvertType(rr.Type)); var expr = new TypeOfExpression(ConvertType(rr.Type));
if (AddResolveResultAnnotations)
expr.AddAnnotation(rr);
return expr;
} else if (rr is ArrayCreateResolveResult) { } else if (rr is ArrayCreateResolveResult) {
ArrayCreateResolveResult acrr = (ArrayCreateResolveResult)rr; ArrayCreateResolveResult acrr = (ArrayCreateResolveResult)rr;
ArrayCreateExpression ace = new ArrayCreateExpression(); ArrayCreateExpression ace = new ArrayCreateExpression();
@ -438,6 +449,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
initializer.Elements.AddRange(acrr.InitializerElements.Select(ConvertConstantValue)); initializer.Elements.AddRange(acrr.InitializerElements.Select(ConvertConstantValue));
ace.Initializer = initializer; ace.Initializer = initializer;
} }
if (AddResolveResultAnnotations)
ace.AddAnnotation(rr);
return ace; return ace;
} else if (rr.IsCompileTimeConstant) { } else if (rr.IsCompileTimeConstant) {
return ConvertConstantValue(rr.Type, rr.ConstantValue); return ConvertConstantValue(rr.Type, rr.ConstantValue);
@ -451,10 +464,17 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (type == null) if (type == null)
throw new ArgumentNullException("type"); throw new ArgumentNullException("type");
if (constantValue == null) { if (constantValue == null) {
if (type.IsReferenceType == true) if (type.IsReferenceType == true) {
return new NullReferenceExpression(); var expr = new NullReferenceExpression();
else if (AddResolveResultAnnotations)
return new DefaultValueExpression(ConvertType(type)); expr.AddAnnotation(new ConstantResolveResult(SpecialType.NullType, null));
return expr;
} else {
var expr = new DefaultValueExpression(ConvertType(type));
if (AddResolveResultAnnotations)
expr.AddAnnotation(new ConstantResolveResult(type, null));
return expr;
}
} else if (type.Kind == TypeKind.Enum) { } else if (type.Kind == TypeKind.Enum) {
return ConvertEnumValue(type, (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false)); return ConvertEnumValue(type, (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false));
} else { } else {

Loading…
Cancel
Save