Browse Source

C# 2.0 mode now disables extension methods.

pull/1198/head
Daniel Grunwald 7 years ago
parent
commit
629e586b25
  1. 84
      ICSharpCode.Decompiler/CSharp/TypeSystem/AttributeTypeReference.cs
  2. 13
      ICSharpCode.Decompiler/DecompilerSettings.cs
  3. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  4. 15
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  5. 23
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs
  6. 19
      ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs

84
ICSharpCode.Decompiler/CSharp/TypeSystem/AttributeTypeReference.cs

@ -1,84 +0,0 @@ @@ -1,84 +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.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.TypeSystem
{
/// <summary>
/// Type reference used within an attribute.
/// Looks up both 'withoutSuffix' and 'withSuffix' and returns the type that exists.
/// </summary>
[Serializable]
public sealed class AttributeTypeReference : ITypeReference, ISupportsInterning
{
readonly ITypeReference withoutSuffix, withSuffix;
public AttributeTypeReference(ITypeReference withoutSuffix, ITypeReference withSuffix)
{
if (withoutSuffix == null)
throw new ArgumentNullException("withoutSuffix");
if (withSuffix == null)
throw new ArgumentNullException("withSuffix");
this.withoutSuffix = withoutSuffix;
this.withSuffix = withSuffix;
}
public IType Resolve(ITypeResolveContext context)
{
IType t1 = withoutSuffix.Resolve(context);
IType t2 = withSuffix.Resolve(context);
return PreferAttributeTypeWithSuffix(t1, t2, context.Compilation) ? t2 : t1;
}
internal static bool PreferAttributeTypeWithSuffix(IType t1, IType t2, ICompilation compilation)
{
if (t2.Kind == TypeKind.Unknown) return false;
if (t1.Kind == TypeKind.Unknown) return true;
var attrTypeDef = compilation.FindType(KnownTypeCode.Attribute).GetDefinition();
if (attrTypeDef != null) {
bool t1IsAttribute = (t1.GetDefinition() != null && t1.GetDefinition().IsDerivedFrom(attrTypeDef));
bool t2IsAttribute = (t2.GetDefinition() != null && t2.GetDefinition().IsDerivedFrom(attrTypeDef));
if (t2IsAttribute && !t1IsAttribute)
return true;
// If both types exist and are attributes, C# considers that to be an ambiguity, but we are less strict.
}
return false;
}
public override string ToString()
{
return withoutSuffix.ToString() + "[Attribute]";
}
int ISupportsInterning.GetHashCodeForInterning()
{
unchecked {
return withoutSuffix.GetHashCode() + 715613 * withSuffix.GetHashCode();
}
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
AttributeTypeReference atr = other as AttributeTypeReference;
return atr != null && this.withoutSuffix == atr.withoutSuffix && this.withSuffix == atr.withSuffix;
}
}
}

