Browse Source

Remove dead code

pull/3532/head
Siegfried Pammer 5 months ago
parent
commit
7ea2c8f32f
  1. 77
      ICSharpCode.Decompiler/CSharp/TypeSystem/AliasNamespaceReference.cs
  2. 122
      ICSharpCode.Decompiler/CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs
  3. 109
      ICSharpCode.Decompiler/CSharp/TypeSystem/SimpleTypeOrNamespaceReference.cs
  4. 82
      ICSharpCode.Decompiler/CSharp/TypeSystem/TypeOrNamespaceReference.cs
  5. 5
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  6. 154
      ICSharpCode.Decompiler/TypeSystem/Implementation/GetClassTypeReference.cs
  7. 226
      ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs
  8. 38
      ICSharpCode.Decompiler/TypeSystem/TupleType.cs
  9. 9
      ICSharpCode.Decompiler/TypeSystem/TypeProvider.cs

77
ICSharpCode.Decompiler/CSharp/TypeSystem/AliasNamespaceReference.cs

@ -1,77 +0,0 @@ @@ -1,77 +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 ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.TypeSystem
{
/// <summary>
/// Looks up an alias (identifier in front of :: operator).
/// </summary>
/// <remarks>
/// The member lookup performed by the :: operator is handled
/// by <see cref="MemberTypeOrNamespaceReference"/>.
/// </remarks>
[Serializable]
public sealed class AliasNamespaceReference : TypeOrNamespaceReference, ISupportsInterning
{
readonly string identifier;
public AliasNamespaceReference(string identifier)
{
if (identifier == null)
throw new ArgumentNullException(nameof(identifier));
this.identifier = identifier;
}
public string Identifier {
get { return identifier; }
}
public override ResolveResult Resolve(CSharpResolver resolver)
{
return resolver.ResolveAlias(identifier);
}
public override IType ResolveType(CSharpResolver resolver)
{
// alias cannot refer to types
return SpecialType.NoType;
}
public override string ToString()
{
return identifier + "::";
}
int ISupportsInterning.GetHashCodeForInterning()
{
return identifier.GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
AliasNamespaceReference anr = other as AliasNamespaceReference;
return anr != null && this.identifier == anr.identifier;
}
}
}

122
ICSharpCode.Decompiler/CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs

@ -1,122 +0,0 @@ @@ -1,122 +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.Resolver;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.CSharp.TypeSystem
{
/// <summary>
/// Reference to a qualified type or namespace name.
/// </summary>
[Serializable]
public sealed class MemberTypeOrNamespaceReference : TypeOrNamespaceReference, ISupportsInterning
{
readonly TypeOrNamespaceReference target;
readonly string identifier;
readonly IList<ITypeReference> typeArguments;
readonly NameLookupMode lookupMode;
public MemberTypeOrNamespaceReference(TypeOrNamespaceReference target, string identifier, IList<ITypeReference> typeArguments, NameLookupMode lookupMode = NameLookupMode.Type)
{
if (target == null)
throw new ArgumentNullException(nameof(target));
if (identifier == null)
throw new ArgumentNullException(nameof(identifier));
this.target = target;
this.identifier = identifier;
this.typeArguments = typeArguments ?? EmptyList<ITypeReference>.Instance;
this.lookupMode = lookupMode;
}
public string Identifier {
get { return identifier; }
}
public TypeOrNamespaceReference Target {
get { return target; }
}
public IList<ITypeReference> TypeArguments {
get { return typeArguments; }
}
public NameLookupMode LookupMode {
get { return lookupMode; }
}
/// <summary>
/// Adds a suffix to the identifier.
/// Does not modify the existing type reference, but returns a new one.
/// </summary>
public MemberTypeOrNamespaceReference AddSuffix(string suffix)
{
return new MemberTypeOrNamespaceReference(target, identifier + suffix, typeArguments, lookupMode);
}
public override ResolveResult Resolve(CSharpResolver resolver)
{
ResolveResult targetRR = target.Resolve(resolver);
if (targetRR.IsError)
return targetRR;
IReadOnlyList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);
return resolver.ResolveMemberAccess(targetRR, identifier, typeArgs, lookupMode);
}
public override IType ResolveType(CSharpResolver resolver)
{
TypeResolveResult trr = Resolve(resolver) as TypeResolveResult;
return trr != null ? trr.Type : new UnknownType(null, identifier, typeArguments.Count);
}
public override string ToString()
{
if (typeArguments.Count == 0)
return target.ToString() + "." + identifier;
else
return target.ToString() + "." + identifier + "<" + string.Join(",", typeArguments) + ">";
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hashCode = 0;
unchecked
{
hashCode += 1000000007 * target.GetHashCode();
hashCode += 1000000033 * identifier.GetHashCode();
hashCode += 1000000087 * typeArguments.GetHashCode();
hashCode += 1000000021 * (int)lookupMode;
}
return hashCode;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
MemberTypeOrNamespaceReference o = other as MemberTypeOrNamespaceReference;
return o != null && this.target == o.target
&& this.identifier == o.identifier && this.typeArguments == o.typeArguments
&& this.lookupMode == o.lookupMode;
}
}
}

