Browse Source

Fix #1103: Deactivating "Insert using declarations" now uses fully qualified types everywhere.

pull/1420/head
Siegfried Pammer 7 years ago
parent
commit
71ffb0183b
  1. 39
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 2
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  3. 4
      ICSharpCode.Decompiler/CSharp/Transforms/ContextTrackingVisitor.cs
  4. 2
      ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
  5. 6
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs
  6. 61
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs
  7. 18
      ICSharpCode.Decompiler/CSharp/Transforms/TransformContext.cs
  8. 12
      ICSharpCode.Decompiler/DecompilerSettings.cs
  9. 20
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  10. 1
      ILSpy/DecompilationOptions.cs
  11. 1
      ILSpy/Options/DecompilerSettingsPanel.xaml
  12. 14
      ILSpy/Options/DecompilerSettingsPanel.xaml.cs

39
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -664,7 +664,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -664,7 +664,6 @@ namespace ICSharpCode.Decompiler.CSharp
{
if (definitions == null)
throw new ArgumentNullException(nameof(definitions));
ITypeDefinition parentTypeDef = null;
syntaxTree = new SyntaxTree();
var decompileRun = new DecompileRun(settings) {
DocumentationProvider = DocumentationProvider ?? CreateDefaultDocumentationProvider(),
@ -676,17 +675,28 @@ namespace ICSharpCode.Decompiler.CSharp @@ -676,17 +675,28 @@ namespace ICSharpCode.Decompiler.CSharp
RequiredNamespaceCollector.CollectNamespaces(entity, module, decompileRun.Namespaces);
}
bool first = true;
ITypeDefinition parentTypeDef = null;
foreach (var entity in definitions) {
switch (entity.Kind) {
case HandleKind.TypeDefinition:
ITypeDefinition typeDef = module.GetDefinition((TypeDefinitionHandle)entity);
syntaxTree.Members.Add(DoDecompile(typeDef, decompileRun, new SimpleTypeResolveContext(typeDef)));
parentTypeDef = typeDef.DeclaringTypeDefinition;
if (first) {
parentTypeDef = typeDef.DeclaringTypeDefinition;
} else if (parentTypeDef != null) {
parentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, typeDef.DeclaringTypeDefinition);
}
break;
case HandleKind.MethodDefinition:
IMethod method = module.GetDefinition((MethodDefinitionHandle)entity);
syntaxTree.Members.Add(DoDecompile(method, decompileRun, new SimpleTypeResolveContext(method)));
parentTypeDef = method.DeclaringTypeDefinition;
if (first) {
parentTypeDef = method.DeclaringTypeDefinition;
} else if (parentTypeDef != null) {
parentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, method.DeclaringTypeDefinition);
}
break;
case HandleKind.FieldDefinition:
IField field = module.GetDefinition((FieldDefinitionHandle)entity);
@ -696,21 +706,39 @@ namespace ICSharpCode.Decompiler.CSharp @@ -696,21 +706,39 @@ namespace ICSharpCode.Decompiler.CSharp
case HandleKind.PropertyDefinition:
IProperty property = module.GetDefinition((PropertyDefinitionHandle)entity);
syntaxTree.Members.Add(DoDecompile(property, decompileRun, new SimpleTypeResolveContext(property)));
parentTypeDef = property.DeclaringTypeDefinition;
if (first) {
parentTypeDef = property.DeclaringTypeDefinition;
} else if (parentTypeDef != null) {
parentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, property.DeclaringTypeDefinition);
}
break;
case HandleKind.EventDefinition:
IEvent ev = module.GetDefinition((EventDefinitionHandle)entity);
syntaxTree.Members.Add(DoDecompile(ev, decompileRun, new SimpleTypeResolveContext(ev)));
parentTypeDef = ev.DeclaringTypeDefinition;
if (first) {
parentTypeDef = ev.DeclaringTypeDefinition;
} else if (parentTypeDef != null) {
parentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, ev.DeclaringTypeDefinition);
}
break;
default:
throw new NotSupportedException(entity.Kind.ToString());
}
first = false;
}
RunTransforms(syntaxTree, decompileRun, parentTypeDef != null ? new SimpleTypeResolveContext(parentTypeDef) : new SimpleTypeResolveContext(typeSystem.MainModule));
return syntaxTree;
}
ITypeDefinition FindCommonDeclaringTypeDefinition(ITypeDefinition a, ITypeDefinition b)
{
if (a == null || b == null)
return null;
var declaringTypes = a.GetDeclaringTypeDefinitions();
var set = new HashSet<ITypeDefinition>(b.GetDeclaringTypeDefinitions());
return declaringTypes.FirstOrDefault(set.Contains);
}
/// <summary>
/// Decompile the specified types and/or members.
/// </summary>
@ -1036,7 +1064,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1036,7 +1064,6 @@ namespace ICSharpCode.Decompiler.CSharp
if (IsWindowsFormsInitializeComponentMethod(method)) {
localSettings.UseImplicitMethodGroupConversion = false;
localSettings.UsingDeclarations = false;
localSettings.FullyQualifyAmbiguousTypeNames = true;
localSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls = true;
}

