Browse Source

Remove UnresolvedUsingScope

pull/3532/head
Siegfried Pammer 5 months ago
parent
commit
c9e3790adc
  1. 56
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 1
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  3. 2
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  4. 34
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs
  5. 86
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs
  6. 143
      ICSharpCode.Decompiler/CSharp/TypeSystem/ResolvedUsingScope.cs
  7. 167
      ICSharpCode.Decompiler/CSharp/TypeSystem/UsingScope.cs
  8. 30
      ICSharpCode.Decompiler/DecompileRun.cs
  9. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  10. 2
      ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs
  11. 3
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

56
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
@ -30,6 +31,7 @@ using ICSharpCode.Decompiler.CSharp.OutputVisitor; @@ -30,6 +31,7 @@ using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Documentation;
@ -518,11 +520,28 @@ namespace ICSharpCode.Decompiler.CSharp @@ -518,11 +520,28 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
DecompileRun CreateDecompileRun()
DecompileRun CreateDecompileRun(HashSet<string> namespaces)
{
return new DecompileRun(settings) {
List<INamespace> resolvedNamespaces = new List<INamespace>();
foreach (var ns in namespaces)
{
var resolvedNamespace = typeSystem.GetNamespaceByFullName(ns);
if (resolvedNamespace != null)
{
resolvedNamespaces.Add(resolvedNamespace);
}
}
ResolvedUsingScope usingScope = new ResolvedUsingScope(
new CSharpTypeResolveContext(typeSystem.MainModule),
typeSystem.RootNamespace,
resolvedNamespaces.ToImmutableArray()
);
return new DecompileRun(settings, usingScope) {
DocumentationProvider = DocumentationProvider ?? CreateDefaultDocumentationProvider(),
CancellationToken = CancellationToken
CancellationToken = CancellationToken,
Namespaces = namespaces
};
}
@ -554,9 +573,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -554,9 +573,10 @@ namespace ICSharpCode.Decompiler.CSharp
public SyntaxTree DecompileModuleAndAssemblyAttributes()
{
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);
DecompileRun decompileRun = CreateDecompileRun();
var namespaces = new HashSet<string>();
syntaxTree = new SyntaxTree();
RequiredNamespaceCollector.CollectAttributeNamespaces(module, decompileRun.Namespaces);
RequiredNamespaceCollector.CollectAttributeNamespaces(module, namespaces);
DecompileRun decompileRun = CreateDecompileRun(namespaces);
DoDecompileModuleAndAssemblyAttributes(decompileRun, decompilationContext, syntaxTree);
RunTransforms(syntaxTree, decompileRun, decompilationContext);
return syntaxTree;
@ -640,9 +660,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -640,9 +660,10 @@ namespace ICSharpCode.Decompiler.CSharp
public SyntaxTree DecompileWholeModuleAsSingleFile(bool sortTypes)
{
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);
var decompileRun = CreateDecompileRun();
syntaxTree = new SyntaxTree();
RequiredNamespaceCollector.CollectNamespaces(module, decompileRun.Namespaces);
var namespaces = new HashSet<string>();
RequiredNamespaceCollector.CollectNamespaces(module, namespaces);
var decompileRun = CreateDecompileRun(namespaces);
DoDecompileModuleAndAssemblyAttributes(decompileRun, decompilationContext, syntaxTree);
var typeDefs = metadata.GetTopLevelTypeDefinitions();
if (sortTypes)
@ -662,8 +683,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -662,8 +683,9 @@ namespace ICSharpCode.Decompiler.CSharp
/// </summary>
public ILTransformContext CreateILTransformContext(ILFunction function)
{
var decompileRun = CreateDecompileRun();
RequiredNamespaceCollector.CollectNamespaces(function.Method, module, decompileRun.Namespaces);
var namespaces = new HashSet<string>();
RequiredNamespaceCollector.CollectNamespaces(function.Method, module, namespaces);
var decompileRun = CreateDecompileRun(namespaces);
return new ILTransformContext(function, typeSystem, DebugInfoProvider, settings) {
CancellationToken = CancellationToken,
DecompileRun = decompileRun
@ -907,17 +929,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -907,17 +929,17 @@ namespace ICSharpCode.Decompiler.CSharp
if (types == null)
throw new ArgumentNullException(nameof(types));
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);
var decompileRun = CreateDecompileRun();
syntaxTree = new SyntaxTree();
var namespaces = new HashSet<string>();
foreach (var type in types)
{
CancellationToken.ThrowIfCancellationRequested();
if (type.IsNil)
throw new ArgumentException("types contains null element");
RequiredNamespaceCollector.CollectNamespaces(type, module, decompileRun.Namespaces);
RequiredNamespaceCollector.CollectNamespaces(type, module, namespaces);
}
var decompileRun = CreateDecompileRun(namespaces);
DoDecompileTypes(types, decompileRun, decompilationContext, syntaxTree);
RunTransforms(syntaxTree, decompileRun, decompilationContext);
return syntaxTree;
@ -949,9 +971,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -949,9 +971,10 @@ namespace ICSharpCode.Decompiler.CSharp
if (type.ParentModule != typeSystem.MainModule)
throw new NotSupportedException($"Type {fullTypeName} was not found in the module being decompiled, but only in {type.ParentModule.Name}");
var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);
var decompileRun = CreateDecompileRun();
var namespaces = new HashSet<string>();
syntaxTree = new SyntaxTree();
RequiredNamespaceCollector.CollectNamespaces(type.MetadataToken, module, decompileRun.Namespaces);
RequiredNamespaceCollector.CollectNamespaces(type.MetadataToken, module, namespaces);
var decompileRun = CreateDecompileRun(namespaces);
DoDecompileTypes(new[] { (TypeDefinitionHandle)type.MetadataToken }, decompileRun, decompilationContext, syntaxTree);
RunTransforms(syntaxTree, decompileRun, decompilationContext);
return syntaxTree;
@ -984,13 +1007,14 @@ namespace ICSharpCode.Decompiler.CSharp @@ -984,13 +1007,14 @@ namespace ICSharpCode.Decompiler.CSharp
if (definitions == null)
throw new ArgumentNullException(nameof(definitions));
syntaxTree = new SyntaxTree();
var decompileRun = CreateDecompileRun();
var namespaces = new HashSet<string>();
foreach (var entity in definitions)
{
if (entity.IsNil)
throw new ArgumentException("definitions contains null element");
RequiredNamespaceCollector.CollectNamespaces(entity, module, decompileRun.Namespaces);
RequiredNamespaceCollector.CollectNamespaces(entity, module, namespaces);
}
var decompileRun = CreateDecompileRun(namespaces);
bool first = true;
ITypeDefinition parentTypeDef = null;

1
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -2051,7 +2051,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2051,7 +2051,6 @@ namespace ICSharpCode.Decompiler.CSharp
if (isExtensionMethodReference)
{
var resolver = this.resolver.WithCurrentUsingScope(this.expressionBuilder.statementBuilder.decompileRun.UsingScope.Resolve(this.resolver.Compilation));
result = resolver.ResolveMemberAccess(target, method.Name, typeArguments, NameLookupMode.InvocationTarget) as MethodGroupResolveResult;
if (result == null)
return false;

2
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -97,7 +97,7 @@ namespace ICSharpCode.Decompiler.CSharp
this.compilation = decompilationContext.Compilation;
this.resolver = new CSharpResolver(new CSharpTypeResolveContext(
compilation.MainModule,
decompileRun.UsingScope.Resolve(compilation),
decompileRun.UsingScope,
decompilationContext.CurrentTypeDefinition,
decompilationContext.CurrentMember
));

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

@ -42,63 +42,53 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -42,63 +42,53 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
this.context = context;
this.conversions = CSharpConversions.Get(context.TypeSystem);
InitializeContext(rootNode.Annotation<UsingScope>());
InitializeContext(rootNode.Annotation<ResolvedUsingScope>());
rootNode.AcceptVisitor(this);
}
Stack<CSharpTypeResolveContext> resolveContextStack = new Stack<CSharpTypeResolveContext>();
void InitializeContext(UsingScope usingScope)
void InitializeContext(ResolvedUsingScope usingScope)
{
this.resolveContextStack = new Stack<CSharpTypeResolveContext>();
if (!string.IsNullOrEmpty(context.CurrentTypeDefinition?.Namespace))
{
foreach (string ns in context.CurrentTypeDefinition.Namespace.Split('.'))
{
usingScope = new UsingScope(usingScope, ns);
usingScope = usingScope.WithNestedNamespace(ns);
}
}
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.CurrentTypeDefinition);
this.resolveContextStack.Push(currentContext);
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope, context.CurrentTypeDefinition);
this.resolver = new CSharpResolver(currentContext);
}
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
{
var previousContext = resolveContextStack.Peek();
var usingScope = previousContext.CurrentUsingScope.UnresolvedUsingScope;
var usingScope = resolver.CurrentUsingScope;
foreach (string ident in namespaceDeclaration.Identifiers)
{
usingScope = new UsingScope(usingScope, ident);
usingScope = usingScope.WithNestedNamespace(ident);
}
var currentContext = new CSharpTypeResolveContext(previousContext.CurrentModule, usingScope.Resolve(previousContext.Compilation));
resolveContextStack.Push(currentContext);
var previousResolver = this.resolver;
try
{
this.resolver = new CSharpResolver(currentContext);
this.resolver = this.resolver.WithCurrentUsingScope(usingScope);
base.VisitNamespaceDeclaration(namespaceDeclaration);
}
finally
{
this.resolver = new CSharpResolver(previousContext);
resolveContextStack.Pop();
this.resolver = previousResolver;
}
}
public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{
var previousContext = resolveContextStack.Peek();
var currentContext = previousContext.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
resolveContextStack.Push(currentContext);
var previousResolver = this.resolver;
this.resolver = resolver.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
try
{
this.resolver = new CSharpResolver(currentContext);
base.VisitTypeDeclaration(typeDeclaration);
}
finally
{
this.resolver = new CSharpResolver(previousContext);
resolveContextStack.Pop();
this.resolver = previousResolver;
}
}

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

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
@ -42,8 +43,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -42,8 +43,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var requiredImports = new FindRequiredImports(context);
rootNode.AcceptVisitor(requiredImports);
var usingScope = new UsingScope();
rootNode.AddAnnotation(usingScope);
List<INamespace> resolvedNamespaces = new List<INamespace>();
if (context.Settings.UsingDeclarations)
{
@ -64,12 +64,22 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -64,12 +64,22 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
nsType = new MemberType { Target = nsType, MemberName = parts[i] };
}
if (nsType.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) is TypeOrNamespaceReference reference)
usingScope.Usings.Add(reference);
var resolvedNamespace = context.TypeSystem.GetNamespaceByFullName(ns);
if (resolvedNamespace != null)
{
resolvedNamespaces.Add(resolvedNamespace);
}
rootNode.InsertChildAfter(insertionPoint, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);
}
}
var usingScope = new ResolvedUsingScope(
new CSharpTypeResolveContext(context.TypeSystem.MainModule),
context.TypeSystem.RootNamespace,
resolvedNamespaces.ToImmutableArray()
);
rootNode.AddAnnotation(usingScope);
// verify that the SimpleTypes refer to the correct type (no ambiguities)
rootNode.AcceptVisitor(new FullyQualifyAmbiguousTypeNamesVisitor(context, usingScope));
}
@ -173,41 +183,35 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -173,41 +183,35 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
sealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor
{
readonly Stack<CSharpTypeResolveContext> context;
readonly bool ignoreUsingScope;
readonly DecompilerSettings settings;
CSharpResolver resolver;
TypeSystemAstBuilder astBuilder;
public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope)
public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, ResolvedUsingScope usingScope)
{
this.ignoreUsingScope = !context.Settings.UsingDeclarations;
this.settings = context.Settings;
this.resolver = new CSharpResolver(new CSharpTypeResolveContext(context.TypeSystem.MainModule));
CSharpTypeResolveContext currentContext;
if (ignoreUsingScope)
{
currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule);
}
else
if (!ignoreUsingScope)
{
this.context = new Stack<CSharpTypeResolveContext>();
if (!string.IsNullOrEmpty(context.CurrentTypeDefinition?.Namespace))
{
foreach (string ns in context.CurrentTypeDefinition.Namespace.Split('.'))
{
usingScope = new UsingScope(usingScope, ns);
usingScope = usingScope.WithNestedNamespace(ns);
}
}
currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope.Resolve(context.TypeSystem), context.CurrentTypeDefinition);
this.context.Push(currentContext);
this.resolver = this.resolver.WithCurrentUsingScope(usingScope)
.WithCurrentTypeDefinition(context.CurrentTypeDefinition);
}
this.astBuilder = CreateAstBuilder(currentContext);
this.astBuilder = CreateAstBuilder(resolver);
}
TypeSystemAstBuilder CreateAstBuilder(CSharpTypeResolveContext context, IL.ILFunction function = null)
TypeSystemAstBuilder CreateAstBuilder(CSharpResolver resolver, IL.ILFunction function = null)
{
CSharpResolver resolver = new CSharpResolver(context);
if (function != null)
{
var variables = new Dictionary<string, IVariable>();
@ -234,23 +238,23 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -234,23 +238,23 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
base.VisitNamespaceDeclaration(namespaceDeclaration);
return;
}
var previousContext = context.Peek();
var usingScope = previousContext.CurrentUsingScope.UnresolvedUsingScope;
var previousResolver = resolver;
var previousAstBuilder = astBuilder;
var usingScope = resolver.CurrentUsingScope;
foreach (string ident in namespaceDeclaration.Identifiers)
{
usingScope = new UsingScope(usingScope, ident);
usingScope = usingScope.WithNestedNamespace(ident);
}
var currentContext = new CSharpTypeResolveContext(previousContext.CurrentModule, usingScope.Resolve(previousContext.Compilation));
context.Push(currentContext);
resolver = resolver.WithCurrentUsingScope(usingScope);
try
{
astBuilder = CreateAstBuilder(currentContext);
astBuilder = CreateAstBuilder(resolver);
base.VisitNamespaceDeclaration(namespaceDeclaration);
}
finally
{
astBuilder = CreateAstBuilder(previousContext);
context.Pop();
astBuilder = previousAstBuilder;
resolver = previousResolver;
}
}
@ -261,18 +265,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -261,18 +265,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
base.VisitTypeDeclaration(typeDeclaration);
return;
}
var previousContext = context.Peek();
var currentContext = previousContext.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
context.Push(currentContext);
var previousResolver = resolver;
var previousAstBuilder = astBuilder;
resolver = resolver.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
try
{
astBuilder = CreateAstBuilder(currentContext);
astBuilder = CreateAstBuilder(resolver);
base.VisitTypeDeclaration(typeDeclaration);
}
finally
{
astBuilder = CreateAstBuilder(previousContext);
context.Pop();
astBuilder = previousAstBuilder;
resolver = previousResolver;
}
}
@ -310,27 +314,27 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -310,27 +314,27 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
if (entityDeclaration.GetSymbol() is IMethod method)
{
var previousContext = context.Peek();
CSharpTypeResolveContext currentContext;
var previousResolver = resolver;
var previousAstBuilder = astBuilder;
if (CSharpDecompiler.IsWindowsFormsInitializeComponentMethod(method))
{
currentContext = new CSharpTypeResolveContext(previousContext.CurrentModule);
var currentContext = new CSharpTypeResolveContext(previousResolver.Compilation.MainModule);
resolver = new CSharpResolver(currentContext);
}
else
{
currentContext = previousContext.WithCurrentMember(method);
resolver = resolver.WithCurrentMember(method);
}
context.Push(currentContext);
try
{
var function = entityDeclaration.Annotation<IL.ILFunction>();
astBuilder = CreateAstBuilder(currentContext, function);
astBuilder = CreateAstBuilder(resolver, function);
baseCall(entityDeclaration);
}
finally
{
astBuilder = CreateAstBuilder(previousContext);
context.Pop();
resolver = previousResolver;
astBuilder = previousAstBuilder;
}
}
else