109
ICSharpCode.Decompiler/CSharp/TypeSystem/SimpleTypeOrNamespaceReference.cs

@ -1,109 +0,0 @@ @@ -1,109 +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.Resolver;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.CSharp.TypeSystem
{
/// <summary>
/// Represents a simple C# name. (a single non-qualified identifier with an optional list of type arguments)
/// </summary>
[Serializable]
public sealed class SimpleTypeOrNamespaceReference : TypeOrNamespaceReference, ISupportsInterning
{
readonly string identifier;
readonly IList<ITypeReference> typeArguments;
readonly NameLookupMode lookupMode;
public SimpleTypeOrNamespaceReference(string identifier, IList<ITypeReference> typeArguments, NameLookupMode lookupMode = NameLookupMode.Type)
{
if (identifier == null)
throw new ArgumentNullException(nameof(identifier));
this.identifier = identifier;
this.typeArguments = typeArguments ?? EmptyList<ITypeReference>.Instance;
this.lookupMode = lookupMode;
}
public string Identifier {
get { return identifier; }
}
public IList<ITypeReference> TypeArguments {
get { return typeArguments; }
}
public NameLookupMode LookupMode {
get { return lookupMode; }
}
/// <summary>
/// Adds a suffix to the identifier.
/// Does not modify the existing type reference, but returns a new one.
/// </summary>
public SimpleTypeOrNamespaceReference AddSuffix(string suffix)
{
return new SimpleTypeOrNamespaceReference(identifier + suffix, typeArguments, lookupMode);
}
public override ResolveResult Resolve(CSharpResolver resolver)
{
var typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);
return resolver.LookupSimpleNameOrTypeName(identifier, typeArgs, lookupMode);
}
public override IType ResolveType(CSharpResolver resolver)
{
TypeResolveResult trr = Resolve(resolver) as TypeResolveResult;
return trr != null ? trr.Type : new UnknownType(null, identifier, typeArguments.Count);
}
public override string ToString()
{
if (typeArguments.Count == 0)
return identifier;
else
return identifier + "<" + string.Join(",", typeArguments) + ">";
}
int ISupportsInterning.GetHashCodeForInterning()
{
int hashCode = 0;
unchecked
{
hashCode += 1000000021 * identifier.GetHashCode();
hashCode += 1000000033 * typeArguments.GetHashCode();
hashCode += 1000000087 * (int)lookupMode;
}
return hashCode;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
SimpleTypeOrNamespaceReference o = other as SimpleTypeOrNamespaceReference;
return o != null && this.identifier == o.identifier
&& this.typeArguments == o.typeArguments && this.lookupMode == o.lookupMode;
}
}
}

82
ICSharpCode.Decompiler/CSharp/TypeSystem/TypeOrNamespaceReference.cs

