summaryrefslogtreecommitdiff
path: root/ICSharpCode.Decompiler/Ast/AstBuilder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ICSharpCode.Decompiler/Ast/AstBuilder.cs')
-rw-r--r--ICSharpCode.Decompiler/Ast/AstBuilder.cs1687
1 files changed, 0 insertions, 1687 deletions
diff --git a/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/ICSharpCode.Decompiler/Ast/AstBuilder.cs
deleted file mode 100644
index 9a53237a..00000000
--- a/ICSharpCode.Decompiler/Ast/AstBuilder.cs
+++ /dev/null
@@ -1,1687 +0,0 @@
-// Copyright (c) 2011 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.Concurrent;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-using ICSharpCode.Decompiler;
-using ICSharpCode.Decompiler.Ast.Transforms;
-using ICSharpCode.Decompiler.ILAst;
-using ICSharpCode.NRefactory.CSharp;
-using ICSharpCode.NRefactory.Utils;
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-
-namespace ICSharpCode.Decompiler.Ast
-{
- using Ast = NRefactory.CSharp;
- using VarianceModifier = NRefactory.TypeSystem.VarianceModifier;
-
- [Flags]
- public enum ConvertTypeOptions
- {
- None = 0,
- IncludeNamespace = 1,
- IncludeTypeParameterDefinitions = 2,
- DoNotUsePrimitiveTypeNames = 4
- }
-
- public class AstBuilder
- {
- DecompilerContext context;
- SyntaxTree syntaxTree = new SyntaxTree();
- Dictionary<string, NamespaceDeclaration> astNamespaces = new Dictionary<string, NamespaceDeclaration>();
- bool transformationsHaveRun;
-
- public AstBuilder(DecompilerContext context)
- {
- if (context == null)
- throw new ArgumentNullException("context");
- this.context = context;
- DecompileMethodBodies = true;
- }
-
- public static bool MemberIsHidden(MemberReference member, DecompilerSettings settings)
- {
- MethodDefinition method = member as MethodDefinition;
- if (method != null) {
- if (method.IsGetter || method.IsSetter || method.IsAddOn || method.IsRemoveOn)
- return true;
- if (settings.AnonymousMethods && method.HasGeneratedName() && method.IsCompilerGenerated())
- return true;
- }
-
- TypeDefinition type = member as TypeDefinition;
- if (type != null) {
- if (type.DeclaringType != null) {
- if (settings.AnonymousMethods && IsClosureType(type))
- return true;
- if (settings.YieldReturn && YieldReturnDecompiler.IsCompilerGeneratorEnumerator(type))
- return true;
- if (settings.AsyncAwait && AsyncDecompiler.IsCompilerGeneratedStateMachine(type))
- return true;
- } else if (type.IsCompilerGenerated()) {
- if (type.Name.StartsWith("<PrivateImplementationDetails>", StringComparison.Ordinal))
- return true;
- if (type.IsAnonymousType())
- return true;
- }
- }
-
- FieldDefinition field = member as FieldDefinition;
- if (field != null) {
- if (field.IsCompilerGenerated()) {
- if (settings.AnonymousMethods && IsAnonymousMethodCacheField(field))
- return true;
- if (settings.AutomaticProperties && IsAutomaticPropertyBackingField(field))
- return true;
- if (settings.SwitchStatementOnString && IsSwitchOnStringCache(field))
- return true;
- }
- // event-fields are not [CompilerGenerated]
- if (settings.AutomaticEvents && field.DeclaringType.Events.Any(ev => ev.Name == field.Name))
- return true;
- }
-
- return false;
- }
-
- static bool IsSwitchOnStringCache(FieldDefinition field)
- {
- return field.Name.StartsWith("<>f__switch", StringComparison.Ordinal);
- }
-
- static bool IsAutomaticPropertyBackingField(FieldDefinition field)
- {
- return field.HasGeneratedName() && field.Name.EndsWith("BackingField", StringComparison.Ordinal);
- }
-
- static bool IsAnonymousMethodCacheField(FieldDefinition field)
- {
- return field.Name.StartsWith("CS$<>", StringComparison.Ordinal) || field.Name.StartsWith("<>f__am", StringComparison.Ordinal);
- }
-
- static bool IsClosureType(TypeDefinition type)
- {
- return type.HasGeneratedName() && type.IsCompilerGenerated() && (type.Name.Contains("DisplayClass") || type.Name.Contains("AnonStorey"));
- }
-
- /// <summary>
- /// Runs the C# transformations on the compilation unit.
- /// </summary>
- public void RunTransformations()
- {
- RunTransformations(null);
- }
-
- public void RunTransformations(Predicate<IAstTransform> transformAbortCondition)
- {
- TransformationPipeline.RunTransformationsUntil(syntaxTree, transformAbortCondition, context);
- transformationsHaveRun = true;
- }
-
- /// <summary>
- /// Gets the abstract source tree.
- /// </summary>
- public SyntaxTree SyntaxTree {
- get { return syntaxTree; }
- }
-
- /// <summary>
- /// Generates C# code from the abstract source tree.
- /// </summary>
- public void GenerateCode(ITextOutput output)
- {
- if (!transformationsHaveRun)
- RunTransformations();
-
- syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
- var outputFormatter = new TextTokenWriter(output, context) { FoldBraces = context.Settings.FoldBraces };
- var formattingPolicy = context.Settings.CSharpFormattingOptions;
- syntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy));
- }
-
- public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
- {
- AddAssembly(assemblyDefinition.MainModule, onlyAssemblyLevel);
- }
-
- public void AddAssembly(ModuleDefinition moduleDefinition, bool onlyAssemblyLevel = false)
- {
- if (moduleDefinition.Assembly != null && moduleDefinition.Assembly.Name.Version != null) {
- syntaxTree.AddChild(
- new AttributeSection {
- AttributeTarget = "assembly",
- Attributes = {
- new NRefactory.CSharp.Attribute {
- Type = new SimpleType("AssemblyVersion")
- .WithAnnotation(new TypeReference(
- "System.Reflection", "AssemblyVersionAttribute",
- moduleDefinition, moduleDefinition.TypeSystem.Corlib)),
- Arguments = {
- new PrimitiveExpression(moduleDefinition.Assembly.Name.Version.ToString())
- }
- }
- }
- }, EntityDeclaration.AttributeRole);
- }
-
- if (moduleDefinition.Assembly != null) {
- ConvertCustomAttributes(syntaxTree, moduleDefinition.Assembly, "assembly");
- ConvertSecurityAttributes(syntaxTree, moduleDefinition.Assembly, "assembly");
- }
- ConvertCustomAttributes(syntaxTree, moduleDefinition, "module");
- AddTypeForwarderAttributes(syntaxTree, moduleDefinition, "assembly");
-
- if (!onlyAssemblyLevel) {
- foreach (TypeDefinition typeDef in moduleDefinition.Types) {
- // Skip the <Module> class
- if (typeDef.Name == "<Module>") continue;
- // Skip any hidden types
- if (MemberIsHidden(typeDef, context.Settings))
- continue;
-
- AddType(typeDef);
- }
- }
- }
-
- void AddTypeForwarderAttributes(SyntaxTree astCompileUnit, ModuleDefinition module, string target)
- {
- if (!module.HasExportedTypes)
- return;
- foreach (ExportedType type in module.ExportedTypes) {
- if (type.IsForwarder) {
- var forwardedType = CreateTypeOfExpression(new TypeReference(type.Namespace, type.Name, module, type.Scope));
- astCompileUnit.AddChild(
- new AttributeSection {
- AttributeTarget = target,
- Attributes = {
- new NRefactory.CSharp.Attribute {
- Type = new SimpleType("TypeForwardedTo")
- .WithAnnotation(new TypeReference(
- "System.Runtime.CompilerServices", "TypeForwardedToAttribute",
- module, module.TypeSystem.Corlib)),
- Arguments = { forwardedType }
- }
- }
- }, EntityDeclaration.AttributeRole);
- }
- }
- }
-
- NamespaceDeclaration GetCodeNamespace(string name)
- {
- if (string.IsNullOrEmpty(name)) {
- return null;
- }
- if (astNamespaces.ContainsKey(name)) {
- return astNamespaces[name];
- } else {
- // Create the namespace
- NamespaceDeclaration astNamespace = new NamespaceDeclaration { Name = name };
- syntaxTree.Members.Add(astNamespace);
- astNamespaces[name] = astNamespace;
- return astNamespace;
- }
- }
-
- public void AddType(TypeDefinition typeDef)
- {
- var astType = CreateType(typeDef);
- NamespaceDeclaration astNS = GetCodeNamespace(typeDef.Namespace);
- if (astNS != null) {
- astNS.Members.Add(astType);
- } else {
- syntaxTree.Members.Add(astType);
- }
- }
-
- public void AddMethod(MethodDefinition method)
- {
- AstNode node = method.IsConstructor ? (AstNode)CreateConstructor(method) : CreateMethod(method);
- syntaxTree.Members.Add(node);
- }
-
- public void AddProperty(PropertyDefinition property)
- {
- syntaxTree.Members.Add(CreateProperty(property));
- }
-
- public void AddField(FieldDefinition field)
- {
- syntaxTree.Members.Add(CreateField(field));
- }
-
- public void AddEvent(EventDefinition ev)
- {
- syntaxTree.Members.Add(CreateEvent(ev));
- }
-
- /// <summary>
- /// Creates the AST for a type definition.
- /// </summary>
- /// <param name="typeDef"></param>
- /// <returns>TypeDeclaration or DelegateDeclaration.</returns>
- public EntityDeclaration CreateType(TypeDefinition typeDef)
- {
- // create type
- TypeDefinition oldCurrentType = context.CurrentType;
- context.CurrentType = typeDef;
- TypeDeclaration astType = new TypeDeclaration();
- ConvertAttributes(astType, typeDef);
- astType.AddAnnotation(typeDef);
- astType.Modifiers = ConvertModifiers(typeDef);
- astType.Name = CleanName(typeDef.Name);
-
- if (typeDef.IsEnum) { // NB: Enum is value type
- astType.ClassType = ClassType.Enum;
- astType.Modifiers &= ~Modifiers.Sealed;
- } else if (typeDef.IsValueType) {
- astType.ClassType = ClassType.Struct;
- astType.Modifiers &= ~Modifiers.Sealed;
- } else if (typeDef.IsInterface) {
- astType.ClassType = ClassType.Interface;
- astType.Modifiers &= ~Modifiers.Abstract;
- } else {
- astType.ClassType = ClassType.Class;
- }
-
- IEnumerable<GenericParameter> genericParameters = typeDef.GenericParameters;
- if (typeDef.DeclaringType != null && typeDef.DeclaringType.HasGenericParameters)
- genericParameters = genericParameters.Skip(typeDef.DeclaringType.GenericParameters.Count);
- astType.TypeParameters.AddRange(MakeTypeParameters(genericParameters));
- astType.Constraints.AddRange(MakeConstraints(genericParameters));
-
- EntityDeclaration result = astType;
- if (typeDef.IsEnum) {
- long expectedEnumMemberValue = 0;
- bool forcePrintingInitializers = IsFlagsEnum(typeDef);
- TypeCode baseType = TypeCode.Int32;
- foreach (FieldDefinition field in typeDef.Fields) {
- if (!field.IsStatic) {
- // the value__ field
- if (field.FieldType != typeDef.Module.TypeSystem.Int32) {
- astType.AddChild(ConvertType(field.FieldType), Roles.BaseType);
- baseType = TypeAnalysis.GetTypeCode(field.FieldType);
- }
- } else {
- EnumMemberDeclaration enumMember = new EnumMemberDeclaration();
- enumMember.AddAnnotation(field);
- enumMember.Name = CleanName(field.Name);
- long memberValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false);
- if (forcePrintingInitializers || memberValue != expectedEnumMemberValue) {
- enumMember.AddChild(new PrimitiveExpression(CSharpPrimitiveCast.Cast(baseType, field.Constant, false)), EnumMemberDeclaration.InitializerRole);
- }
- expectedEnumMemberValue = memberValue + 1;
- astType.AddChild(enumMember, Roles.TypeMemberRole);
- }
- }
- } else if (typeDef.BaseType != null && typeDef.BaseType.FullName == "System.MulticastDelegate") {
- DelegateDeclaration dd = new DelegateDeclaration();
- dd.Modifiers = astType.Modifiers & ~Modifiers.Sealed;
- dd.Name = astType.Name;
- dd.AddAnnotation(typeDef);
- astType.Attributes.MoveTo(dd.Attributes);
- astType.TypeParameters.MoveTo(dd.TypeParameters);
- astType.Constraints.MoveTo(dd.Constraints);
- foreach (var m in typeDef.Methods) {
- if (m.Name == "Invoke") {
- dd.ReturnType = ConvertType(m.ReturnType, m.MethodReturnType);
- dd.Parameters.AddRange(MakeParameters(m));
- ConvertAttributes(dd, m.MethodReturnType, m.Module);
- }
- }
- result = dd;
- } else {
- // Base type
- if (typeDef.BaseType != null && !typeDef.IsValueType && typeDef.BaseType.FullName != "System.Object") {
- astType.AddChild(ConvertType(typeDef.BaseType), Roles.BaseType);
- }
- foreach (var i in typeDef.Interfaces)
- astType.AddChild(ConvertType(i), Roles.BaseType);
-
- AddTypeMembers(astType, typeDef);
-
- if (astType.Members.OfType<IndexerDeclaration>().Any(idx => idx.PrivateImplementationType.IsNull)) {
- // Remove the [DefaultMember] attribute if the class contains indexers
- foreach (AttributeSection section in astType.Attributes) {
- foreach (Ast.Attribute attr in section.Attributes) {
- TypeReference tr = attr.Type.Annotation<TypeReference>();
- if (tr != null && tr.Name == "DefaultMemberAttribute" && tr.Namespace == "System.Reflection") {
- attr.Remove();
- }
- }
- if (section.Attributes.Count == 0)
- section.Remove();
- }
- }
- }
-
- context.CurrentType = oldCurrentType;
- return result;
- }
-
- internal static string CleanName(string name)
- {
- int pos = name.LastIndexOf('`');
- if (pos >= 0)
- name = name.Substring(0, pos);
- pos = name.LastIndexOf('.');
- if (pos >= 0)
- name = name.Substring(pos + 1);
- return name;
- }
-
- #region Create TypeOf Expression
- /// <summary>
- /// Creates a typeof-expression for the specified type.
- /// </summary>
- public static TypeOfExpression CreateTypeOfExpression(TypeReference type)
- {
- return new TypeOfExpression(AddEmptyTypeArgumentsForUnboundGenerics(ConvertType(type)));
- }
-
- static AstType AddEmptyTypeArgumentsForUnboundGenerics(AstType type)
- {
- TypeReference typeRef = type.Annotation<TypeReference>();
- if (typeRef == null)
- return type;
- TypeDefinition typeDef = typeRef.Resolve(); // need to resolve to figure out the number of type parameters
- if (typeDef == null || !typeDef.HasGenericParameters)
- return type;
- SimpleType sType = type as SimpleType;
- MemberType mType = type as MemberType;
- if (sType != null) {
- while (typeDef.GenericParameters.Count > sType.TypeArguments.Count) {
- sType.TypeArguments.Add(new SimpleType(""));
- }
- }
-
- if (mType != null) {
- AddEmptyTypeArgumentsForUnboundGenerics(mType.Target);
-
- int outerTypeParamCount = typeDef.DeclaringType == null ? 0 : typeDef.DeclaringType.GenericParameters.Count;
-
- while (typeDef.GenericParameters.Count - outerTypeParamCount > mType.TypeArguments.Count) {
- mType.TypeArguments.Add(new SimpleType(""));
- }
- }
-
- return type;
- }
- #endregion
-
- #region Convert Type Reference
- /// <summary>
- /// Converts a type reference.
- /// </summary>
- public static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttributes = null, ConvertTypeOptions options = ConvertTypeOptions.None)
- {
- int typeIndex = 0;
- return ConvertType(type, typeAttributes, ref typeIndex, options);
- }
-
- static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttributes, ref int typeIndex, ConvertTypeOptions options)
- {
- while (type is OptionalModifierType || type is RequiredModifierType) {
- type = ((TypeSpecification)type).ElementType;
- }
- if (type == null) {
- return AstType.Null;
- }
-
- if (type is ByReferenceType) {
- typeIndex++;
- // by reference type cannot be represented in C#; so we'll represent it as a pointer instead
- return ConvertType((type as ByReferenceType).ElementType, typeAttributes, ref typeIndex, options)
- .MakePointerType();
- } else if (type is PointerType) {
- typeIndex++;
- return ConvertType((type as PointerType).ElementType, typeAttributes, ref typeIndex, options)
- .MakePointerType();
- } else if (type is ArrayType) {
- typeIndex++;
- return ConvertType((type as ArrayType).ElementType, typeAttributes, ref typeIndex, options)
- .MakeArrayType((type as ArrayType).Rank);
- } else if (type is GenericInstanceType) {
- GenericInstanceType gType = (GenericInstanceType)type;
- if (gType.ElementType.Namespace == "System" && gType.ElementType.Name == "Nullable`1" && gType.GenericArguments.Count == 1) {
- typeIndex++;
- return new ComposedType {
- BaseType = ConvertType(gType.GenericArguments[0], typeAttributes, ref typeIndex, options),
- HasNullableSpecifier = true
- };
- }
- AstType baseType = ConvertType(gType.ElementType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions);
- List<AstType> typeArguments = new List<AstType>();
- foreach (var typeArgument in gType.GenericArguments) {
- typeIndex++;
- typeArguments.Add(ConvertType(typeArgument, typeAttributes, ref typeIndex, options));
- }
- ApplyTypeArgumentsTo(baseType, typeArguments);
- return baseType;
- } else if (type is GenericParameter) {
- return new SimpleType(type.Name);
- } else if (type.IsNested) {
- AstType typeRef = ConvertType(type.DeclaringType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions);
- string namepart = NRefactory.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name);
- MemberType memberType = new MemberType { Target = typeRef, MemberName = namepart };
- memberType.AddAnnotation(type);
- if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) {
- AddTypeParameterDefininitionsTo(type, memberType);
- }
- return memberType;
- } else {
- string ns = type.Namespace ?? string.Empty;
- string name = type.Name;
- if (name == null)
- throw new InvalidOperationException("type.Name returned null. Type: " + type.ToString());
-
- if (name == "Object" && ns == "System" && HasDynamicAttribute(typeAttributes, typeIndex)) {
- return new PrimitiveType("dynamic");
- } else {
- if (ns == "System") {
- if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames)
- != ConvertTypeOptions.DoNotUsePrimitiveTypeNames) {
- switch (name) {
- case "SByte":
- return new PrimitiveType("sbyte");
- case "Int16":
- return new PrimitiveType("short");
- case "Int32":
- return new PrimitiveType("int");
- case "Int64":
- return new PrimitiveType("long");
- case "Byte":
- return new PrimitiveType("byte");
- case "UInt16":
- return new PrimitiveType("ushort");
- case "UInt32":
- return new PrimitiveType("uint");
- case "UInt64":
- return new PrimitiveType("ulong");
- case "String":
- return new PrimitiveType("string");
- case "Single":
- return new PrimitiveType("float");
- case "Double":
- return new PrimitiveType("double");
- case "Decimal":
- return new PrimitiveType("decimal");
- case "Char":
- return new PrimitiveType("char");
- case "Boolean":
- return new PrimitiveType("bool");
- case "Void":
- return new PrimitiveType("void");
- case "Object":
- return new PrimitiveType("object");
- }
- }
- }
-
- name = NRefactory.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(name);
-
- AstType astType;
- if ((options & ConvertTypeOptions.IncludeNamespace) == ConvertTypeOptions.IncludeNamespace && ns.Length > 0) {
- 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] };
- }
- astType = new MemberType { Target = nsType, MemberName = name };
- } else {
- astType = new SimpleType(name);
- }
- astType.AddAnnotation(type);
-
- if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) {
- AddTypeParameterDefininitionsTo(type, astType);
- }
- return astType;
- }
- }
- }
-
- static void AddTypeParameterDefininitionsTo(TypeReference type, AstType astType)
- {
- if (type.HasGenericParameters) {
- List<AstType> typeArguments = new List<AstType>();
- foreach (GenericParameter gp in type.GenericParameters) {
- typeArguments.Add(new SimpleType(gp.Name));
- }
- ApplyTypeArgumentsTo(astType, typeArguments);
- }
- }
-
- static void ApplyTypeArgumentsTo(AstType baseType, List<AstType> typeArguments)
- {
- SimpleType st = baseType as SimpleType;
- if (st != null) {
- st.TypeArguments.AddRange(typeArguments);
- }
- MemberType mt = baseType as MemberType;
- if (mt != null) {
- TypeReference type = mt.Annotation<TypeReference>();
- if (type != null) {
- int typeParameterCount;
- NRefactory.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
- if (typeParameterCount > typeArguments.Count)
- typeParameterCount = typeArguments.Count;
- mt.TypeArguments.AddRange(typeArguments.GetRange(typeArguments.Count - typeParameterCount, typeParameterCount));
- typeArguments.RemoveRange(typeArguments.Count - typeParameterCount, typeParameterCount);
- if (typeArguments.Count > 0)
- ApplyTypeArgumentsTo(mt.Target, typeArguments);
- } else {
- mt.TypeArguments.AddRange(typeArguments);
- }
- }
- }
-
- const string DynamicAttributeFullName = "System.Runtime.CompilerServices.DynamicAttribute";
-
- static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex)
- {
- if (attributeProvider == null || !attributeProvider.HasCustomAttributes)
- return false;
- foreach (CustomAttribute a in attributeProvider.CustomAttributes) {
- if (a.Constructor.DeclaringType.FullName == DynamicAttributeFullName) {
- if (a.ConstructorArguments.Count == 1) {
- CustomAttributeArgument[] values = a.ConstructorArguments[0].Value as CustomAttributeArgument[];
- if (values != null && typeIndex < values.Length && values[typeIndex].Value is bool)
- return (bool)values[typeIndex].Value;
- }
- return true;
- }
- }
- return false;
- }
- #endregion
-
- #region ConvertModifiers
- Modifiers ConvertModifiers(TypeDefinition typeDef)
- {
- Modifiers modifiers = Modifiers.None;
- if (typeDef.IsNestedPrivate)
- modifiers |= Modifiers.Private;
- else if (typeDef.IsNestedAssembly || typeDef.IsNestedFamilyAndAssembly || typeDef.IsNotPublic)
- modifiers |= Modifiers.Internal;
- else if (typeDef.IsNestedFamily)
- modifiers |= Modifiers.Protected;
- else if (typeDef.IsNestedFamilyOrAssembly)
- modifiers |= Modifiers.Protected | Modifiers.Internal;
- else if (typeDef.IsPublic || typeDef.IsNestedPublic)
- modifiers |= Modifiers.Public;
-
- if (typeDef.IsAbstract && typeDef.IsSealed)
- modifiers |= Modifiers.Static;
- else if (typeDef.IsAbstract)
- modifiers |= Modifiers.Abstract;
- else if (typeDef.IsSealed)
- modifiers |= Modifiers.Sealed;
-
- return modifiers;
- }
-
- Modifiers ConvertModifiers(FieldDefinition fieldDef)
- {
- Modifiers modifiers = Modifiers.None;
- if (fieldDef.IsPrivate)
- modifiers |= Modifiers.Private;
- else if (fieldDef.IsAssembly || fieldDef.IsFamilyAndAssembly)
- modifiers |= Modifiers.Internal;
- else if (fieldDef.IsFamily)
- modifiers |= Modifiers.Protected;
- else if (fieldDef.IsFamilyOrAssembly)
- modifiers |= Modifiers.Protected | Modifiers.Internal;
- else if (fieldDef.IsPublic)
- modifiers |= Modifiers.Public;
-
- if (fieldDef.IsLiteral) {
- modifiers |= Modifiers.Const;
- } else {
- if (fieldDef.IsStatic)
- modifiers |= Modifiers.Static;
-
- if (fieldDef.IsInitOnly)
- modifiers |= Modifiers.Readonly;
- }
-
- RequiredModifierType modreq = fieldDef.FieldType as RequiredModifierType;
- if (modreq != null && modreq.ModifierType.FullName == typeof(IsVolatile).FullName)
- modifiers |= Modifiers.Volatile;
-
- return modifiers;
- }
-
- Modifiers ConvertModifiers(MethodDefinition methodDef)
- {
- if (methodDef == null)
- return Modifiers.None;
- Modifiers modifiers = Modifiers.None;
- if (methodDef.IsPrivate)
- modifiers |= Modifiers.Private;
- else if (methodDef.IsAssembly || methodDef.IsFamilyAndAssembly)
- modifiers |= Modifiers.Internal;
- else if (methodDef.IsFamily)
- modifiers |= Modifiers.Protected;
- else if (methodDef.IsFamilyOrAssembly)
- modifiers |= Modifiers.Protected | Modifiers.Internal;
- else if (methodDef.IsPublic)
- modifiers |= Modifiers.Public;
-
- if (methodDef.IsStatic)
- modifiers |= Modifiers.Static;
-
- if (methodDef.IsAbstract) {
- modifiers |= Modifiers.Abstract;
- if (!methodDef.IsNewSlot)
- modifiers |= Modifiers.Override;
- } else if (methodDef.IsFinal) {
- if (!methodDef.IsNewSlot) {
- modifiers |= Modifiers.Sealed | Modifiers.Override;
- }
- } else if (methodDef.IsVirtual) {
- if (methodDef.IsNewSlot)
- modifiers |= Modifiers.Virtual;
- else
- modifiers |= Modifiers.Override;
- }
- if (!methodDef.HasBody && !methodDef.IsAbstract)
- modifiers |= Modifiers.Extern;
-
- return modifiers;
- }
-
- #endregion
-
- void AddTypeMembers(TypeDeclaration astType, TypeDefinition typeDef)
- {
- // Nested types
- foreach (TypeDefinition nestedTypeDef in typeDef.NestedTypes) {
- if (MemberIsHidden(nestedTypeDef, context.Settings))
- continue;
- var nestedType = CreateType(nestedTypeDef);
- SetNewModifier(nestedType);
- astType.AddChild(nestedType, Roles.TypeMemberRole);
- }
-
- // Add fields
- foreach(FieldDefinition fieldDef in typeDef.Fields) {
- if (MemberIsHidden(fieldDef, context.Settings)) continue;
- astType.AddChild(CreateField(fieldDef), Roles.TypeMemberRole);
- }
-
- // Add events
- foreach(EventDefinition eventDef in typeDef.Events) {
- astType.AddChild(CreateEvent(eventDef), Roles.TypeMemberRole);
- }
-
- // Add properties
- foreach(PropertyDefinition propDef in typeDef.Properties) {
- astType.Members.Add(CreateProperty(propDef));
- }
-
- // Add methods
- foreach(MethodDefinition methodDef in typeDef.Methods) {
- if (MemberIsHidden(methodDef, context.Settings)) continue;
-
- if (methodDef.IsConstructor)
- astType.Members.Add(CreateConstructor(methodDef));
- else
- astType.Members.Add(CreateMethod(methodDef));
- }
- }
-
- EntityDeclaration CreateMethod(MethodDefinition methodDef)
- {
- MethodDeclaration astMethod = new MethodDeclaration();
- astMethod.AddAnnotation(methodDef);
- astMethod.ReturnType = ConvertType(methodDef.ReturnType, methodDef.MethodReturnType);
- astMethod.Name = CleanName(methodDef.Name);
- astMethod.TypeParameters.AddRange(MakeTypeParameters(methodDef.GenericParameters));
- astMethod.Parameters.AddRange(MakeParameters(methodDef));
- // constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly
- if (!methodDef.IsVirtual || (methodDef.IsNewSlot && !methodDef.IsPrivate)) astMethod.Constraints.AddRange(MakeConstraints(methodDef.GenericParameters));
- if (!methodDef.DeclaringType.IsInterface) {
- if (IsExplicitInterfaceImplementation(methodDef)) {
- astMethod.PrivateImplementationType = ConvertType(methodDef.Overrides.First().DeclaringType);
- } else {
- astMethod.Modifiers = ConvertModifiers(methodDef);
- if (methodDef.IsVirtual == methodDef.IsNewSlot)
- SetNewModifier(astMethod);
- }
- astMethod.Body = CreateMethodBody(methodDef, astMethod.Parameters);
- if (context.CurrentMethodIsAsync) {
- astMethod.Modifiers |= Modifiers.Async;
- context.CurrentMethodIsAsync = false;
- }
- }
- ConvertAttributes(astMethod, methodDef);
- if (methodDef.HasCustomAttributes && astMethod.Parameters.Count > 0) {
- foreach (CustomAttribute ca in methodDef.CustomAttributes) {
- if (ca.AttributeType.Name == "ExtensionAttribute" && ca.AttributeType.Namespace == "System.Runtime.CompilerServices") {
- astMethod.Parameters.First().ParameterModifier = ParameterModifier.This;
- }
- }
- }
-
- // Convert MethodDeclaration to OperatorDeclaration if possible
- if (methodDef.IsSpecialName && !methodDef.HasGenericParameters) {
- OperatorType? opType = OperatorDeclaration.GetOperatorType(methodDef.Name);
- if (opType.HasValue) {
- OperatorDeclaration op = new OperatorDeclaration();
- op.CopyAnnotationsFrom(astMethod);
- op.ReturnType = astMethod.ReturnType.Detach();
- op.OperatorType = opType.Value;
- op.Modifiers = astMethod.Modifiers;
- astMethod.Parameters.MoveTo(op.Parameters);
- astMethod.Attributes.MoveTo(op.Attributes);
- op.Body = astMethod.Body.Detach();
- return op;
- }
- }
- return astMethod;
- }
-
- bool IsExplicitInterfaceImplementation(MethodDefinition methodDef)
- {
- return methodDef.HasOverrides && methodDef.IsPrivate;
- }
-
- IEnumerable<TypeParameterDeclaration> MakeTypeParameters(IEnumerable<GenericParameter> genericParameters)
- {
- foreach (var gp in genericParameters) {
- TypeParameterDeclaration tp = new TypeParameterDeclaration();
- tp.Name = CleanName(gp.Name);
- if (gp.IsContravariant)
- tp.Variance = VarianceModifier.Contravariant;
- else if (gp.IsCovariant)
- tp.Variance = VarianceModifier.Covariant;
- ConvertCustomAttributes(tp, gp);
- yield return tp;
- }
- }
-
- IEnumerable<Constraint> MakeConstraints(IEnumerable<GenericParameter> genericParameters)
- {
- foreach (var gp in genericParameters) {
- Constraint c = new Constraint();
- c.TypeParameter = new SimpleType(CleanName(gp.Name));
- // class/struct must be first
- if (gp.HasReferenceTypeConstraint)
- c.BaseTypes.Add(new PrimitiveType("class"));
- if (gp.HasNotNullableValueTypeConstraint)
- c.BaseTypes.Add(new PrimitiveType("struct"));
-
- foreach (var constraintType in gp.Constraints) {
- if (gp.HasNotNullableValueTypeConstraint && constraintType.FullName == "System.ValueType")
- continue;
- c.BaseTypes.Add(ConvertType(constraintType));
- }
-
- if (gp.HasDefaultConstructorConstraint && !gp.HasNotNullableValueTypeConstraint)
- c.BaseTypes.Add(new PrimitiveType("new")); // new() must be last
- if (c.BaseTypes.Any())
- yield return c;
- }
- }
-
- ConstructorDeclaration CreateConstructor(MethodDefinition methodDef)
- {
- ConstructorDeclaration astMethod = new ConstructorDeclaration();
- astMethod.AddAnnotation(methodDef);
- astMethod.Modifiers = ConvertModifiers(methodDef);
- if (methodDef.IsStatic) {
- // don't show visibility for static ctors
- astMethod.Modifiers &= ~Modifiers.VisibilityMask;
- }
- astMethod.Name = CleanName(methodDef.DeclaringType.Name);
- astMethod.Parameters.AddRange(MakeParameters(methodDef));
- astMethod.Body = CreateMethodBody(methodDef, astMethod.Parameters);
- ConvertAttributes(astMethod, methodDef);
- if (methodDef.IsStatic && methodDef.DeclaringType.IsBeforeFieldInit && !astMethod.Body.IsNull) {
- astMethod.Body.InsertChildAfter(null, new Comment(" Note: this type is marked as 'beforefieldinit'."), Roles.Comment);
- }
- return astMethod;
- }
-
- Modifiers FixUpVisibility(Modifiers m)
- {
- Modifiers v = m & Modifiers.VisibilityMask;
- // If any of the modifiers is public, use that
- if ((v & Modifiers.Public) == Modifiers.Public)
- return Modifiers.Public | (m & ~Modifiers.VisibilityMask);
- // If both modifiers are private, no need to fix anything
- if (v == Modifiers.Private)
- return m;
- // Otherwise, use the other modifiers (internal and/or protected)
- return m & ~Modifiers.Private;
- }
-
- EntityDeclaration CreateProperty(PropertyDefinition propDef)
- {
- PropertyDeclaration astProp = new PropertyDeclaration();
- astProp.AddAnnotation(propDef);
- var accessor = propDef.GetMethod ?? propDef.SetMethod;
- Modifiers getterModifiers = Modifiers.None;
- Modifiers setterModifiers = Modifiers.None;
- if (IsExplicitInterfaceImplementation(accessor)) {
- astProp.PrivateImplementationType = ConvertType(accessor.Overrides.First().DeclaringType);
- } else if (!propDef.DeclaringType.IsInterface) {
- getterModifiers = ConvertModifiers(propDef.GetMethod);
- setterModifiers = ConvertModifiers(propDef.SetMethod);
- astProp.Modifiers = FixUpVisibility(getterModifiers | setterModifiers);
- try {
- if (accessor.IsVirtual && !accessor.IsNewSlot && (propDef.GetMethod == null || propDef.SetMethod == null)) {
- foreach (var basePropDef in TypesHierarchyHelpers.FindBaseProperties(propDef)) {
- if (basePropDef.GetMethod != null && basePropDef.SetMethod != null) {
- var propVisibilityModifiers = ConvertModifiers(basePropDef.GetMethod) | ConvertModifiers(basePropDef.SetMethod);
- astProp.Modifiers = FixUpVisibility((astProp.Modifiers & ~Modifiers.VisibilityMask) | (propVisibilityModifiers & Modifiers.VisibilityMask));
- break;
- } else if ((basePropDef.GetMethod ?? basePropDef.SetMethod).IsNewSlot) {
- break;
- }
- }
- }
- } catch (ReferenceResolvingException) {
- // TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references.
- }
- }
- astProp.Name = CleanName(propDef.Name);
- astProp.ReturnType = ConvertType(propDef.PropertyType, propDef);
-
- if (propDef.GetMethod != null) {
- astProp.Getter = new Accessor();
- astProp.Getter.Body = CreateMethodBody(propDef.GetMethod);
- astProp.Getter.AddAnnotation(propDef.GetMethod);
- ConvertAttributes(astProp.Getter, propDef.GetMethod);
-
- if ((getterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask))
- astProp.Getter.Modifiers = getterModifiers & Modifiers.VisibilityMask;
- }
- if (propDef.SetMethod != null) {
- astProp.Setter = new Accessor();
- astProp.Setter.Body = CreateMethodBody(propDef.SetMethod);
- astProp.Setter.AddAnnotation(propDef.SetMethod);
- ConvertAttributes(astProp.Setter, propDef.SetMethod);
- ParameterDefinition lastParam = propDef.SetMethod.Parameters.LastOrDefault();
- if (lastParam != null) {
- ConvertCustomAttributes(astProp.Setter, lastParam, "param");
- if (lastParam.HasMarshalInfo) {
- astProp.Setter.Attributes.Add(new AttributeSection(ConvertMarshalInfo(lastParam, propDef.Module)) { AttributeTarget = "param" });
- }
- }
-
- if ((setterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask))
- astProp.Setter.Modifiers = setterModifiers & Modifiers.VisibilityMask;
- }
- ConvertCustomAttributes(astProp, propDef);
-
- EntityDeclaration member = astProp;
- if(propDef.IsIndexer())
- member = ConvertPropertyToIndexer(astProp, propDef);
- if(!accessor.HasOverrides && !accessor.DeclaringType.IsInterface)
- if (accessor.IsVirtual == accessor.IsNewSlot)
- SetNewModifier(member);
- return member;
- }
-
- IndexerDeclaration ConvertPropertyToIndexer(PropertyDeclaration astProp, PropertyDefinition propDef)
- {
- var astIndexer = new IndexerDeclaration();
- astIndexer.CopyAnnotationsFrom(astProp);
- astProp.Attributes.MoveTo(astIndexer.Attributes);
- astIndexer.Modifiers = astProp.Modifiers;
- astIndexer.PrivateImplementationType = astProp.PrivateImplementationType.Detach();
- astIndexer.ReturnType = astProp.ReturnType.Detach();
- astIndexer.Getter = astProp.Getter.Detach();
- astIndexer.Setter = astProp.Setter.Detach();
- astIndexer.Parameters.AddRange(MakeParameters(propDef.Parameters));
- return astIndexer;
- }
-
- EntityDeclaration CreateEvent(EventDefinition eventDef)
- {
- if (eventDef.AddMethod != null && eventDef.AddMethod.IsAbstract) {
- // An abstract event cannot be custom
- EventDeclaration astEvent = new EventDeclaration();
- ConvertCustomAttributes(astEvent, eventDef);
- astEvent.AddAnnotation(eventDef);
- astEvent.Variables.Add(new VariableInitializer(CleanName(eventDef.Name)));
- astEvent.ReturnType = ConvertType(eventDef.EventType, eventDef);
- if (!eventDef.DeclaringType.IsInterface)
- astEvent.Modifiers = ConvertModifiers(eventDef.AddMethod);
- return astEvent;
- } else {
- CustomEventDeclaration astEvent = new CustomEventDeclaration();
- ConvertCustomAttributes(astEvent, eventDef);
- astEvent.AddAnnotation(eventDef);
- astEvent.Name = CleanName(eventDef.Name);
- astEvent.ReturnType = ConvertType(eventDef.EventType, eventDef);
- if (eventDef.AddMethod == null || !IsExplicitInterfaceImplementation(eventDef.AddMethod))
- astEvent.Modifiers = ConvertModifiers(eventDef.AddMethod);
- else
- astEvent.PrivateImplementationType = ConvertType(eventDef.AddMethod.Overrides.First().DeclaringType);
-
- if (eventDef.AddMethod != null) {
- astEvent.AddAccessor = new Accessor {
- Body = CreateMethodBody(eventDef.AddMethod)
- }.WithAnnotation(eventDef.AddMethod);
- ConvertAttributes(astEvent.AddAccessor, eventDef.AddMethod);
- }
- if (eventDef.RemoveMethod != null) {
- astEvent.RemoveAccessor = new Accessor {
- Body = CreateMethodBody(eventDef.RemoveMethod)
- }.WithAnnotation(eventDef.RemoveMethod);
- ConvertAttributes(astEvent.RemoveAccessor, eventDef.RemoveMethod);
- }
- MethodDefinition accessor = eventDef.AddMethod ?? eventDef.RemoveMethod;
- if (accessor.IsVirtual == accessor.IsNewSlot) {
- SetNewModifier(astEvent);
- }
- return astEvent;
- }
- }
-
- public bool DecompileMethodBodies { get; set; }
-
- BlockStatement CreateMethodBody(MethodDefinition method, IEnumerable<ParameterDeclaration> parameters = null)
- {
- if (DecompileMethodBodies)
- return AstMethodBodyBuilder.CreateMethodBody(method, context, parameters);
- else
- return null;
- }
-
- FieldDeclaration CreateField(FieldDefinition fieldDef)
- {
- FieldDeclaration astField = new FieldDeclaration();
- astField.AddAnnotation(fieldDef);
- VariableInitializer initializer = new VariableInitializer(CleanName(fieldDef.Name));
- astField.AddChild(initializer, Roles.Variable);
- astField.ReturnType = ConvertType(fieldDef.FieldType, fieldDef);
- astField.Modifiers = ConvertModifiers(fieldDef);
- if (fieldDef.HasConstant) {
- initializer.Initializer = CreateExpressionForConstant(fieldDef.Constant, fieldDef.FieldType, fieldDef.DeclaringType.IsEnum);
- }
- ConvertAttributes(astField, fieldDef);
- SetNewModifier(astField);
- return astField;
- }
-
- static Expression CreateExpressionForConstant(object constant, TypeReference type, bool isEnumMemberDeclaration = false)
- {
- if (constant == null) {
- if (type.IsValueType && !(type.Namespace == "System" && type.Name == "Nullable`1"))
- return new DefaultValueExpression(ConvertType(type));
- else
- return new NullReferenceExpression();
- } else {
- TypeCode c = Type.GetTypeCode(constant.GetType());
- if (c >= TypeCode.SByte && c <= TypeCode.UInt64 && !isEnumMemberDeclaration) {
- return MakePrimitive((long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constant, false), type);
- } else {
- return new PrimitiveExpression(constant);
- }
- }
- }
-
- public static IEnumerable<ParameterDeclaration> MakeParameters(MethodDefinition method, bool isLambda = false)
- {
- var parameters = MakeParameters(method.Parameters, isLambda);
- if (method.CallingConvention == MethodCallingConvention.VarArg) {
- return parameters.Concat(new[] { new ParameterDeclaration { Type = new PrimitiveType("__arglist") } });
- } else {
- return parameters;
- }
- }
-
- public static IEnumerable<ParameterDeclaration> MakeParameters(IEnumerable<ParameterDefinition> paramCol, bool isLambda = false)
- {
- foreach(ParameterDefinition paramDef in paramCol) {
- ParameterDeclaration astParam = new ParameterDeclaration();
- astParam.AddAnnotation(paramDef);
- if (!(isLambda && paramDef.ParameterType.ContainsAnonymousType()))
- astParam.Type = ConvertType(paramDef.ParameterType, paramDef);
- astParam.Name = paramDef.Name;
-
- if (paramDef.ParameterType is ByReferenceType) {
- astParam.ParameterModifier = (!paramDef.IsIn && paramDef.IsOut) ? ParameterModifier.Out : ParameterModifier.Ref;
- ComposedType ct = astParam.Type as ComposedType;
- if (ct != null && ct.PointerRank > 0)
- ct.PointerRank--;
- }
-
- if (paramDef.HasCustomAttributes) {
- foreach (CustomAttribute ca in paramDef.CustomAttributes) {
- if (ca.AttributeType.Name == "ParamArrayAttribute" && ca.AttributeType.Namespace == "System")
- astParam.ParameterModifier = ParameterModifier.Params;
- }
- }
- if (paramDef.IsOptional) {
- astParam.DefaultExpression = CreateExpressionForConstant(paramDef.Constant, paramDef.ParameterType);
- }
-
- ConvertCustomAttributes(astParam, paramDef);
- ModuleDefinition module = ((MethodDefinition)paramDef.Method).Module;
- if (paramDef.HasMarshalInfo) {
- astParam.Attributes.Add(new AttributeSection(ConvertMarshalInfo(paramDef, module)));
- }
- if (astParam.ParameterModifier != ParameterModifier.Out) {
- if (paramDef.IsIn)
- astParam.Attributes.Add(new AttributeSection(CreateNonCustomAttribute(typeof(InAttribute), module)));
- if (paramDef.IsOut)
- astParam.Attributes.Add(new AttributeSection(CreateNonCustomAttribute(typeof(OutAttribute), module)));
- }
- yield return astParam;
- }
- }
-
- #region ConvertAttributes
- void ConvertAttributes(EntityDeclaration attributedNode, TypeDefinition typeDefinition)
- {
- ConvertCustomAttributes(attributedNode, typeDefinition);
- ConvertSecurityAttributes(attributedNode, typeDefinition);
-
- // Handle the non-custom attributes:
- #region SerializableAttribute
- if (typeDefinition.IsSerializable)
- attributedNode.Attributes.Add(new AttributeSection(CreateNonCustomAttribute(typeof(SerializableAttribute))));
- #endregion
-
- #region ComImportAttribute
- if (typeDefinition.IsImport)
- attributedNode.Attributes.Add(new AttributeSection(CreateNonCustomAttribute(typeof(ComImportAttribute))));
- #endregion
-
- #region StructLayoutAttribute
- LayoutKind layoutKind = LayoutKind.Auto;
- switch (typeDefinition.Attributes & TypeAttributes.LayoutMask) {
- case TypeAttributes.SequentialLayout:
- layoutKind = LayoutKind.Sequential;
- break;
- case TypeAttributes.ExplicitLayout:
- layoutKind = LayoutKind.Explicit;
- break;
- }
- CharSet charSet = CharSet.None;
- switch (typeDefinition.Attributes & TypeAttributes.StringFormatMask) {
- case TypeAttributes.AnsiClass:
- charSet = CharSet.Ansi;
- break;
- case TypeAttributes.AutoClass:
- charSet = CharSet.Auto;
- break;
- case TypeAttributes.UnicodeClass:
- charSet = CharSet.Unicode;
- break;
- }
- LayoutKind defaultLayoutKind = (typeDefinition.IsValueType && !typeDefinition.IsEnum) ? LayoutKind.Sequential: LayoutKind.Auto;
- if (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || typeDefinition.PackingSize > 0 || typeDefinition.ClassSize > 0) {
- var structLayout = CreateNonCustomAttribute(typeof(StructLayoutAttribute));
- structLayout.Arguments.Add(new IdentifierExpression("LayoutKind").Member(layoutKind.ToString()));
- if (charSet != CharSet.Ansi) {
- structLayout.AddNamedArgument("CharSet", new IdentifierExpression("CharSet").Member(charSet.ToString()));
- }
- if (typeDefinition.PackingSize > 0) {
- structLayout.AddNamedArgument("Pack", new PrimitiveExpression((int)typeDefinition.PackingSize));
- }
- if (typeDefinition.ClassSize > 0) {
- structLayout.AddNamedArgument("Size", new PrimitiveExpression((int)typeDefinition.ClassSize));
- }
- attributedNode.Attributes.Add(new AttributeSection(structLayout));
- }
- #endregion
- }
-
- void ConvertAttributes(EntityDeclaration attributedNode, MethodDefinition methodDefinition)
- {
- ConvertCustomAttributes(attributedNode, methodDefinition);
- ConvertSecurityAttributes(attributedNode, methodDefinition);
-
- MethodImplAttributes implAttributes = methodDefinition.ImplAttributes & ~MethodImplAttributes.CodeTypeMask;
-
- #region DllImportAttribute
- if (methodDefinition.HasPInvokeInfo && methodDefinition.PInvokeInfo != null) {
- PInvokeInfo info = methodDefinition.PInvokeInfo;
- Ast.Attribute dllImport = CreateNonCustomAttribute(typeof(DllImportAttribute));
- dllImport.Arguments.Add(new PrimitiveExpression(info.Module.Name));
-
- if (info.IsBestFitDisabled)
- dllImport.AddNamedArgument("BestFitMapping", new PrimitiveExpression(false));
- if (info.IsBestFitEnabled)
- dllImport.AddNamedArgument("BestFitMapping", new PrimitiveExpression(true));
-
- CallingConvention callingConvention;
- switch (info.Attributes & PInvokeAttributes.CallConvMask) {
- case PInvokeAttributes.CallConvCdecl:
- callingConvention = CallingConvention.Cdecl;
- break;
- case PInvokeAttributes.CallConvFastcall:
- callingConvention = CallingConvention.FastCall;
- break;
- case PInvokeAttributes.CallConvStdCall:
- callingConvention = CallingConvention.StdCall;
- break;
- case PInvokeAttributes.CallConvThiscall:
- callingConvention = CallingConvention.ThisCall;
- break;
- case PInvokeAttributes.CallConvWinapi:
- callingConvention = CallingConvention.Winapi;
- break;
- default:
- throw new NotSupportedException("unknown calling convention");
- }
- if (callingConvention != CallingConvention.Winapi)
- dllImport.AddNamedArgument("CallingConvention", new IdentifierExpression("CallingConvention").Member(callingConvention.ToString()));
-
- CharSet charSet = CharSet.None;
- switch (info.Attributes & PInvokeAttributes.CharSetMask) {
- case PInvokeAttributes.CharSetAnsi:
- charSet = CharSet.Ansi;
- break;
- case PInvokeAttributes.CharSetAuto:
- charSet = CharSet.Auto;
- break;
- case PInvokeAttributes.CharSetUnicode:
- charSet = CharSet.Unicode;
- break;
- }
- if (charSet != CharSet.None)
- dllImport.AddNamedArgument("CharSet", new IdentifierExpression("CharSet").Member(charSet.ToString()));
-
- if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != methodDefinition.Name)
- dllImport.AddNamedArgument("EntryPoint", new PrimitiveExpression(info.EntryPoint));
-
- if (info.IsNoMangle)
- dllImport.AddNamedArgument("ExactSpelling", new PrimitiveExpression(true));
-
- if ((implAttributes & MethodImplAttributes.PreserveSig) == MethodImplAttributes.PreserveSig)
- implAttributes &= ~MethodImplAttributes.PreserveSig;
- else
- dllImport.AddNamedArgument("PreserveSig", new PrimitiveExpression(false));
-
- if (info.SupportsLastError)
- dllImport.AddNamedArgument("SetLastError", new PrimitiveExpression(true));
-
- if (info.IsThrowOnUnmappableCharDisabled)
- dllImport.AddNamedArgument("ThrowOnUnmappableChar", new PrimitiveExpression(false));
- if (info.IsThrowOnUnmappableCharEnabled)
- dllImport.AddNamedArgument("ThrowOnUnmappableChar", new PrimitiveExpression(true));
-
- attributedNode.Attributes.Add(new AttributeSection(dllImport));
- }
- #endregion
-
- #region PreserveSigAttribute
- if (implAttributes == MethodImplAttributes.PreserveSig) {
- attributedNode.Attributes.Add(new AttributeSection(CreateNonCustomAttribute(typeof(PreserveSigAttribute))));
- implAttributes = 0;
- }
- #endregion
-
- #region MethodImplAttribute
- if (implAttributes != 0) {
- Ast.Attribute methodImpl = CreateNonCustomAttribute(typeof(MethodImplAttribute));
- TypeReference methodImplOptions = new TypeReference(
- "System.Runtime.CompilerServices", "MethodImplOptions",
- methodDefinition.Module, methodDefinition.Module.TypeSystem.Corlib);
- methodImpl.Arguments.Add(MakePrimitive((long)implAttributes, methodImplOptions));
- attributedNode.Attributes.Add(new AttributeSection(methodImpl));
- }
- #endregion
-
- ConvertAttributes(attributedNode, methodDefinition.MethodReturnType, methodDefinition.Module);
- }
-
- void ConvertAttributes(EntityDeclaration attributedNode, MethodReturnType methodReturnType, ModuleDefinition module)
- {
- ConvertCustomAttributes(attributedNode, methodReturnType, "return");
- if (methodReturnType.HasMarshalInfo) {
- var marshalInfo = ConvertMarshalInfo(methodReturnType, module);
- attributedNode.Attributes.Add(new AttributeSection(marshalInfo) { AttributeTarget = "return" });
- }
- }
-
- internal static void ConvertAttributes(EntityDeclaration attributedNode, FieldDefinition fieldDefinition, string attributeTarget = null)
- {
- ConvertCustomAttributes(attributedNode, fieldDefinition);
-
- #region FieldOffsetAttribute
- if (fieldDefinition.HasLayoutInfo) {
- Ast.Attribute fieldOffset = CreateNonCustomAttribute(typeof(FieldOffsetAttribute), fieldDefinition.Module);
- fieldOffset.Arguments.Add(new PrimitiveExpression(fieldDefinition.Offset));
- attributedNode.Attributes.Add(new AttributeSection(fieldOffset) { AttributeTarget = attributeTarget });
- }
- #endregion
-
- #region NonSerializedAttribute
- if (fieldDefinition.IsNotSerialized) {
- Ast.Attribute nonSerialized = CreateNonCustomAttribute(typeof(NonSerializedAttribute), fieldDefinition.Module);
- attributedNode.Attributes.Add(new AttributeSection(nonSerialized) { AttributeTarget = attributeTarget });
- }
- #endregion
-
- if (fieldDefinition.HasMarshalInfo) {
- attributedNode.Attributes.Add(new AttributeSection(ConvertMarshalInfo(fieldDefinition, fieldDefinition.Module)) { AttributeTarget = attributeTarget });
- }
- }
-
- #region MarshalAsAttribute (ConvertMarshalInfo)
- static Ast.Attribute ConvertMarshalInfo(IMarshalInfoProvider marshalInfoProvider, ModuleDefinition module)
- {
- MarshalInfo marshalInfo = marshalInfoProvider.MarshalInfo;
- Ast.Attribute attr = CreateNonCustomAttribute(typeof(MarshalAsAttribute), module);
- var unmanagedType = new TypeReference("System.Runtime.InteropServices", "UnmanagedType", module, module.TypeSystem.Corlib);
- attr.Arguments.Add(MakePrimitive((int)marshalInfo.NativeType, unmanagedType));
-
- FixedArrayMarshalInfo fami = marshalInfo as FixedArrayMarshalInfo;
- if (fami != null) {
- attr.AddNamedArgument("SizeConst", new PrimitiveExpression(fami.Size));
- if (fami.ElementType != NativeType.None)
- attr.AddNamedArgument("ArraySubType", MakePrimitive((int)fami.ElementType, unmanagedType));
- }
- SafeArrayMarshalInfo sami = marshalInfo as SafeArrayMarshalInfo;
- if (sami != null && sami.ElementType != VariantType.None) {
- var varEnum = new TypeReference("System.Runtime.InteropServices", "VarEnum", module, module.TypeSystem.Corlib);
- attr.AddNamedArgument("SafeArraySubType", MakePrimitive((int)sami.ElementType, varEnum));
- }
- ArrayMarshalInfo ami = marshalInfo as ArrayMarshalInfo;
- if (ami != null) {
- if (ami.ElementType != NativeType.Max)
- attr.AddNamedArgument("ArraySubType", MakePrimitive((int)ami.ElementType, unmanagedType));
- if (ami.Size >= 0)
- attr.AddNamedArgument("SizeConst", new PrimitiveExpression(ami.Size));
- if (ami.SizeParameterMultiplier != 0 && ami.SizeParameterIndex >= 0)
- attr.AddNamedArgument("SizeParamIndex", new PrimitiveExpression(ami.SizeParameterIndex));
- }
- CustomMarshalInfo cmi = marshalInfo as CustomMarshalInfo;
- if (cmi != null) {
- attr.AddNamedArgument("MarshalType", new PrimitiveExpression(cmi.ManagedType.FullName));
- if (!string.IsNullOrEmpty(cmi.Cookie))
- attr.AddNamedArgument("MarshalCookie", new PrimitiveExpression(cmi.Cookie));
- }
- FixedSysStringMarshalInfo fssmi = marshalInfo as FixedSysStringMarshalInfo;
- if (fssmi != null) {
- attr.AddNamedArgument("SizeConst", new PrimitiveExpression(fssmi.Size));
- }
- return attr;
- }
- #endregion
-
- Ast.Attribute CreateNonCustomAttribute(Type attributeType)
- {
- return CreateNonCustomAttribute(attributeType, context.CurrentType != null ? context.CurrentType.Module : null);
- }
-
- static Ast.Attribute CreateNonCustomAttribute(Type attributeType, ModuleDefinition module)
- {
- Debug.Assert(attributeType.Name.EndsWith("Attribute", StringComparison.Ordinal));
- Ast.Attribute attr = new Ast.Attribute();
- attr.Type = new SimpleType(attributeType.Name.Substring(0, attributeType.Name.Length - "Attribute".Length));
- if (module != null) {
- attr.Type.AddAnnotation(new TypeReference(attributeType.Namespace, attributeType.Name, module, module.TypeSystem.Corlib));
- }
- return attr;
- }
-
- static void ConvertCustomAttributes(AstNode attributedNode, ICustomAttributeProvider customAttributeProvider, string attributeTarget = null)
- {
- EntityDeclaration entityDecl = attributedNode as EntityDeclaration;
- if (customAttributeProvider.HasCustomAttributes) {
- var attributes = new List<NRefactory.CSharp.Attribute>();
- foreach (var customAttribute in customAttributeProvider.CustomAttributes.OrderBy(a => a.AttributeType.FullName)) {
- if (customAttribute.AttributeType.Name == "ExtensionAttribute" && customAttribute.AttributeType.Namespace == "System.Runtime.CompilerServices") {
- // don't show the ExtensionAttribute (it's converted to the 'this' modifier)
- continue;
- }
- if (customAttribute.AttributeType.Name == "ParamArrayAttribute" && customAttribute.AttributeType.Namespace == "System") {
- // don't show the ParamArrayAttribute (it's converted to the 'params' modifier)
- continue;
- }
- // if the method is async, remove [DebuggerStepThrough] and [Async
- if (entityDecl != null && entityDecl.HasModifier(Modifiers.Async)) {
- if (customAttribute.AttributeType.Name == "DebuggerStepThroughAttribute" && customAttribute.AttributeType.Namespace == "System.Diagnostics") {
- continue;
- }
- if (customAttribute.AttributeType.Name == "AsyncStateMachineAttribute" && customAttribute.AttributeType.Namespace == "System.Runtime.CompilerServices") {
- continue;
- }
- }
-
- var attribute = new NRefactory.CSharp.Attribute();
- attribute.AddAnnotation(customAttribute);
- attribute.Type = ConvertType(customAttribute.AttributeType);
- attributes.Add(attribute);
-
- SimpleType st = attribute.Type as SimpleType;
- if (st != null && st.Identifier.EndsWith("Attribute", StringComparison.Ordinal)) {
- st.Identifier = st.Identifier.Substring(0, st.Identifier.Length - "Attribute".Length);
- }
-
- if(customAttribute.HasConstructorArguments) {
- foreach (var parameter in customAttribute.ConstructorArguments) {
- Expression parameterValue = ConvertArgumentValue(parameter);
- attribute.Arguments.Add(parameterValue);
- }
- }
- if (customAttribute.HasProperties) {
- TypeDefinition resolvedAttributeType = customAttribute.AttributeType.Resolve();
- foreach (var propertyNamedArg in customAttribute.Properties) {
- var propertyReference = resolvedAttributeType != null ? resolvedAttributeType.Properties.FirstOrDefault(pr => pr.Name == propertyNamedArg.Name) : null;
- var propertyName = new IdentifierExpression(propertyNamedArg.Name).WithAnnotation(propertyReference);
- var argumentValue = ConvertArgumentValue(propertyNamedArg.Argument);
- attribute.Arguments.Add(new AssignmentExpression(propertyName, argumentValue));
- }
- }
-
- if (customAttribute.HasFields) {
- TypeDefinition resolvedAttributeType = customAttribute.AttributeType.Resolve();
- foreach (var fieldNamedArg in customAttribute.Fields) {
- var fieldReference = resolvedAttributeType != null ? resolvedAttributeType.Fields.FirstOrDefault(f => f.Name == fieldNamedArg.Name) : null;
- var fieldName = new IdentifierExpression(fieldNamedArg.Name).WithAnnotation(fieldReference);
- var argumentValue = ConvertArgumentValue(fieldNamedArg.Argument);
- attribute.Arguments.Add(new AssignmentExpression(fieldName, argumentValue));
- }
- }
- }
-
- if (attributeTarget == "module" || attributeTarget == "assembly") {
- // use separate section for each attribute
- foreach (var attribute in attributes) {
- var section = new AttributeSection();
- section.AttributeTarget = attributeTarget;
- section.Attributes.Add(attribute);
- attributedNode.AddChild(section, EntityDeclaration.AttributeRole);
- }
- } else if (attributes.Count > 0) {
- // use single section for all attributes
- var section = new AttributeSection();
- section.AttributeTarget = attributeTarget;
- section.Attributes.AddRange(attributes);
- attributedNode.AddChild(section, EntityDeclaration.AttributeRole);
- }
- }
- }
-
- static void ConvertSecurityAttributes(AstNode attributedNode, ISecurityDeclarationProvider secDeclProvider, string attributeTarget = null)
- {
- if (!secDeclProvider.HasSecurityDeclarations)
- return;
- var attributes = new List<NRefactory.CSharp.Attribute>();
- foreach (var secDecl in secDeclProvider.SecurityDeclarations.OrderBy(d => d.Action)) {
- foreach (var secAttribute in secDecl.SecurityAttributes.OrderBy(a => a.AttributeType.FullName)) {
- var attribute = new NRefactory.CSharp.Attribute();
- attribute.AddAnnotation(secAttribute);
- attribute.Type = ConvertType(secAttribute.AttributeType);
- attributes.Add(attribute);
-
- SimpleType st = attribute.Type as SimpleType;
- if (st != null && st.Identifier.EndsWith("Attribute", StringComparison.Ordinal)) {
- st.Identifier = st.Identifier.Substring(0, st.Identifier.Length - "Attribute".Length);
- }
-
- var module = secAttribute.AttributeType.Module;
- var securityActionType = new TypeReference("System.Security.Permissions", "SecurityAction", module, module.TypeSystem.Corlib);
- attribute.Arguments.Add(MakePrimitive((int)secDecl.Action, securityActionType));
-
- if (secAttribute.HasProperties) {
- TypeDefinition resolvedAttributeType = secAttribute.AttributeType.Resolve();
- foreach (var propertyNamedArg in secAttribute.Properties) {
- var propertyReference = resolvedAttributeType != null ? resolvedAttributeType.Properties.FirstOrDefault(pr => pr.Name == propertyNamedArg.Name) : null;
- var propertyName = new IdentifierExpression(propertyNamedArg.Name).WithAnnotation(propertyReference);
- var argumentValue = ConvertArgumentValue(propertyNamedArg.Argument);
- attribute.Arguments.Add(new AssignmentExpression(propertyName, argumentValue));
- }
- }
-
- if (secAttribute.HasFields) {
- TypeDefinition resolvedAttributeType = secAttribute.AttributeType.Resolve();
- foreach (var fieldNamedArg in secAttribute.Fields) {
- var fieldReference = resolvedAttributeType != null ? resolvedAttributeType.Fields.FirstOrDefault(f => f.Name == fieldNamedArg.Name) : null;
- var fieldName = new IdentifierExpression(fieldNamedArg.Name).WithAnnotation(fieldReference);
- var argumentValue = ConvertArgumentValue(fieldNamedArg.Argument);
- attribute.Arguments.Add(new AssignmentExpression(fieldName, argumentValue));
- }
- }
- }
- }
- if (attributeTarget == "module" || attributeTarget == "assembly") {
- // use separate section for each attribute
- foreach (var attribute in attributes) {
- var section = new AttributeSection();
- section.AttributeTarget = attributeTarget;
- section.Attributes.Add(attribute);
- attributedNode.AddChild(section, EntityDeclaration.AttributeRole);
- }
- } else if (attributes.Count > 0) {
- // use single section for all attributes
- var section = new AttributeSection();
- section.AttributeTarget = attributeTarget;
- section.Attributes.AddRange(attributes);
- attributedNode.AddChild(section, EntityDeclaration.AttributeRole);
- }
- }
-
- static Expression ConvertArgumentValue(CustomAttributeArgument argument)
- {
- if (argument.Value is CustomAttributeArgument[]) {
- ArrayInitializerExpression arrayInit = new ArrayInitializerExpression();
- foreach (CustomAttributeArgument element in (CustomAttributeArgument[])argument.Value) {
- arrayInit.Elements.Add(ConvertArgumentValue(element));
- }
- ArrayType arrayType = argument.Type as ArrayType;
- return new ArrayCreateExpression {
- Type = ConvertType(arrayType != null ? arrayType.ElementType : argument.Type),
- AdditionalArraySpecifiers = { new ArraySpecifier() },
- Initializer = arrayInit
- };
- } else if (argument.Value is CustomAttributeArgument) {
- // occurs with boxed arguments
- return ConvertArgumentValue((CustomAttributeArgument)argument.Value);
- }
- var type = argument.Type.Resolve();
- if (type != null && type.IsEnum) {
- return MakePrimitive(Convert.ToInt64(argument.Value), type);
- } else if (argument.Value is TypeReference) {
- return CreateTypeOfExpression((TypeReference)argument.Value);
- } else {
- return new PrimitiveExpression(argument.Value);
- }
- }
- #endregion
-
- internal static Expression MakePrimitive(long val, TypeReference type)
- {
- if (TypeAnalysis.IsBoolean(type) && val == 0)
- return new PrimitiveExpression(false);
- else if (TypeAnalysis.IsBoolean(type) && val == 1)
- return new PrimitiveExpression(true);
- else if (val == 0 && type is PointerType)
- return new NullReferenceExpression();
- if (type != null)
- { // cannot rely on type.IsValueType, it's not set for typerefs (but is set for typespecs)
- TypeDefinition enumDefinition = type.Resolve();
- if (enumDefinition != null && enumDefinition.IsEnum) {
- TypeCode enumBaseTypeCode = TypeCode.Int32;
- foreach (FieldDefinition field in enumDefinition.Fields) {
- if (field.IsStatic && Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false), val))
- return ConvertType(type).Member(field.Name).WithAnnotation(field);
- else if (!field.IsStatic)
- enumBaseTypeCode = TypeAnalysis.GetTypeCode(field.FieldType); // use primitive type of the enum
- }
- if (IsFlagsEnum(enumDefinition)) {
- long enumValue = val;
- Expression expr = null;
- long negatedEnumValue = ~val;
- // limit negatedEnumValue to the appropriate range
- switch (enumBaseTypeCode) {
- case TypeCode.Byte:
- case TypeCode.SByte:
- negatedEnumValue &= byte.MaxValue;
- break;
- case TypeCode.Int16:
- case TypeCode.UInt16:
- negatedEnumValue &= ushort.MaxValue;
- break;
- case TypeCode.Int32:
- case TypeCode.UInt32:
- negatedEnumValue &= uint.MaxValue;
- break;
- }
- Expression negatedExpr = null;
- foreach (FieldDefinition field in enumDefinition.Fields.Where(fld => fld.IsStatic)) {
- long fieldValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false);
- if (fieldValue == 0)
- continue; // skip None enum value
-
- if ((fieldValue & enumValue) == fieldValue) {
- var fieldExpression = ConvertType(type).Member(field.Name).WithAnnotation(field);
- if (expr == null)
- expr = fieldExpression;
- else
- expr = new BinaryOperatorExpression(expr, BinaryOperatorType.BitwiseOr, fieldExpression);
-
- enumValue &= ~fieldValue;
- }
- if ((fieldValue & negatedEnumValue) == fieldValue) {
- var fieldExpression = ConvertType(type).Member(field.Name).WithAnnotation(field);
- if (negatedExpr == null)
- negatedExpr = fieldExpression;
- else
- negatedExpr = new BinaryOperatorExpression(negatedExpr, BinaryOperatorType.BitwiseOr, fieldExpression);
-
- negatedEnumValue &= ~fieldValue;
- }
- }
- if (enumValue == 0 && expr != null) {
- if (!(negatedEnumValue == 0 && negatedExpr != null && negatedExpr.Descendants.Count() < expr.Descendants.Count())) {
- return expr;
- }
- }
- if (negatedEnumValue == 0 && negatedExpr != null) {
- return new UnaryOperatorExpression(UnaryOperatorType.BitNot, negatedExpr);
- }
- }
- return new PrimitiveExpression(CSharpPrimitiveCast.Cast(enumBaseTypeCode, val, false)).CastTo(ConvertType(type));
- }
- }
- TypeCode code = TypeAnalysis.GetTypeCode(type);
- if (code == TypeCode.Object || code == TypeCode.Empty)
- code = TypeCode.Int32;
- return new PrimitiveExpression(CSharpPrimitiveCast.Cast(code, val, false));
- }
-
- static bool IsFlagsEnum(TypeDefinition type)
- {
- if (!type.HasCustomAttributes)
- return false;
-
- return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute");
- }
-
- /// <summary>
- /// Sets new modifier if the member hides some other member from a base type.
- /// </summary>
- /// <param name="member">The node of the member which new modifier state should be determined.</param>
- static void SetNewModifier(EntityDeclaration member)
- {
- try {
- bool addNewModifier = false;
- if (member is IndexerDeclaration) {
- var propertyDef = member.Annotation<PropertyDefinition>();
- var baseProperties =
- TypesHierarchyHelpers.FindBaseProperties(propertyDef);
- addNewModifier = baseProperties.Any();
- } else
- addNewModifier = HidesBaseMember(member);
-
- if (addNewModifier)
- member.Modifiers |= Modifiers.New;
- }
- catch (ReferenceResolvingException) {
- // TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references.
- }
- }
-
- static bool HidesBaseMember(EntityDeclaration member)
- {
- var memberDefinition = member.Annotation<IMemberDefinition>();
- bool addNewModifier = false;
- var methodDefinition = memberDefinition as MethodDefinition;
- if (methodDefinition != null) {
- addNewModifier = HidesByName(memberDefinition, includeBaseMethods: false);
- if (!addNewModifier)
- addNewModifier = TypesHierarchyHelpers.FindBaseMethods(methodDefinition).Any();
- } else
- addNewModifier = HidesByName(memberDefinition, includeBaseMethods: true);
- return addNewModifier;
- }
-
- /// <summary>
- /// Determines whether any base class member has the same name as the given member.
- /// </summary>
- /// <param name="member">The derived type's member.</param>
- /// <param name="includeBaseMethods">true if names of methods declared in base types should also be checked.</param>
- /// <returns>true if any base member has the same name as given member, otherwise false.</returns>
- static bool HidesByName(IMemberDefinition member, bool includeBaseMethods)
- {
- Debug.Assert(!(member is PropertyDefinition) || !((PropertyDefinition)member).IsIndexer());
-
- if (member.DeclaringType.BaseType != null) {
- var baseTypeRef = member.DeclaringType.BaseType;
- while (baseTypeRef != null) {
-#pragma warning disable 618
- var baseType = baseTypeRef.ResolveOrThrow();
-#pragma warning restore 618
- if (baseType.HasProperties && AnyIsHiddenBy(baseType.Properties, member, m => !m.IsIndexer()))
- return true;
- if (baseType.HasEvents && AnyIsHiddenBy(baseType.Events, member))
- return true;
- if (baseType.HasFields && AnyIsHiddenBy(baseType.Fields, member))
- return true;
- if (includeBaseMethods && baseType.HasMethods
- && AnyIsHiddenBy(baseType.Methods, member, m => !m.IsSpecialName))
- return true;
- if (baseType.HasNestedTypes && AnyIsHiddenBy(baseType.NestedTypes, member))
- return true;
- baseTypeRef = baseType.BaseType;
- }
- }
- return false;
- }
-
- static bool AnyIsHiddenBy<T>(IEnumerable<T> members, IMemberDefinition derived, Predicate<T> condition = null)
- where T : IMemberDefinition
- {
- return members.Any(m => m.Name == derived.Name
- && (condition == null || condition(m))
- && TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType));
- }
- }
-}