143
ICSharpCode.Decompiler/CSharp/TypeSystem/ResolvedUsingScope.cs

@ -19,153 +19,60 @@ @@ -19,153 +19,60 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Collections.Immutable;
using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
#nullable enable
namespace ICSharpCode.Decompiler.CSharp.TypeSystem
{
/// <summary>
/// Resolved version of using scope.
/// Represents a scope that contains "using" statements.
/// This is either the mo itself, or a namespace declaration.
/// </summary>
public class ResolvedUsingScope
{
readonly CSharpTypeResolveContext parentContext;
readonly UsingScope usingScope;
internal readonly ConcurrentDictionary<string, ResolveResult> ResolveCache = new ConcurrentDictionary<string, ResolveResult>();
internal List<List<IMethod>> AllExtensionMethods;
internal List<List<IMethod>>? AllExtensionMethods;
public ResolvedUsingScope(CSharpTypeResolveContext context, UsingScope usingScope)
public ResolvedUsingScope(CSharpTypeResolveContext context, INamespace @namespace, ImmutableArray<INamespace> usings)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (usingScope == null)
throw new ArgumentNullException(nameof(usingScope));
this.parentContext = context;
this.usingScope = usingScope;
if (usingScope.Parent != null)
{
if (context.CurrentUsingScope == null)
throw new InvalidOperationException();
}
else
{
if (context.CurrentUsingScope != null)
throw new InvalidOperationException();
}
this.parentContext = context ?? throw new ArgumentNullException(nameof(context));
this.Usings = usings;
this.Namespace = @namespace ?? throw new ArgumentNullException(nameof(@namespace));
}
public UsingScope UnresolvedUsingScope {
get { return usingScope; }
}
INamespace @namespace;
public INamespace Namespace {
get {
INamespace result = LazyInit.VolatileRead(ref this.@namespace);
if (result != null)
{
return result;
}
else
{
if (parentContext.CurrentUsingScope != null)
{
result = parentContext.CurrentUsingScope.Namespace.GetChildNamespace(usingScope.ShortNamespaceName);
if (result == null)
result = new DummyNamespace(parentContext.CurrentUsingScope.Namespace, usingScope.ShortNamespaceName);
}
else
{
result = parentContext.Compilation.RootNamespace;
}
Debug.Assert(result != null);
return LazyInit.GetOrSet(ref this.@namespace, result);
}
}
}
public INamespace Namespace { get; }
public ResolvedUsingScope Parent {
get { return parentContext.CurrentUsingScope; }
}
IList<INamespace> usings;
public IList<INamespace> Usings {
get {
var result = LazyInit.VolatileRead(ref this.usings);
if (result != null)
{
return result;
}
else
{
result = new List<INamespace>();
CSharpResolver resolver = new CSharpResolver(parentContext.WithUsingScope(this));
foreach (var u in usingScope.Usings)
{
INamespace ns = u.ResolveNamespace(resolver);
if (ns != null && !result.Contains(ns))
result.Add(ns);
}
return LazyInit.GetOrSet(ref this.usings, new ReadOnlyCollection<INamespace>(result));
}
}
}
public ImmutableArray<INamespace> Usings { get; }
IList<KeyValuePair<string, ResolveResult>> usingAliases;
public IList<KeyValuePair<string, ResolveResult>> UsingAliases {
get {
var result = LazyInit.VolatileRead(ref this.usingAliases);
if (result != null)
{
return result;
}
else
{
CSharpResolver resolver = new CSharpResolver(parentContext.WithUsingScope(this));
result = new KeyValuePair<string, ResolveResult>[usingScope.UsingAliases.Count];
for (int i = 0; i < result.Count; i++)
{
var rr = usingScope.UsingAliases[i].Value.Resolve(resolver);
if (rr is TypeResolveResult)
{
rr = new AliasTypeResolveResult(usingScope.UsingAliases[i].Key, (TypeResolveResult)rr);
}
else if (rr is NamespaceResolveResult)
{
rr = new AliasNamespaceResolveResult(usingScope.UsingAliases[i].Key, (NamespaceResolveResult)rr);
}
result[i] = new KeyValuePair<string, ResolveResult>(
usingScope.UsingAliases[i].Key,
rr
);
}
return LazyInit.GetOrSet(ref this.usingAliases, result);
}
}
}
public IReadOnlyList<KeyValuePair<string, ResolveResult>> UsingAliases => [];
public IList<string> ExternAliases {
get { return usingScope.ExternAliases; }
}
public IReadOnlyList<string> ExternAliases => [];
/// <summary>
/// Gets whether this using scope has an alias (either using or extern)
/// with the specified name.
/// </summary>
public bool HasAlias(string identifier)
public bool HasAlias(string identifier) => false;
internal ResolvedUsingScope WithNestedNamespace(string simpleName)
{
return usingScope.HasAlias(identifier);
var ns = Namespace.GetChildNamespace(simpleName) ?? new DummyNamespace(Namespace, simpleName);
return new ResolvedUsingScope(
parentContext.WithUsingScope(this),
ns,
[]);
}
sealed class DummyNamespace : INamespace
@ -179,7 +86,7 @@ namespace ICSharpCode.Decompiler.CSharp.TypeSystem @@ -179,7 +86,7 @@ namespace ICSharpCode.Decompiler.CSharp.TypeSystem
this.name = name;
}
public string ExternAlias { get; set; }
string INamespace.ExternAlias => "";
string INamespace.FullName {
get { return NamespaceDeclaration.BuildQualifiedName(parentNamespace.FullName, name); }
@ -213,12 +120,12 @@ namespace ICSharpCode.Decompiler.CSharp.TypeSystem @@ -213,12 +120,12 @@ namespace ICSharpCode.Decompiler.CSharp.TypeSystem
get { return parentNamespace.Compilation; }
}
INamespace INamespace.GetChildNamespace(string name)
INamespace? INamespace.GetChildNamespace(string name)
{
return null;
}
ITypeDefinition INamespace.GetTypeDefinition(string name, int typeParameterCount)
ITypeDefinition? INamespace.GetTypeDefinition(string name, int typeParameterCount)
{
return null;
}