@ -1,82 +0,0 @@ @@ -1,82 +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 ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.TypeSystem
{
/// <summary>
/// Represents a reference which could point to a type or namespace.
/// </summary>
[Serializable]
public abstract class TypeOrNamespaceReference : ITypeReference
{
/// <summary>
/// Resolves the reference and returns the ResolveResult.
/// </summary>
public abstract ResolveResult Resolve(CSharpResolver resolver);
/// <summary>
/// Returns the type that is referenced; or an <c>UnknownType</c> if the type isn't found.
/// </summary>
public abstract IType ResolveType(CSharpResolver resolver);
/// <summary>
/// Returns the namespace that is referenced; or null if no such namespace is found.
/// </summary>
public INamespace ResolveNamespace(CSharpResolver resolver)
{
NamespaceResolveResult nrr = Resolve(resolver) as NamespaceResolveResult;
return nrr != null ? nrr.Namespace : null;
}
IType ITypeReference.Resolve(ITypeResolveContext context)
{
// Strictly speaking, we might have to resolve the type in a nested compilation, similar
// to what we're doing with ConstantExpression.
// However, in almost all cases this will work correctly - if the resulting type is only available in the
// nested compilation and not in this, we wouldn't be able to map it anyways.
var ctx = context as CSharpTypeResolveContext;
if (ctx == null)
{
ctx = new CSharpTypeResolveContext(context.CurrentModule ?? context.Compilation.MainModule, null, context.CurrentTypeDefinition, context.CurrentMember);
}
return ResolveType(new CSharpResolver(ctx));
// A potential issue might be this scenario:
// Assembly 1:
// class A { public class Nested {} }
// Assembly 2: (references asm 1)
// class B : A {}
// Assembly 3: (references asm 1 and 2)
// class C { public B.Nested Field; }
// Assembly 4: (references asm 1 and 3, but not 2):
// uses C.Field;
// Here we would not be able to resolve 'B.Nested' in the compilation of assembly 4, as type B is missing there.
}
}
}

5
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -335,12 +335,8 @@ @@ -335,12 +335,8 @@
<Compile Include="CSharp\Transforms\PrettifyAssignments.cs" />
<Compile Include="CSharp\Transforms\RemoveCLSCompliantAttribute.cs" />
<Compile Include="CSharp\TranslationContext.cs" />
<Compile Include="CSharp\TypeSystem\AliasNamespaceReference.cs" />
<Compile Include="CSharp\TypeSystem\CSharpTypeResolveContext.cs" />
<Compile Include="CSharp\TypeSystem\MemberTypeOrNamespaceReference.cs" />
<Compile Include="CSharp\TypeSystem\UsingScope.cs" />
<Compile Include="CSharp\TypeSystem\SimpleTypeOrNamespaceReference.cs" />
<Compile Include="CSharp\TypeSystem\TypeOrNamespaceReference.cs" />
<Compile Include="DebugInfo\AsyncDebugInfo.cs" />
<Compile Include="DebugInfo\ImportScopeInfo.cs" />
<Compile Include="DebugInfo\DebugInfoGenerator.cs" />
@ -620,7 +616,6 @@ @@ -620,7 +616,6 @@
<Compile Include="TypeSystem\Implementation\DefaultParameter.cs" />
<Compile Include="TypeSystem\Implementation\DefaultVariable.cs" />
<Compile Include="TypeSystem\Implementation\DummyTypeParameter.cs" />
<Compile Include="TypeSystem\Implementation\GetClassTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\GetMembersHelper.cs" />
<Compile Include="TypeSystem\Implementation\KnownTypeCache.cs" />
<Compile Include="TypeSystem\Implementation\MergedNamespace.cs" />

154
ICSharpCode.Decompiler/TypeSystem/Implementation/GetClassTypeReference.cs