13
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -55,6 +55,7 @@ namespace ICSharpCode.Decompiler @@ -55,6 +55,7 @@ namespace ICSharpCode.Decompiler
anonymousTypes = false;
objectCollectionInitializers = false;
automaticProperties = false;
extensionMethods = false;
queryExpressions = false;
expressionTrees = false;
}
@ -353,6 +354,18 @@ namespace ICSharpCode.Decompiler @@ -353,6 +354,18 @@ namespace ICSharpCode.Decompiler
}
}
bool extensionMethods = true;
public bool ExtensionMethods {
get { return extensionMethods; }
set {
if (extensionMethods != value) {
extensionMethods = value;
OnPropertyChanged();
}
}
}
bool queryExpressions = true;
public bool QueryExpressions {

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -238,7 +238,6 @@ @@ -238,7 +238,6 @@
<Compile Include="CSharp\Transforms\RemoveCLSCompliantAttribute.cs" />
<Compile Include="CSharp\TranslationContext.cs" />
<Compile Include="CSharp\TypeSystem\AliasNamespaceReference.cs" />
<Compile Include="CSharp\TypeSystem\AttributeTypeReference.cs" />
<Compile Include="CSharp\TypeSystem\CSharpTypeResolveContext.cs" />
<Compile Include="CSharp\TypeSystem\MemberTypeOrNamespaceReference.cs" />
<Compile Include="CSharp\TypeSystem\MethodTypeParameterWithInheritedConstraints.cs" />

15
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -50,6 +50,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -50,6 +50,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
ShortenInterfaceImplNames = false,
UseDynamicType = settings.Dynamic,
UseTupleTypes = settings.TupleTypes,
UseExtensionMethods = settings.ExtensionMethods,
};
IUnresolvedAssembly mainAssembly = loader.LoadModule(moduleDefinition);
// Load referenced assemblies and type-forwarder references.
@ -209,10 +210,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -209,10 +210,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
break;
case SRM.HandleKind.MemberReference:
var memberRef = metadata.GetMemberReference((SRM.MemberReferenceHandle)fieldReference);
var memberRefHandle = (SRM.MemberReferenceHandle)fieldReference;
var memberRef = metadata.GetMemberReference(memberRefHandle);
Debug.Assert(memberRef.GetKind() == SRM.MemberReferenceKind.Field);
declaringType = ResolveDeclaringType(memberRef.Parent);
field = FindNonGenericField(metadata, memberRef, declaringType);
field = FindNonGenericField(metadata, memberRefHandle, declaringType);
break;
default:
throw new NotSupportedException();
@ -226,11 +228,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -226,11 +228,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
IField FindNonGenericField(SRM.MetadataReader metadata, SRM.MemberReference memberRef, IType declaringType)
IField FindNonGenericField(SRM.MetadataReader metadata, SRM.MemberReferenceHandle memberRefHandle, IType declaringType)
{
var memberRef = metadata.GetMemberReference(memberRefHandle);
string name = metadata.GetString(memberRef.Name);
ITypeDefinition typeDef = declaringType.GetDefinition();
ITypeReference returnType = memberRef.DecodeFieldSignature(TypeReferenceSignatureDecoder.Instance, default);
ITypeReference returnType = new FieldTypeReference(memberRefHandle, metadata, typeAttributeOptions);
if (typeDef == null)
return CreateFakeField(declaringType, name, returnType);
@ -299,9 +302,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -299,9 +302,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
case SRM.HandleKind.MethodSpecification:
var methodSpec = metadata.GetMethodSpecification((SRM.MethodSpecificationHandle)methodReference);
method = FindNonGenericMethod(metadata, methodSpec.Method, out declaringType);
var typeArguments = methodSpec.DecodeSignature(TypeReferenceSignatureDecoder.Instance, default);
var typeArguments = methodSpec.DecodeSignature(new TypeProvider(context.CurrentAssembly), default);
if (typeArguments.Length > 0) {
methodTypeArguments = typeArguments.SelectArray(arg => arg.Resolve(context));
methodTypeArguments = typeArguments;
}
break;
default:

23
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
sealed class FieldTypeReference : ITypeReference
{
readonly SRM.FieldDefinitionHandle fieldHandle;
readonly SRM.EntityHandle fieldHandle;
readonly SRM.MetadataReader metadata;
readonly TypeAttributeOptions attributeOptions;
@ -95,10 +95,27 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -95,10 +95,27 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.metadata = metadata;
this.attributeOptions = attributeOptions;
}
public FieldTypeReference(SRM.MemberReferenceHandle fieldReferenceHandle,
SRM.MetadataReader metadata,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
{
this.fieldHandle = fieldReferenceHandle;
this.metadata = metadata;
this.attributeOptions = attributeOptions;
}
IType ITypeReference.Resolve(ITypeResolveContext context)
{
return Resolve(fieldHandle, metadata, context, attributeOptions);
if (fieldHandle.Kind == SRM.HandleKind.FieldDefinition) {
return Resolve((SRM.FieldDefinitionHandle)fieldHandle, metadata, context, attributeOptions);
} else {
var memberRef = metadata.GetMemberReference((SRM.MemberReferenceHandle)fieldHandle);
IType ty = memberRef.DecodeFieldSignature(new TypeProvider(context.CurrentAssembly), context);
ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, context.Compilation,
memberRef.GetCustomAttributes(), metadata, attributeOptions);
return ty;
}
}
public static IType Resolve(SRM.FieldDefinitionHandle fieldHandle,

19
ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs

@ -59,6 +59,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -59,6 +59,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
public bool UseTupleTypes { get; set; } = true;
/// <summary>
/// Gets/Sets whether to use extension methods.
/// </summary>
public bool UseExtensionMethods { get; set; } = true;
/// <summary>
/// Gets/Sets the cancellation token used by the assembly loader.
/// </summary>
@ -133,6 +138,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -133,6 +138,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
this.ShortenInterfaceImplNames = loader.ShortenInterfaceImplNames;
this.UseDynamicType = loader.UseDynamicType;
this.UseTupleTypes = loader.UseTupleTypes;
this.UseExtensionMethods = loader.UseExtensionMethods;
this.currentModule = loader.currentModule;
this.currentMetadata = loader.currentMetadata;
this.currentAssembly = loader.currentAssembly;
@ -693,7 +699,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -693,7 +699,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
case "TupleElementNamesAttribute":
return UseTupleTypes;
case "ExtensionAttribute":
return true; // TODO: shouldn't we disable extension methods in C# 2.0 mode?
return UseExtensionMethods;
case "DecimalConstantAttribute":
return true;
default:
@ -821,7 +827,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -821,7 +827,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
foreach (FieldDefinitionHandle h in typeDefinition.GetFields()) {
var enumField = currentMetadata.GetFieldDefinition(h);
if (!enumField.HasFlag(FieldAttributes.Static)) {
baseTypes.Add(enumField.DecodeSignature(TypeReferenceSignatureDecoder.Instance, default));
baseTypes.Add(new FieldTypeReference(h, currentMetadata, TypeAttributeOptions.None));
break;
}
}
@ -1040,7 +1046,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1040,7 +1046,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
loader.InitTypeParameterConstraints(td, typeParameters);
loader.AddAttributes(td, this);
flags[FlagHasExtensionMethods] = HasExtensionAttribute(metadata, td.GetCustomAttributes());
flags[FlagHasExtensionMethods] = loader.HasExtensionAttribute(metadata, td.GetCustomAttributes());
this.ApplyInterningProvider(loader.interningProvider);
this.Freeze();
@ -1346,12 +1352,13 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1346,12 +1352,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
=> SignatureTypeCode.TypeHandle;
}
static bool HasExtensionAttribute(MetadataReader metadata, CustomAttributeHandleCollection attributes)
bool HasExtensionAttribute(MetadataReader metadata, CustomAttributeHandleCollection attributes)
{
if (!UseExtensionMethods)
return false;
foreach (var h in attributes) {
var attr = metadata.GetCustomAttribute(h);
var type = attr.GetAttributeType(metadata);
if (type.IsTopLevelType(metadata, "System.Runtime.CompilerServices", "ExtensionAttribute"))
if (attr.IsAttributeType(metadata, "System.Runtime.CompilerServices", "ExtensionAttribute"))
return true;
}
return false;

Loading…
Cancel
Save