167
ICSharpCode.Decompiler/CSharp/TypeSystem/UsingScope.cs

@ -1,167 +0,0 @@ @@ -1,167 +0,0 @@
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
//
// 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 System.Collections.Generic;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.CSharp.TypeSystem
{
/// <summary>
/// Represents a scope that contains "using" statements.
/// This is either the file itself, or a namespace declaration.
/// </summary>
[Serializable]
public class UsingScope : AbstractFreezable
{
readonly UsingScope parent;
string shortName = "";
IList<TypeOrNamespaceReference> usings;
IList<KeyValuePair<string, TypeOrNamespaceReference>> usingAliases;
IList<string> externAliases;
protected override void FreezeInternal()
{
usings = FreezableHelper.FreezeList(usings);
usingAliases = FreezableHelper.FreezeList(usingAliases);
externAliases = FreezableHelper.FreezeList(externAliases);
// In current model (no child scopes), it makes sense to freeze the parent as well
// to ensure the whole lookup chain is immutable.
if (parent != null)
parent.Freeze();
base.FreezeInternal();
}
/// <summary>
/// Creates a new root using scope.
/// </summary>
public UsingScope()
{
}
/// <summary>
/// Creates a new nested using scope.
/// </summary>
/// <param name="parent">The parent using scope.</param>
/// <param name="shortName">The short namespace name.</param>
public UsingScope(UsingScope parent, string shortName)
{
if (parent == null)
throw new ArgumentNullException(nameof(parent));
if (shortName == null)
throw new ArgumentNullException(nameof(shortName));
this.parent = parent;
this.shortName = shortName;
}
public UsingScope Parent {
get { return parent; }
}
public string ShortNamespaceName {
get {
return shortName;
}
}
public string NamespaceName {
get {
if (parent != null)
return NamespaceDeclaration.BuildQualifiedName(parent.NamespaceName, shortName);
else
return shortName;
}
// set {
// if (value == null)
// throw new ArgumentNullException("NamespaceName");
// FreezableHelper.ThrowIfFrozen(this);
// namespaceName = value;
// }
}
public IList<TypeOrNamespaceReference> Usings {
get {
if (usings == null)
usings = new List<TypeOrNamespaceReference>();
return usings;
}
}
public IList<KeyValuePair<string, TypeOrNamespaceReference>> UsingAliases {
get {
if (usingAliases == null)
usingAliases = new List<KeyValuePair<string, TypeOrNamespaceReference>>();
return usingAliases;
}
}
public IList<string> ExternAliases {
get {
if (externAliases == null)
externAliases = new List<string>();
return externAliases;
}
}
// public IList<UsingScope> ChildScopes {
// get {
// if (childScopes == null)
// childScopes = new List<UsingScope>();
// return childScopes;
// }
// }
/// <summary>
/// Gets whether this using scope has an alias (either using or extern)
/// with the specified name.
/// </summary>
public bool HasAlias(string identifier)
{
if (usingAliases != null)
{
foreach (var pair in usingAliases)
{
if (pair.Key == identifier)
return true;
}
}
return externAliases != null && externAliases.Contains(identifier);
}
/// <summary>
/// Resolves the namespace represented by this using scope.
/// </summary>
public ResolvedUsingScope Resolve(ICompilation compilation)
{
CacheManager cache = compilation.CacheManager;
ResolvedUsingScope resolved = cache.GetShared(this) as ResolvedUsingScope;
if (resolved == null)
{
var csContext = new CSharpTypeResolveContext(compilation.MainModule, parent != null ? parent.Resolve(compilation) : null);
resolved = (ResolvedUsingScope)cache.GetOrAddShared(this, new ResolvedUsingScope(csContext, this));
}
return resolved;
}
}
}