@ -1,154 +0,0 @@ @@ -1,154 +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;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
/// <summary>
/// Type Reference used when the fully qualified type name is known.
/// </summary>
[Serializable]
public sealed class GetClassTypeReference : ITypeReference, ISupportsInterning
{
readonly IModuleReference module;
readonly FullTypeName fullTypeName;
readonly bool? isReferenceType;
/// <summary>
/// Creates a new GetClassTypeReference that searches a type definition.
/// </summary>
/// <param name="fullTypeName">The full name of the type.</param>
/// <param name="module">A reference to the module containing this type.
/// If this parameter is null, the GetClassTypeReference will search in all
/// assemblies belonging to the compilation.
/// </param>
public GetClassTypeReference(FullTypeName fullTypeName, IModuleReference module = null, bool? isReferenceType = null)
{
this.fullTypeName = fullTypeName;
this.module = module;
this.isReferenceType = isReferenceType;
}
/// <summary>
/// Creates a new GetClassTypeReference that searches a top-level type in all assemblies.
/// </summary>
/// <param name="namespaceName">The namespace name containing the type, e.g. "System.Collections.Generic".</param>
/// <param name="name">The name of the type, e.g. "List".</param>
/// <param name="typeParameterCount">The number of type parameters, (e.g. 1 for List&lt;T&gt;).</param>
public GetClassTypeReference(string namespaceName, string name, int typeParameterCount = 0, bool? isReferenceType = null)
{
this.fullTypeName = new TopLevelTypeName(namespaceName, name, typeParameterCount);
this.isReferenceType = isReferenceType;
}
/// <summary>
/// Creates a new GetClassTypeReference that searches a top-level type in the specified assembly.
/// </summary>
/// <param name="module">A reference to the assembly containing this type.
/// If this parameter is null, the GetClassTypeReference will search in all assemblies belonging to the ICompilation.</param>
/// <param name="namespaceName">The namespace name containing the type, e.g. "System.Collections.Generic".</param>
/// <param name="name">The name of the type, e.g. "List".</param>
/// <param name="typeParameterCount">The number of type parameters, (e.g. 1 for List&lt;T&gt;).</param>
public GetClassTypeReference(IModuleReference module, string namespaceName, string name, int typeParameterCount = 0, bool? isReferenceType = null)
{
this.module = module;
this.fullTypeName = new TopLevelTypeName(namespaceName, name, typeParameterCount);
this.isReferenceType = isReferenceType;
}
/// <summary>
/// Gets the assembly reference.
/// This property returns null if the GetClassTypeReference is searching in all assemblies
/// of the compilation.
/// </summary>
public IModuleReference Module { get { return module; } }
/// <summary>
/// Gets the full name of the type this reference is searching for.
/// </summary>
public FullTypeName FullTypeName { get { return fullTypeName; } }
internal static IType ResolveInAllAssemblies(ICompilation compilation, in FullTypeName fullTypeName)
{
foreach (var asm in compilation.Modules)
{
IType type = asm.GetTypeDefinition(fullTypeName);
if (type != null)
return type;
}
return null;
}
public IType Resolve(ITypeResolveContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
IType type = null;
if (module == null)
{
// No assembly specified: look in all assemblies, but prefer the current assembly
if (context.CurrentModule != null)
{
type = context.CurrentModule.GetTypeDefinition(fullTypeName);
}
if (type == null)
{
type = ResolveInAllAssemblies(context.Compilation, in fullTypeName);
}
}
else
{
// Assembly specified: only look in the specified assembly.
// But if that's not loaded in the compilation, allow fall back to other assemblies.
// (the non-loaded assembly might be a facade containing type forwarders -
// for example, when referencing a portable library from a non-portable project)
IModule asm = module.Resolve(context);
if (asm != null)
{
type = asm.GetTypeDefinition(fullTypeName);
}
else
{
type = ResolveInAllAssemblies(context.Compilation, in fullTypeName);
}
}
return type ?? new UnknownType(fullTypeName, isReferenceType);
}
public override string ToString()
{
return fullTypeName.ToString() + (module != null ? ", " + module.ToString() : null);
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked
{
return 33 * module.GetHashCode() + fullTypeName.GetHashCode();
}
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
GetClassTypeReference o = other as GetClassTypeReference;
return o != null && module == o.module && fullTypeName == o.fullTypeName && isReferenceType == o.isReferenceType;
}
}
}