2
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -332,7 +332,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -332,7 +332,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
// Handle top-level types
if (string.IsNullOrEmpty(genericType.Namespace)) {
result.Target = new SimpleType("global");
if (AddResolveResultAnnotations)
if (AddResolveResultAnnotations && resolver != null)
result.Target.AddAnnotation(new NamespaceResolveResult(resolver.Compilation.RootNamespace));
result.IsDoubleColon = true;
} else {

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

@ -32,8 +32,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -32,8 +32,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
protected void Initialize(TransformContext context)
{
currentTypeDefinition = context.DecompiledTypeDefinition;
currentMethod = context.DecompiledMember as IMethod;
currentTypeDefinition = context.CurrentTypeDefinition;
currentMethod = context.CurrentMember as IMethod;
}
protected void Uninitialize()

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

@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
node.AcceptVisitor(visitor);
visitor.RemoveSingleEmptyConstructor(node.Children, context.DecompiledTypeDefinition);
visitor.RemoveSingleEmptyConstructor(node.Children, context.CurrentTypeDefinition);
}
}

6
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs

@ -51,12 +51,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -51,12 +51,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
void InitializeContext(UsingScope usingScope)
{
this.resolveContextStack = new Stack<CSharpTypeResolveContext>();
if (!string.IsNullOrEmpty(context.DecompiledTypeDefinition?.Namespace)) {
foreach (string ns in context.DecompiledTypeDefinition.Namespace.Split('.')) {
if (!string.IsNullOrEmpty(context.CurrentTypeDefinition?.Namespace)) {
foreach (string ns in context.CurrentTypeDefinition.Namespace.Split('.')) {
usingScope = new UsingScope(usingScope, ns);
}
}
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.DecompiledTypeDefinition);
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.CurrentTypeDefinition);
this.resolveContextStack.Push(currentContext);
this.resolver = new CSharpResolver(currentContext);
}

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