30
ICSharpCode.Decompiler/DecompileRun.cs

@ -21,7 +21,6 @@ using System.Collections.Generic; @@ -21,7 +21,6 @@ using System.Collections.Generic;
using System.Threading;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.TypeSystem;
@ -30,7 +29,7 @@ namespace ICSharpCode.Decompiler @@ -30,7 +29,7 @@ namespace ICSharpCode.Decompiler
internal class DecompileRun
{
public HashSet<string> DefinedSymbols { get; } = new HashSet<string>();
public HashSet<string> Namespaces { get; } = new HashSet<string>();
public HashSet<string> Namespaces { get; set; }
public CancellationToken CancellationToken { get; set; }
public DecompilerSettings Settings { get; }
public IDocumentationProvider DocumentationProvider { get; set; }
@ -38,33 +37,12 @@ namespace ICSharpCode.Decompiler @@ -38,33 +37,12 @@ namespace ICSharpCode.Decompiler
public Dictionary<ITypeDefinition, bool> TypeHierarchyIsKnown { get; } = new();
Lazy<CSharp.TypeSystem.UsingScope> usingScope =>
new Lazy<CSharp.TypeSystem.UsingScope>(() => CreateUsingScope(Namespaces));
public CSharp.TypeSystem.ResolvedUsingScope UsingScope { get; }
public CSharp.TypeSystem.UsingScope UsingScope => usingScope.Value;
public DecompileRun(DecompilerSettings settings)
public DecompileRun(DecompilerSettings settings, CSharp.TypeSystem.ResolvedUsingScope usingScope)
{
this.Settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
CSharp.TypeSystem.UsingScope CreateUsingScope(HashSet<string> requiredNamespacesSuperset)
{
var usingScope = new CSharp.TypeSystem.UsingScope();
foreach (var ns in requiredNamespacesSuperset)
{
string[] parts = ns.Split('.');
AstType nsType = new SimpleType(parts[0]);
for (int i = 1; i < parts.Length; i++)
{
nsType = new MemberType { Target = nsType, MemberName = parts[i] };
}
var reference = nsType.ToTypeReference(CSharp.Resolver.NameLookupMode.TypeInUsingDeclaration)
as CSharp.TypeSystem.TypeOrNamespaceReference;
if (reference != null)
usingScope.Usings.Add(reference);
}
return usingScope;
this.UsingScope = usingScope ?? throw new ArgumentNullException(nameof(usingScope));
}
}

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -341,7 +341,6 @@ @@ -341,7 +341,6 @@
<Compile Include="CSharp\TypeSystem\ResolvedUsingScope.cs" />
<Compile Include="CSharp\TypeSystem\SimpleTypeOrNamespaceReference.cs" />
<Compile Include="CSharp\TypeSystem\TypeOrNamespaceReference.cs" />
<Compile Include="CSharp\TypeSystem\UsingScope.cs" />
<Compile Include="DebugInfo\AsyncDebugInfo.cs" />
<Compile Include="DebugInfo\ImportScopeInfo.cs" />
<Compile Include="DebugInfo\DebugInfoGenerator.cs" />

2
ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public Metadata.MetadataFile PEFile => TypeSystem.MainModule.MetadataFile;
internal DecompileRun? DecompileRun { get; set; }
internal ResolvedUsingScope? UsingScope => DecompileRun?.UsingScope.Resolve(TypeSystem);
internal ResolvedUsingScope? UsingScope => DecompileRun?.UsingScope;
CSharpResolver? csharpResolver;

3
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -831,7 +831,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -831,7 +831,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public static INamespace GetNamespaceByFullName(this ICompilation compilation, string name)
#nullable enable
public static INamespace? GetNamespaceByFullName(this ICompilation compilation, string? name)
{
if (string.IsNullOrEmpty(name))
return compilation.RootNamespace;

Loading…
Cancel
Save