Browse Source

Re-enable IntroduceUsingDeclarations

pull/728/head
Daniel Grunwald 11 years ago
parent
commit
08a5e81517
  1. 82
      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. 47
      ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
  6. 2
      ICSharpCode.Decompiler/CSharp/Transforms/IAstTransform.cs
  7. 2
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs
  8. 69
      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

82
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
@ -36,8 +37,22 @@ namespace ICSharpCode.Decompiler.CSharp @@ -36,8 +37,22 @@ namespace ICSharpCode.Decompiler.CSharp
public class CSharpDecompiler
{
readonly DecompilerTypeSystem typeSystem;
TypeSystemAstBuilder typeSystemAstBuilder;
List<IAstTransform> astTransforms;
List<IAstTransform> astTransforms = new List<IAstTransform> {
//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; }
@ -58,38 +73,27 @@ namespace ICSharpCode.Decompiler.CSharp @@ -58,38 +73,27 @@ namespace ICSharpCode.Decompiler.CSharp
if (typeSystem == null)
throw new ArgumentNullException("typeSystem");
this.typeSystem = typeSystem;
astTransforms = new List<IAstTransform> {
//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(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 CreateAstBuilder(ITypeResolveContext decompilationContext)
{
var typeSystemAstBuilder = new TypeSystemAstBuilder();
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)
transform.Run(rootNode);
transform.Run(rootNode, context);
rootNode.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
}
public SyntaxTree DecompileWholeModuleAsSingleFile()
{
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly);
SyntaxTree syntaxTree = new SyntaxTree();
foreach (var g in typeSystem.Compilation.MainAssembly.TopLevelTypeDefinitions.GroupBy(t => t.Namespace)) {
AstNode groupNode;
@ -104,11 +108,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -104,11 +108,11 @@ namespace ICSharpCode.Decompiler.CSharp
foreach (var typeDef in g) {
if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0)
continue;
var typeDecl = DoDecompile(typeDef);
var typeDecl = DoDecompile(typeDef, decompilationContext.WithCurrentTypeDefinition(typeDef));
groupNode.AddChild(typeDecl, SyntaxTree.MemberRole);
}
}
RunTransforms(syntaxTree);
RunTransforms(syntaxTree, decompilationContext);
return syntaxTree;
}
@ -116,16 +120,19 @@ namespace ICSharpCode.Decompiler.CSharp @@ -116,16 +120,19 @@ namespace ICSharpCode.Decompiler.CSharp
{
if (typeDefinition == null)
throw new ArgumentNullException("typeDefinition");
ITypeDefinition typeDef = typeSystem.GetType(typeDefinition).GetDefinition();
ITypeDefinition typeDef = typeSystem.Resolve(typeDefinition).GetDefinition();
if (typeDef == null)
throw new InvalidOperationException("Could not find type definition in NR type system");
var decl = DoDecompile(typeDef);
RunTransforms(decl);
var decompilationContext = new SimpleTypeResolveContext(typeDef);
var decl = DoDecompile(typeDef, decompilationContext);
RunTransforms(decl, decompilationContext);
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 typeDecl = entityDecl as TypeDeclaration;
if (typeDecl == null) {
@ -135,7 +142,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -135,7 +142,7 @@ namespace ICSharpCode.Decompiler.CSharp
foreach (var method in typeDef.Methods) {
var methodDef = typeSystem.GetCecil(method) as MethodDefinition;
if (methodDef != null) {
var memberDecl = DoDecompile(methodDef, method);
var memberDecl = DoDecompile(methodDef, method, decompilationContext.WithCurrentMember(method));
typeDecl.Members.Add(memberDecl);
}
}
@ -146,16 +153,19 @@ namespace ICSharpCode.Decompiler.CSharp @@ -146,16 +153,19 @@ namespace ICSharpCode.Decompiler.CSharp
{
if (methodDefinition == null)
throw new ArgumentNullException("methodDefinition");
var method = typeSystem.GetMethod(methodDefinition);
var method = typeSystem.Resolve(methodDefinition);
if (method == null)
throw new InvalidOperationException("Could not find method in NR type system");
var decl = DoDecompile(methodDefinition, method);
RunTransforms(decl);
var decompilationContext = new SimpleTypeResolveContext(method);
var decl = DoDecompile(methodDefinition, method, decompilationContext);
RunTransforms(decl, decompilationContext);
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);
if (methodDefinition.HasBody) {
var ilReader = new ILReader(typeSystem);
@ -163,7 +173,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -163,7 +173,7 @@ namespace ICSharpCode.Decompiler.CSharp
function.CheckInvariant();
function.Body = function.Body.AcceptVisitor(new TransformingVisitor());
function.CheckInvariant();
var statementBuilder = new StatementBuilder(method);
var statementBuilder = new StatementBuilder(decompilationContext);
var body = statementBuilder.ConvertAsBlock(function.Body);
// insert variables at start of body

13
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

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

8
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

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

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

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

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

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.PatternMatching;
@ -30,17 +31,31 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -30,17 +31,31 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
/// <summary>
/// If the first element of a constructor is a chained constructor call, convert it into a constructor initializer.
/// </summary>
public class ConvertConstructorCallIntoInitializer : DepthFirstAstVisitor, IAstTransform
public class ConvertConstructorCallIntoInitializer : IAstTransform
{
readonly DecompilerTypeSystem typeSystem;
public ConvertConstructorCallIntoInitializer(DecompilerTypeSystem typeSystem)
public void Run(AstNode node, TransformContext context)
{
if (typeSystem == null)
throw new ArgumentNullException("typeSystem");
this.typeSystem = typeSystem;
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);
node.AcceptVisitor(visitor);
}
}
sealed class ConvertConstructorCallIntoInitializerVisitor : DepthFirstAstVisitor
{
readonly TransformContext context;
public ConvertConstructorCallIntoInitializerVisitor(TransformContext context)
{
Debug.Assert(context != null);
this.context = context;
}
public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
{
ExpressionStatement stmt = constructorDeclaration.Body.Statements.FirstOrDefault() as ExpressionStatement;
@ -96,7 +111,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -96,7 +111,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
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 instanceCtorsNotChainingWithThis = instanceCtors.Where(ctor => !thisCallPattern.IsMatch(ctor.Body.Statements.FirstOrDefault())).ToArray();
@ -150,13 +165,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -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
var staticCtor = members.OfType<ConstructorDeclaration>().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static);
if (staticCtor != null) {
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) {
while (true) {
ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement;
@ -179,15 +194,5 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -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 @@ -25,6 +25,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
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 @@ -27,7 +27,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
sealed class PointerArithmetic {}
public void Run(AstNode compilationUnit)
public void Run(AstNode compilationUnit, TransformContext context)
{
compilationUnit.AcceptVisitor(this);
}

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

@ -20,7 +20,7 @@ using System; @@ -20,7 +20,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
using ICSharpCode.NRefactory.Semantics;
namespace ICSharpCode.Decompiler.CSharp.Transforms
{
@ -29,25 +29,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -29,25 +29,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
/// </summary>
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:
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:
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
// (always inserting at the start of the list)
string[] parts = ns.Split('.');
@ -58,9 +51,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -58,9 +51,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
compilationUnit.InsertChildAfter(null, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);
}
if (!context.Settings.FullyQualifyAmbiguousTypeNames)
if (!FullyQualifyAmbiguousTypeNames)
return;
/*
FindAmbiguousTypeNames(context.CurrentModule, internalsVisible: true);
foreach (AssemblyNameReference r in context.CurrentModule.AssemblyReferences) {
AssemblyDefinition d = context.CurrentModule.AssemblyResolver.Resolve(r);
@ -69,25 +63,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -69,25 +63,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
// 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.
readonly HashSet<string> availableTypeNames = new HashSet<string>();
readonly HashSet<string> ambiguousTypeNames = new HashSet<string>();
//readonly HashSet<string> availableTypeNames = 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;
public readonly HashSet<string> DeclaredNamespaces = new HashSet<string>() { string.Empty };
public readonly HashSet<string> ImportedNamespaces = new HashSet<string>();
public FindRequiredImports(IntroduceUsingDeclarations transform)
public FindRequiredImports(TransformContext context)
{
this.transform = transform;
this.currentNamespace = transform.context.CurrentType != null ? transform.context.CurrentType.Namespace : string.Empty;
this.currentNamespace = context.DecompiledTypeDefinition != null ? context.DecompiledTypeDefinition.Namespace : string.Empty;
}
bool IsParentOfCurrentNamespace(string ns)
@ -103,28 +96,28 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -103,28 +96,28 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return false;
}
public override object VisitSimpleType(SimpleType simpleType, object data)
public override void VisitSimpleType(SimpleType simpleType)
{
TypeReference tr = simpleType.Annotation<TypeReference>();
if (tr != null && !IsParentOfCurrentNamespace(tr.Namespace)) {
transform.importedNamespaces.Add(tr.Namespace);
var trr = simpleType.Annotation<TypeResolveResult>();
if (trr != null && !IsParentOfCurrentNamespace(trr.Type.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;
foreach (Identifier ident in namespaceDeclaration.Identifiers) {
currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident.Name);
transform.declaredNamespaces.Add(currentNamespace);
foreach (string ident in namespaceDeclaration.Identifiers) {
currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident);
DeclaredNamespaces.Add(currentNamespace);
}
base.VisitNamespaceDeclaration(namespaceDeclaration, data);
base.VisitNamespaceDeclaration(namespaceDeclaration);
currentNamespace = oldNamespace;
return null;
}
}
/*
void FindAmbiguousTypeNames(ModuleDefinition module, bool internalsVisible)
{
foreach (TypeDefinition type in module.Types) {
@ -355,6 +348,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -355,6 +348,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return false;
return transform.ambiguousTypeNames.Contains(name);
}
}
}*/
}
}

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

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

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

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

30
ICSharpCode.Decompiler/DecompilerTypeSystem.cs

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

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -63,6 +63,8 @@ @@ -63,6 +63,8 @@
</ItemGroup>
<ItemGroup>
<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\CSharpDecompiler.cs" />
<Compile Include="CSharp\ExpressionBuilder.cs" />

2
ICSharpCode.Decompiler/IL/BlockBuilder.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL @@ -72,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL
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";
handlerBlock.EntryPoint.Instructions.Add(new LdLoc(variable));

10
ICSharpCode.Decompiler/IL/ILReader.cs

@ -93,21 +93,21 @@ namespace ICSharpCode.Decompiler.IL @@ -93,21 +93,21 @@ namespace ICSharpCode.Decompiler.IL
{
var token = ReadMetadataToken(ref reader);
var typeReference = body.LookupToken(token) as TypeReference;
return typeSystem.GetType(typeReference);
return typeSystem.Resolve(typeReference);
}
IMethod ReadAndDecodeMethodReference()
{
var token = ReadMetadataToken(ref reader);
var methodReference = body.LookupToken(token) as MethodReference;
return typeSystem.GetMethod(methodReference);
return typeSystem.Resolve(methodReference);
}
IField ReadAndDecodeFieldReference()
{
var token = ReadMetadataToken(ref reader);
var fieldReference = body.LookupToken(token) as FieldReference;
return typeSystem.GetField(fieldReference);
return typeSystem.Resolve(fieldReference);
}
void InitParameterVariables()
@ -123,7 +123,7 @@ namespace ICSharpCode.Decompiler.IL @@ -123,7 +123,7 @@ namespace ICSharpCode.Decompiler.IL
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))
ilVar.Name = "V_" + v.Index;
else
@ -134,7 +134,7 @@ namespace ICSharpCode.Decompiler.IL @@ -134,7 +134,7 @@ namespace ICSharpCode.Decompiler.IL
ILVariable CreateILVariable(ParameterDefinition p)
{
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
if (variableKind == VariableKind.This)
ilVar.Name = "this";

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

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

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

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

Loading…
Cancel
Save