@ -55,18 +55,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -55,18 +55,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
for (int i = 1; i < parts.Length; i++) {
nsType = new MemberType { Target = nsType, MemberName = parts[i] };
}
if (context.Settings.FullyQualifyAmbiguousTypeNames) {
var reference = nsType.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
if (reference != null)
usingScope.Usings.Add(reference);
}
var reference = nsType.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
if (reference != null)
usingScope.Usings.Add(reference);
rootNode.InsertChildAfter(insertionPoint, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);
}
}
if (!context.Settings.FullyQualifyAmbiguousTypeNames)
return;
// verify that the SimpleTypes refer to the correct type (no ambiguities)
rootNode.AcceptVisitor(new FullyQualifyAmbiguousTypeNamesVisitor(context, usingScope));
}
@ -80,7 +75,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -80,7 +75,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public FindRequiredImports(TransformContext context)
{
this.currentNamespace = context.DecompiledTypeDefinition?.Namespace ?? string.Empty;
this.currentNamespace = context.CurrentTypeDefinition?.Namespace ?? string.Empty;
}
bool IsParentOfCurrentNamespace(string ns)
@ -114,24 +109,46 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -114,24 +109,46 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
base.VisitNamespaceDeclaration(namespaceDeclaration);
currentNamespace = oldNamespace;
}
}/*
public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{
string oldNamespace = currentNamespace;
if (!(typeDeclaration.Parent is NamespaceDeclaration || typeDeclaration.Parent is TypeDeclaration)) {
var symbol = typeDeclaration.GetSymbol() as ITypeDefinition;
if (symbol != null) {
currentNamespace = symbol.Namespace;
DeclaredNamespaces.Add(currentNamespace);
}
}
base.VisitTypeDeclaration(typeDeclaration);
currentNamespace = oldNamespace;
}*/
}
sealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor
{
Stack<CSharpTypeResolveContext> context;
TypeSystemAstBuilder astBuilder;
bool ignoreUsingScope;
public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope)
{
this.context = new Stack<CSharpTypeResolveContext>();
if (!string.IsNullOrEmpty(context.DecompiledTypeDefinition?.Namespace)) {
foreach (string ns in context.DecompiledTypeDefinition.Namespace.Split('.')) {
usingScope = new UsingScope(usingScope, ns);
this.ignoreUsingScope = !context.Settings.UsingDeclarations;
CSharpTypeResolveContext currentContext;
if (ignoreUsingScope) {
currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule);
} else {
this.context = new Stack<CSharpTypeResolveContext>();
if (!string.IsNullOrEmpty(context.CurrentTypeDefinition?.Namespace)) {
foreach (string ns in context.CurrentTypeDefinition.Namespace.Split('.')) {
usingScope = new UsingScope(usingScope, ns);
}
}
currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.CurrentTypeDefinition);
this.context.Push(currentContext);
}
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.DecompiledTypeDefinition);
this.context.Push(currentContext);
this.astBuilder = CreateAstBuilder(currentContext);
}
@ -145,6 +162,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -145,6 +162,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
{
if (ignoreUsingScope) {
base.VisitNamespaceDeclaration(namespaceDeclaration);
return;
}
var previousContext = context.Peek();
var usingScope = previousContext.CurrentUsingScope.UnresolvedUsingScope;
foreach (string ident in namespaceDeclaration.Identifiers) {
@ -163,6 +184,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -163,6 +184,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{
if (ignoreUsingScope) {
base.VisitTypeDeclaration(typeDeclaration);
return;
}
var previousContext = context.Peek();
var currentContext = previousContext.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
context.Push(currentContext);
@ -177,6 +202,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -177,6 +202,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{
if (ignoreUsingScope) {
base.VisitMethodDeclaration(methodDeclaration);
return;
}
if (methodDeclaration.GetSymbol() is IMethod method && CSharpDecompiler.IsWindowsFormsInitializeComponentMethod(method)) {
var previousContext = context.Peek();
var currentContext = new CSharpTypeResolveContext(previousContext.CurrentModule);

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

@ -37,25 +37,19 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -37,25 +37,19 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
readonly ITypeResolveContext decompilationContext;
/// <summary>
/// Returns the member that is being decompiled; or null if a whole type or assembly is being decompiled.
/// Returns the current member; or null if a whole type or module is being decompiled.
/// </summary>
public IMember DecompiledMember {
get { return decompilationContext.CurrentMember; }
}
public IMember CurrentMember => decompilationContext.CurrentMember;
/// <summary>
/// Returns the type definition that is being decompiled; or null if an assembly is being decompiled.
/// Returns the current type definition; or null if a module is being decompiled.
/// </summary>
public ITypeDefinition DecompiledTypeDefinition {
get { return decompilationContext.CurrentTypeDefinition; }
}
public ITypeDefinition CurrentTypeDefinition => decompilationContext.CurrentTypeDefinition;
/// <summary>
/// Returns the module that is being decompiled.
/// </summary>
public IModule DecompiledModule {
get { return decompilationContext.CurrentModule; }
}
public IModule CurrentModule => decompilationContext.CurrentModule;
/// <summary>
/// Returns the max possible set of namespaces that will be used during decompilation.

12
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -415,18 +415,6 @@ namespace ICSharpCode.Decompiler @@ -415,18 +415,6 @@ namespace ICSharpCode.Decompiler
}
}
bool fullyQualifyAmbiguousTypeNames = true;
public bool FullyQualifyAmbiguousTypeNames {
get { return fullyQualifyAmbiguousTypeNames; }
set {
if (fullyQualifyAmbiguousTypeNames != value) {
fullyQualifyAmbiguousTypeNames = value;
OnPropertyChanged();
}
}
}
bool useDebugSymbols = true;
/// <summary>

20
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -112,7 +112,25 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -112,7 +112,25 @@ namespace ICSharpCode.Decompiler.TypeSystem
return IsDerivedFrom(type, type.Compilation.FindType(baseType).GetDefinition());
}
#endregion
#region GetDeclaringTypeDefinitionsOrThis
/// <summary>
/// Returns all declaring type definitions of this type definition.
/// The output is ordered so that inner types occur before outer types.
/// </summary>
public static IEnumerable<ITypeDefinition> GetDeclaringTypeDefinitions(this ITypeDefinition definition)
{
if (definition == null) {
throw new ArgumentNullException(nameof(definition));
}
while (definition != null) {
yield return definition;
definition = definition.DeclaringTypeDefinition;
}
}
#endregion
#region IsOpen / IsUnbound / IsKnownType
sealed class TypeClassificationVisitor : TypeVisitor
{

1
ILSpy/DecompilationOptions.cs

@ -85,7 +85,6 @@ namespace ICSharpCode.ILSpy @@ -85,7 +85,6 @@ namespace ICSharpCode.ILSpy
AlwaysUseBraces = settings.AlwaysUseBraces,
ExpandMemberDefinitions = settings.ExpandMemberDefinitions,
FoldBraces = settings.FoldBraces,
FullyQualifyAmbiguousTypeNames = settings.FullyQualifyAmbiguousTypeNames,
RemoveDeadCode = settings.RemoveDeadCode,
ShowDebugInfo = settings.ShowDebugInfo,
ShowXmlDocumentation = settings.ShowXmlDocumentation,

1
ILSpy/Options/DecompilerSettingsPanel.xaml

@ -14,7 +14,6 @@ @@ -14,7 +14,6 @@
<CheckBox IsChecked="{Binding FoldBraces}">Enable folding on all blocks in braces</CheckBox>
<CheckBox IsChecked="{Binding RemoveDeadCode}">Remove dead and side effect free code</CheckBox>
<CheckBox IsChecked="{Binding UsingDeclarations}">Insert using declarations</CheckBox>
<CheckBox IsChecked="{Binding FullyQualifyAmbiguousTypeNames}">Fully qualify ambiguous type names</CheckBox>
<CheckBox IsChecked="{Binding AlwaysUseBraces}">Always use braces</CheckBox>
<CheckBox IsChecked="{Binding ExpandMemberDefinitions}">Expand member definitions after decompilation</CheckBox>
</StackPanel>

14
ILSpy/Options/DecompilerSettingsPanel.xaml.cs

@ -57,7 +57,6 @@ namespace ICSharpCode.ILSpy.Options @@ -57,7 +57,6 @@ namespace ICSharpCode.ILSpy.Options
s.ExpandMemberDefinitions = (bool?)e.Attribute("expandMemberDefinitions") ?? s.ExpandMemberDefinitions;
s.RemoveDeadCode = (bool?)e.Attribute("removeDeadCode") ?? s.RemoveDeadCode;
s.UsingDeclarations = (bool?)e.Attribute("usingDeclarations") ?? s.UsingDeclarations;
s.FullyQualifyAmbiguousTypeNames = (bool?)e.Attribute("fullyQualifyAmbiguousTypeNames") ?? s.FullyQualifyAmbiguousTypeNames;
s.AlwaysUseBraces = (bool?)e.Attribute("alwaysUseBraces") ?? s.AlwaysUseBraces;
return s;
}
@ -73,7 +72,6 @@ namespace ICSharpCode.ILSpy.Options @@ -73,7 +72,6 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("expandMemberDefinitions", s.ExpandMemberDefinitions);
section.SetAttributeValue("removeDeadCode", s.RemoveDeadCode);
section.SetAttributeValue("usingDeclarations", s.UsingDeclarations);
section.SetAttributeValue("fullyQualifyAmbiguousTypeNames", s.FullyQualifyAmbiguousTypeNames);
section.SetAttributeValue("alwaysUseBraces", s.AlwaysUseBraces);
XElement existingElement = root.Element("DecompilerSettings");
@ -142,18 +140,6 @@ namespace ICSharpCode.ILSpy.Options @@ -142,18 +140,6 @@ namespace ICSharpCode.ILSpy.Options
}
}
bool fullyQualifyAmbiguousTypeNames = true;
public bool FullyQualifyAmbiguousTypeNames {
get { return fullyQualifyAmbiguousTypeNames; }
set {
if (fullyQualifyAmbiguousTypeNames != value) {
fullyQualifyAmbiguousTypeNames = value;
OnPropertyChanged();
}
}
}
bool useDebugSymbols = true;
/// <summary>

Loading…
Cancel
Save