226
ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs

@ -17,7 +17,6 @@ @@ -17,7 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata;
@ -257,231 +256,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -257,231 +256,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
static bool IsReflectionNameSpecialCharacter(char c)
{
switch (c)
{
case '+':
case '`':
case '[':
case ']':
case ',':
case '*':
case '&':
return true;
default:
return false;
}
}
/// <summary>
/// Parses the reflection name starting at pos.
/// If local is true, only parses local type names, not assembly qualified type names.
/// </summary>
static ITypeReference ParseReflectionName(string reflectionTypeName, ref int pos, bool local = false)
{
if (pos == reflectionTypeName.Length)
throw new ReflectionNameParseException(pos, "Unexpected end");
ITypeReference reference;
if (reflectionTypeName[pos] == '`')
{
// type parameter reference
pos++;
if (pos == reflectionTypeName.Length)
throw new ReflectionNameParseException(pos, "Unexpected end");
if (reflectionTypeName[pos] == '`')
{
// method type parameter reference
pos++;
int index = ReadTypeParameterCount(reflectionTypeName, ref pos);
reference = TypeParameterReference.Create(SymbolKind.Method, index);
}
else
{
// class type parameter reference
int index = ReadTypeParameterCount(reflectionTypeName, ref pos);
reference = TypeParameterReference.Create(SymbolKind.TypeDefinition, index);
}
}
else
{
// not a type parameter reference: read the actual type name
string typeName = ReadTypeName(reflectionTypeName, ref pos, out int tpc);
string assemblyName = local ? null : SkipAheadAndReadAssemblyName(reflectionTypeName, pos);
reference = CreateGetClassTypeReference(assemblyName, typeName, tpc);
}
// read type suffixes
while (pos < reflectionTypeName.Length)
{
switch (reflectionTypeName[pos++])
{
case '+':
int tpc;
string typeName = ReadTypeName(reflectionTypeName, ref pos, out tpc);
reference = new NestedTypeReference(reference, typeName, tpc);
break;
case '*':
reference = new PointerTypeReference(reference);
break;
case '&':
reference = new ByReferenceTypeReference(reference);
break;
case '[':
// this might be an array or a generic type
if (pos == reflectionTypeName.Length)
throw new ReflectionNameParseException(pos, "Unexpected end");
if (reflectionTypeName[pos] != ']' && reflectionTypeName[pos] != ',')
{
// it's a generic type
List<ITypeReference> typeArguments = new List<ITypeReference>();
bool first = true;
while (first || pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',')
{
if (first)
{
first = false;
}
else
{
pos++; // skip ','
}
if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == '[')
{
// non-local type names are enclosed in another set of []
pos++;
typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos));
if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
pos++;
else
throw new ReflectionNameParseException(pos, "Expected end of type argument");
}
else
{
// local type names occur directly in the outer []
typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos, local: true));
}
}
if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
{
pos++;
reference = new ParameterizedTypeReference(reference, typeArguments);
}
else
{
throw new ReflectionNameParseException(pos, "Expected end of generic type");
}
}
else
{
// it's an array
int dimensions = 1;
while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',')
{
dimensions++;
pos++;
}
if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
{
pos++; // end of array
reference = new ArrayTypeReference(reference, dimensions);
}
else
{
throw new ReflectionNameParseException(pos, "Invalid array modifier");
}
}
break;
case ',' when !local:
// assembly qualified name, ignore everything up to the end/next ']'
while (pos < reflectionTypeName.Length && reflectionTypeName[pos] != ']')
pos++;
break;
default:
pos--; // reset pos to the character we couldn't read
if (reflectionTypeName[pos] == ']' || reflectionTypeName[pos] == ',')
return reference; // return from a nested generic
else
throw new ReflectionNameParseException(pos, "Unexpected character: '" + reflectionTypeName[pos] + "'");
}
}
return reference;
}
static ITypeReference CreateGetClassTypeReference(string assemblyName, string typeName, int tpc)
{
IModuleReference assemblyReference;
if (assemblyName != null)
{
assemblyReference = new DefaultAssemblyReference(assemblyName);
}
else
{
assemblyReference = null;
}
int pos = typeName.LastIndexOf('.');
if (pos < 0)
return new GetClassTypeReference(assemblyReference, string.Empty, typeName, tpc);
else
return new GetClassTypeReference(assemblyReference, typeName.Substring(0, pos), typeName.Substring(pos + 1), tpc);
}
static string SkipAheadAndReadAssemblyName(string reflectionTypeName, int pos)
{
int nestingLevel = 0;
while (pos < reflectionTypeName.Length)
{
switch (reflectionTypeName[pos++])
{
case '[':
nestingLevel++;
break;
case ']':
if (nestingLevel == 0)
return null;
nestingLevel--;
break;
case ',':
if (nestingLevel == 0)
{
// first skip the whitespace
while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ' ')
pos++;
// everything up to the end/next ']' is the assembly name
int endPos = pos;
while (endPos < reflectionTypeName.Length && reflectionTypeName[endPos] != ']')
endPos++;
return reflectionTypeName.Substring(pos, endPos - pos);
}
break;
}
}
return null;
}
static string ReadTypeName(string reflectionTypeName, ref int pos, out int tpc)
{
int startPos = pos;
// skip the simple name portion:
while (pos < reflectionTypeName.Length && !IsReflectionNameSpecialCharacter(reflectionTypeName[pos]))
pos++;
if (pos == startPos)
throw new ReflectionNameParseException(pos, "Expected type name");
string typeName = reflectionTypeName.Substring(startPos, pos - startPos);
if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == '`')
{
pos++;
tpc = ReadTypeParameterCount(reflectionTypeName, ref pos);
}
else
{
tpc = 0;
}
return typeName;
}
internal static int ReadTypeParameterCount(string reflectionTypeName, ref int pos)
{
int startPos = pos;

38
ICSharpCode.Decompiler/TypeSystem/TupleType.cs

@ -375,44 +375,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -375,44 +375,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public class TupleTypeReference : ITypeReference
{
/// <summary>
/// Gets the types of the tuple elements.
/// </summary>
public ImmutableArray<ITypeReference> ElementTypes { get; }
/// <summary>
/// Gets the names of the tuple elements.
/// </summary>
public ImmutableArray<string> ElementNames { get; }
public IModuleReference ValueTupleAssembly { get; }
public TupleTypeReference(ImmutableArray<ITypeReference> elementTypes)
{
this.ElementTypes = elementTypes;
}
public TupleTypeReference(ImmutableArray<ITypeReference> elementTypes,
ImmutableArray<string> elementNames = default(ImmutableArray<string>),
IModuleReference valueTupleAssembly = null)
{
this.ValueTupleAssembly = valueTupleAssembly;
this.ElementTypes = elementTypes;
this.ElementNames = elementNames;
}
public IType Resolve(ITypeResolveContext context)
{
return new TupleType(context.Compilation,
ElementTypes.Select(t => t.Resolve(context)).ToImmutableArray(),
ElementNames,
ValueTupleAssembly?.Resolve(context)
);
}
}
public static class TupleTypeExtensions
{
public static IType TupleUnderlyingTypeOrSelf(this IType type)

9
ICSharpCode.Decompiler/TypeSystem/TypeProvider.cs

@ -148,14 +148,19 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -148,14 +148,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
IModule resolvedModule = module?.GetDeclaringModule(handle);
var fullTypeName = handle.GetFullTypeName(reader);
IType type;
IType type = null;
if (resolvedModule != null)
{
type = resolvedModule.GetTypeDefinition(fullTypeName);
}
else
{
type = GetClassTypeReference.ResolveInAllAssemblies(compilation, in fullTypeName);
foreach (var asm in compilation.Modules)
{
type = asm.GetTypeDefinition(fullTypeName);
if (type != null)
return type;
}
}
return type ?? new UnknownType(fullTypeName, IsReferenceType(reader, handle, rawTypeKind));
}

Loading…
Cancel
Save