示例#1
0
		HashSet<ILVariable> localVariablesToDefine = new HashSet<ILVariable>(); // local variables that are missing a definition
		
		/// <summary>
		/// Creates the body for the method definition.
		/// </summary>
		/// <param name="methodDef">Method definition to decompile.</param>
		/// <param name="context">Decompilation context.</param>
		/// <param name="parameters">Parameter declarations of the method being decompiled.
		/// These are used to update the parameter names when the decompiler generates names for the parameters.</param>
		/// <returns>Block for the method body</returns>
		public static BlockStatement CreateMethodBody(MethodDef methodDef,
		                                              DecompilerContext context,
		                                              IEnumerable<ParameterDeclaration> parameters,
													  out MemberMapping mm)
		{
			MethodDef oldCurrentMethod = context.CurrentMethod;
			Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef);
			context.CurrentMethod = methodDef;
			context.CurrentMethodIsAsync = false;
			try {
				AstMethodBodyBuilder builder = new AstMethodBodyBuilder();
				builder.methodDef = methodDef;
				builder.context = context;
				builder.corLib = methodDef.Module.CorLibTypes;
				if (Debugger.IsAttached) {
					return builder.CreateMethodBody(parameters, out mm);
				} else {
					try {
						return builder.CreateMethodBody(parameters, out mm);
					} catch (OperationCanceledException) {
						throw;
					} catch (Exception ex) {
						throw new ICSharpCode.Decompiler.DecompilerException(methodDef, ex);
					}
				}
			} finally {
				context.CurrentMethod = oldCurrentMethod;
			}
		}
示例#2
0
		BlockStatement CreateMethodBody(IEnumerable<ParameterDeclaration> parameters, out MemberMapping mm)
		{
			if (methodDef.Body == null) {
				mm = null;
				return null;
			}
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILBlock ilMethod = new ILBlock();
			ILAstBuilder astBuilder = new ILAstBuilder();
			ilMethod.Body = astBuilder.Build(methodDef, true, context);
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILAstOptimizer bodyGraph = new ILAstOptimizer();
			bodyGraph.Optimize(context, ilMethod);
			context.CancellationToken.ThrowIfCancellationRequested();
			
			var localVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			Debug.Assert(context.CurrentMethod == methodDef);
			NameVariables.AssignNamesToVariables(context, astBuilder.Parameters, localVariables, ilMethod);
			
			if (parameters != null) {
				foreach (var pair in (from p in parameters
				                      join v in astBuilder.Parameters on p.Annotation<Parameter>() equals v.OriginalParameter
				                      select new { p, v.Name }))
				{
					pair.p.NameToken = Identifier.Create(pair.Name).WithAnnotation(TextTokenType.Parameter);
				}
			}
			
			context.CancellationToken.ThrowIfCancellationRequested();
			Ast.BlockStatement astBlock = TransformBlock(ilMethod);
			CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments
			
			Statement insertionPoint = astBlock.Statements.FirstOrDefault();
			foreach (ILVariable v in localVariablesToDefine) {
				AstType type;
				if (v.Type.ContainsAnonymousType())
					type = new SimpleType("var").WithAnnotation(TextTokenType.Keyword);
				else
					type = AstBuilder.ConvertType(v.Type);
				var newVarDecl = new VariableDeclarationStatement(v.IsParameter ? TextTokenType.Parameter : TextTokenType.Local, type, v.Name);
				newVarDecl.Variables.Single().AddAnnotation(v);
				astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
			}
			
			mm = new MemberMapping(methodDef) { LocalVariables = localVariables.ToList() };
			
			return astBlock;
		}
        public virtual bool Include(MemberMapping member)
        {
            bool anyIncluded = false;
            for (int i = 0; i < member.ElementCount; i++)
                if (member[i] != null && _filter.Include(member[i]))
                    anyIncluded = true;

            if (!anyIncluded)
                return false;

            if (Include(member.Difference))
                return true;
            return false;
        }
示例#4
0
        internal EntityMapping CreateMapping()
        {
            var entity = new EntityMapping { entityType = EntityType };
            if (table == null)
                table = entity.entityType.GetAttribute<TableAttribute>(false);
            if (table != null)
            {
                entity.tableName = table.Name.IsNullOrEmpty()
                    ? entity.entityType.Name
                    : table.Name;
                entity.@readonly = table.Readonly;
                entity.schema = table.Schema;
                entity.databaseName = table.DatabaseName;
                entity.serverName = table.Server;
            }
            else
                entity.tableName = entity.entityType.Name;

            const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            var allMembers = new Dictionary<MemberInfo, MemberMapping>();
            foreach (var k in members.Keys)
                allMembers[k] = new MemberMapping(k, members[k], entity);

            var items = from m in entity.entityType
                       .GetFields(bindingFlags)
                       .Where(p => !members.ContainsKey(p))
                       .Where(p => !IgnoreMembers.Contains(p))
                       .Where(p => !p.HasAttribute<IgnoreAttribute>(true))
                       .Where(p => !p.Name.Contains("k__BackingField"))
                       .Where(p => !p.IsInitOnly)
                       .Cast<MemberInfo>()
                       .Union(entity.entityType
                           .GetProperties(bindingFlags)
                           .Where(p => !members.ContainsKey(p))
                           .Where(p => !IgnoreMembers.Contains(p))
                           .Where(p => p.CanRead && p.CanWrite)
                           .Where(p => !p.HasAttribute<IgnoreAttribute>(true))
                           .Cast<MemberInfo>()
                           ).Distinct()
                        let att = m.GetAttribute<MemberAttribute>(true)
                        select new NLite.Data.Mapping.MemberMapping(m, att, entity);

            foreach (var item in items)
                allMembers[item.member] = item;

            entity.innerMappingMembers = allMembers.Values.ToArray();
            return entity;
        }
示例#5
0
 protected void UpdateMemberMapping(MemberMapping memberMapping, TextLocation startLoc, TextLocation endLoc, IEnumerable <ILRange> ranges)
 {
     if (memberMapping == null)
     {
         return;
     }
     foreach (var range in ILRange.OrderAndJoin(ranges))
     {
         memberMapping.MemberCodeMappings.Add(new SourceCodeMapping {
             StartLocation       = startLoc,
             EndLocation         = endLoc,
             ILInstructionOffset = range,
             MemberMapping       = memberMapping
         });
     }
 }
示例#6
0
        protected MemberMapping MapMemberInternal(MemberInfo sourceMember, MemberInfo targetMember,
                                                  LambdaExpression sourceMemberGetter, LambdaExpression targetMemberGetter,
                                                  LambdaExpression targetMemberSetter)
        {
            var mappingSource = _typeMapping.GetMappingSource(sourceMember,
                                                              sourceMemberGetter);

            var mappingTarget = _typeMapping.GetMappingTarget(targetMember,
                                                              targetMemberGetter, targetMemberSetter);

            var mapping = new MemberMapping(_typeMapping, mappingSource, mappingTarget);

            _typeMapping.MemberMappings[mappingTarget] = mapping;

            return(mapping);
        }
示例#7
0
        public MemberConfigurator MapMember(MemberInfo sourceMember, MemberInfo targetMember)
        {
            CheckThrowMemberBelongsToType(sourceMember, _typeMapping.Source.EntryType);
            CheckThrowMemberBelongsToType(targetMember, _typeMapping.Target.EntryType);

            var sourceMemberGetter = sourceMember.GetGetterExp();
            var targetMemberGetter = targetMember.GetGetterExp();
            var targetMemberSetter = targetMember.GetSetterExp();

            MemberMapping mapping = this.MapMemberInternal(sourceMember, targetMember,
                                                           sourceMemberGetter, targetMemberGetter, targetMemberSetter);

            mapping.MappingResolution = MappingResolution.USER_DEFINED;

            return(this);
        }
示例#8
0
        public void StartNode(AstNode node)
        {
            // code mappings
            var ranges = node.Annotation <List <ILRange> >();

            if (ranges != null && ranges.Count > 0)
            {
                // find the ancestor that has method mapping as annotation
                if (node.Parent != null)
                {
                    var n = node.Ancestors.FirstOrDefault(a => a.Annotation <MemberMapping>() != null);
                    if (n != null)
                    {
                        MemberMapping mapping = n.Annotation <MemberMapping>();

                        // add all ranges
                        foreach (var range in ranges)
                        {
                            mapping.MemberCodeMappings.Add(new SourceCodeMapping {
                                ILInstructionOffset = range,
                                SourceCodeLine      = output.Location.Line,
                                MemberMapping       = mapping
                            });
                        }
                    }
                }
            }

            // definitions of types and their members
            Predicate <AstNode> predicate = n => n is AttributedNode;

            if (predicate(node))
            {
                var n = node as AttributedNode;
                int attributesCount = 0;
                if (n != null)
                {
                    attributesCount = n.Attributes.Count;
                }
                node.AddAnnotation(new TextOutputLocation {
                    Line = output.Location.Line + attributesCount, Column = output.Location.Column
                });
            }

            nodeStack.Push(node);
        }
示例#9
0
        private MembersMapping ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, string ns, bool hasWrapperElement, bool writeAccessors, bool validateWrapperElement, RecursionLimiter limiter)
        {
            MembersMapping members = new MembersMapping();

            members.TypeDesc = _typeScope.GetTypeDesc(typeof(object[]));
            MemberMapping[] mappings = new MemberMapping[xmlReflectionMembers.Length];
            for (int i = 0; i < mappings.Length; i++)
            {
                try
                {
                    XmlReflectionMember member  = xmlReflectionMembers[i];
                    MemberMapping       mapping = ImportMemberMapping(member, ns, xmlReflectionMembers, hasWrapperElement ? XmlSchemaForm.Unqualified : XmlSchemaForm.Qualified, limiter);
                    if (member.IsReturnValue && writeAccessors)
                    { // no special treatment for return values with doc/enc
                        if (i > 0)
                        {
                            throw new InvalidOperationException(SR.XmlInvalidReturnPosition);
                        }
                        mapping.IsReturnValue = true;
                    }
                    mappings[i] = mapping;
                }
                catch (Exception e)
                {
                    if (e is OutOfMemoryException)
                    {
                        throw;
                    }
                    throw ReflectionException(xmlReflectionMembers[i].MemberName, e);
                }
            }
            members.Members           = mappings;
            members.HasWrapperElement = hasWrapperElement;
            if (hasWrapperElement)
            {
                members.ValidateRpcWrapperElement = validateWrapperElement;
            }
            members.WriteAccessors = writeAccessors;
            members.IsSoap         = true;
            if (hasWrapperElement && !writeAccessors)
            {
                members.Namespace = ns;
            }
            return(members);
        }
示例#10
0
        /// <summary>
        /// Start a fluent configuration for the specified <paramref name="property"/>.
        /// </summary>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="property">The source property to configure.</param>
        /// <returns>A fluent member builder for the specified property.</returns>
        public MemberMappingBuilder <TEntity, TProperty> Property <TProperty>(Expression <Func <TEntity, TProperty> > property)
        {
            var propertyAccessor = EntityMapping.TypeAccessor.FindProperty(property);

            var memberMapping = EntityMapping.Members.Find(m => m.MemberAccessor.MemberInfo == propertyAccessor.MemberInfo);

            if (memberMapping == null)
            {
                memberMapping = new MemberMapping();
                memberMapping.MemberAccessor = propertyAccessor;

                EntityMapping.Members.Add(memberMapping);
            }

            var builder = new MemberMappingBuilder <TEntity, TProperty>(memberMapping);

            return(builder);
        }
示例#11
0
        public MemberMappingContext(MemberMapping mapping)
            : base(mapping.InstanceTypeMapping.TypePair.SourceType,
                   mapping.InstanceTypeMapping.TypePair.TargetType, mapping)
        {
            var sourceMemberType = mapping.SourceMember.MemberInfo.GetMemberType();
            var targetMemberType = mapping.TargetMember.MemberInfo.GetMemberType();

            TrackedReference = Expression.Parameter(targetMemberType, "trackedReference");

            SourceMember = Expression.Variable(sourceMemberType, "sourceValue");
            TargetMember = Expression.Variable(targetMemberType, "targetValue");

            if (!sourceMemberType.IsValueType)
            {
                SourceMemberNullValue = Expression.Constant(null, sourceMemberType);
            }

            if (!targetMemberType.IsValueType)
            {
                TargetMemberNullValue = Expression.Constant(null, targetMemberType);
            }

            var sourceGetterInstanceParamName = mapping.SourceMember
                                                .ValueGetter.Parameters[0].Name;

            SourceMemberValueGetter = mapping.SourceMember.ValueGetter.Body
                                      .ReplaceParameter(SourceInstance, sourceGetterInstanceParamName);

            if (mapping.TargetMember.ValueGetter != null)
            {
                var targetGetterInstanceParamName = mapping.TargetMember
                                                    .ValueGetter.Parameters[0].Name;

                TargetMemberValueGetter = mapping.TargetMember.ValueGetter.Body
                                          .ReplaceParameter(TargetInstance, targetGetterInstanceParamName);
            }

            var targetSetterInstanceParamName = mapping.TargetMember.ValueSetter.Parameters[0].Name;
            var targetSetterMemberParamName   = mapping.TargetMember.ValueSetter.Parameters[1].Name;

            TargetMemberValueSetter = mapping.TargetMember.ValueSetter.Body
                                      .ReplaceParameter(TargetInstance, targetSetterInstanceParamName)
                                      .ReplaceParameter(TargetMember, targetSetterMemberParamName);
        }
示例#12
0
        public virtual DifferenceType Diff <T>(IDifferences differences, ElementMapping <T> mapping) where T : class
        {
            if (mapping.ElementCount < 2)
            {
                return(DifferenceType.Unchanged);
            }

            MemberMapping member = mapping as MemberMapping;

            if (member != null)
            {
                return(Diff(differences, member));
            }

            TypeMapping type = mapping as TypeMapping;

            if (type != null)
            {
                return(Diff(differences, type));
            }

            NamespaceMapping ns = mapping as NamespaceMapping;

            if (ns != null)
            {
                return(Diff(differences, ns));
            }

            AssemblyMapping asm = mapping as AssemblyMapping;

            if (asm != null)
            {
                return(Diff(differences, asm));
            }

            AssemblySetMapping asmSet = mapping as AssemblySetMapping;

            if (asmSet != null)
            {
                return(Diff(differences, asmSet));
            }

            return(DifferenceType.Unknown);
        }
示例#13
0
        private MemberMapping ImportFieldMapping(FieldModel model, SoapAttributes a, string ns, RecursionLimiter limiter)
        {
            if (a.SoapIgnore)
            {
                return(null);
            }
            MemberMapping member = new MemberMapping();

            member.IsSoap                       = true;
            member.Name                         = model.Name;
            member.CheckShouldPersist           = model.CheckShouldPersist;
            member.CheckSpecified               = model.CheckSpecified;
            member.MemberInfo                   = model.MemberInfo;
            member.CheckSpecifiedMemberInfo     = model.CheckSpecifiedMemberInfo;
            member.CheckShouldPersistMethodInfo = model.CheckShouldPersistMethodInfo;
            member.ReadOnly                     = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor;
            ImportAccessorMapping(member, model, a, ns, XmlSchemaForm.Unqualified, limiter);
            return(member);
        }
        private IMethodDefinition FindBestMatch(IMethodDefinition matchMethod, TypeMapping mapping, int typeIndex, int memberIndex)
        {
            // No matches if we don't have a matching type.
            if (mapping[typeIndex] == null)
            {
                return(null);
            }

            foreach (IMethodDefinition method in mapping[typeIndex].Methods)
            {
                if (method.Name.Value != matchMethod.Name.Value)
                {
                    continue;
                }

                if (method.ParameterCount != matchMethod.ParameterCount)
                {
                    continue;
                }

                if (method.IsGeneric && matchMethod.IsGeneric &&
                    method.GenericParameterCount != matchMethod.GenericParameterCount)
                {
                    continue;
                }

                MemberMapping member = mapping.FindMember(method);

                // It is possible to find a match that was filtered at the mapping layer
                if (member == null)
                {
                    continue;
                }

                // If the other member also doesn't have a match then this is our best match
                if (member[memberIndex] == null)
                {
                    return(method);
                }
            }

            return(null);
        }
        public override string GetValue(MemberMapping mapping)
        {
            var virtuality = GetVirtuality(mapping.Representative);

            switch (virtuality)
            {
            case Virtuality.None:
                return(string.Empty);

            case Virtuality.Virtual:
                return("Virtual");

            case Virtuality.Abstract:
                return("Abstract");

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#16
0
        /// <inheritdoc/>
        public override InstructionPrototype Map(MemberMapping mapping)
        {
            var newType = mapping.MapType(TargetType);

            if (object.ReferenceEquals(newType, TargetType))
            {
                return(this);
            }
            else if (!(newType is PointerType))
            {
                throw new InvalidOperationException(
                          "Cannot transform a reinterpret cast to take non-pointer target type '" +
                          newType.FullName + "'.");
            }
            else
            {
                return(Create((PointerType)newType));
            }
        }
示例#17
0
        /// <summary>
        /// Start a fluent configuration for the specified <paramref name="collection"/>.
        /// </summary>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="collection">The source property to configure.</param>
        /// <returns>A fluent member builder for the specified property.</returns>
        public CollectionMappingBuilder <TEntity, TProperty> Collection <TProperty>(Expression <Func <TEntity, TProperty> > collection)
            where TProperty : IEnumerable
        {
            var propertyAccessor = EntityMapping.TypeAccessor.FindProperty(collection);

            var memberMapping = EntityMapping.Members.Find(m => m.MemberAccessor.MemberInfo == propertyAccessor.MemberInfo);

            if (memberMapping == null)
            {
                memberMapping = new MemberMapping();
                memberMapping.MemberAccessor = propertyAccessor;

                EntityMapping.Members.Add(memberMapping);
            }

            var builder = new CollectionMappingBuilder <TEntity, TProperty>(memberMapping);

            return(builder);
        }
示例#18
0
        public int Compare(object o1, object o2)
        {
            MemberMapping m1 = (MemberMapping)o1;
            MemberMapping m2 = (MemberMapping)o2;

            bool m1Text = m1.IsText;

            if (m1Text)
            {
                if (m2.IsText)
                {
                    return(0);
                }
                return(1);
            }
            else if (m2.IsText)
            {
                return(-1);
            }

            if (m1.SequenceId < 0 && m2.SequenceId < 0)
            {
                return(0);
            }
            if (m1.SequenceId < 0)
            {
                return(1);
            }
            if (m2.SequenceId < 0)
            {
                return(-1);
            }
            if (m1.SequenceId < m2.SequenceId)
            {
                return(-1);
            }
            if (m1.SequenceId > m2.SequenceId)
            {
                return(1);
            }
            return(0);
        }
示例#19
0
        public override DifferenceType Diff(IDifferences differences, MemberMapping mapping)
        {
            ITypeDefinitionMember implMember     = mapping[0];
            ITypeDefinitionMember contractMember = mapping[1];

            if (!(implMember == null && contractMember != null))
            {
                return(DifferenceType.Unknown);
            }

            // Nested types are handled separately.
            // @TODO: Events and Properties - should we consider these too (or rely on the fact that dropping one of these will also drop their accessors.)
            if (!(contractMember is IMethodDefinition || contractMember is IFieldDefinition))
            {
                return(DifferenceType.Unknown);
            }

            string incompatibleDifferenceMessage = contractMember.GetMemberViolationMessage("Member", $"does not exist in the {Implementation}", $"it does exist in the {Contract}");

            ITypeDefinition contractType = mapping.ContainingType[0];

            if (contractType != null)
            {
                if (contractMember is IMethodDefinition contractMethod)
                {
                    // If the contract is a Explicit Interface method, we don't need to check if the method is in implementation since that will be caught by different rule.
                    if (contractMethod.IsExplicitInterfaceMethod())
                    {
                        return(DifferenceType.Unknown);
                    }

                    // It is valid to promote a member from a base type up so check to see if it member exits on a base type.
                    if (FindMatchingMethodOnBase(contractType, contractMethod))
                    {
                        return(DifferenceType.Unknown);
                    }
                }
            }

            differences.AddIncompatibleDifference(this, incompatibleDifferenceMessage);
            return(DifferenceType.Added);
        }
示例#20
0
        public void StartNode(AstNode node)
        {
//			var ranges = node.Annotation<List<ILRange>>();
//			if (ranges != null && ranges.Count > 0)
//			{
//				// find the ancestor that has method mapping as annotation
//				if (node.Ancestors != null && node.Ancestors.Count() > 0)
//				{
//					var n = node.Ancestors.FirstOrDefault(a => a.Annotation<MemberMapping>() != null);
//					if (n != null) {
//						MemberMapping mapping = n.Annotation<MemberMapping>();
//
//						// add all ranges
//						foreach (var range in ranges) {
//							mapping.MemberCodeMappings.Add(new SourceCodeMapping {
//							                                ILInstructionOffset = range,
//							                                SourceCodeLine = output.CurrentLine,
//							                                MemberMapping = mapping
//							                               });
//						}
//					}
//				}
//			}

            nodeStack.Push(node);

            MemberMapping mapping = node.Annotation <MemberMapping>();

            if (mapping != null)
            {
                parentMemberMappings.Push(currentMemberMapping);
                currentMemberMapping = mapping;
            }
            // For ctor/cctor field initializers
            var mms = node.Annotation <List <Tuple <MemberMapping, List <ILRange> > > >();

            if (mms != null)
            {
                Debug.Assert(multiMappings == null);
                multiMappings = mms;
            }
        }
示例#21
0
        public override void Visit(MemberMapping member)
        {
            _diffRecorder.CancellationToken.ThrowIfCancellationRequested();

            var shouldVisit = !IsPropertyOrEventAccessor(member.Representative) &&
                              !IsEnumValueField(member.Representative) &&
                              !IsDelegateMember(member.Representative);

            if (shouldVisit)
            {
                PushApi(member);
            }

            base.Visit(member);

            if (shouldVisit)
            {
                PopApi();
            }
        }
示例#22
0
        private Expression GetSimpleMemberExpression(MemberMapping mapping)
        {
            var memberContext = new MemberMappingContext(mapping);

            var targetSetterInstanceParamName = mapping.TargetMember.ValueSetter.Parameters[0].Name;
            var targetSetterValueParamName    = mapping.TargetMember.ValueSetter.Parameters[1].Name;

            var valueReaderExp = mapping.MappingExpression.Body.ReplaceParameter(
                memberContext.SourceMemberValueGetter, mapping.MappingExpression.Parameters[0].Name);

            if (mapping.MappingExpression.Parameters[0].Type == typeof(ReferenceTracker))
            {
                valueReaderExp = mapping.MappingExpression.Body.ReplaceParameter(
                    memberContext.SourceMemberValueGetter, mapping.MappingExpression.Parameters[1].Name);
            }

            return(mapping.TargetMember.ValueSetter.Body
                   .ReplaceParameter(memberContext.TargetInstance, targetSetterInstanceParamName)
                   .ReplaceParameter(valueReaderExp, targetSetterValueParamName));
        }
        // TODO: Add support for property parameter lists
        public override DifferenceType Diff(IDifferences differences, MemberMapping mapping)
        {
            IMethodDefinition method1 = mapping[0] as IMethodDefinition;
            IMethodDefinition method2 = mapping[1] as IMethodDefinition;

            if (method1 == null && method2 == null)
            {
                return(DifferenceType.Unknown);
            }

            if (method1 != null && method2 != null)
            {
                return(DifferenceType.Unknown);
            }

            if (method1 != null)
            {
                IMethodDefinition match = FindBestMatch(method1, mapping.ContainingType, 1, 0);

                if (match != null)
                {
                    differences.AddIncompatibleDifference(this,
                                                          "Cannot change parameter types for method {0} and {1}", method1.GetMethodSignature(), match.GetMethodSignature());
                    return(DifferenceType.Changed);
                }
            }

            if (method2 != null)
            {
                IMethodDefinition match = FindBestMatch(method2, mapping.ContainingType, 0, 1);

                if (match != null)
                {
                    differences.AddIncompatibleDifference(this,
                                                          "Cannot change parameter types for method {0} and {1}", method2.GetMethodSignature(), match.GetMethodSignature());
                    return(DifferenceType.Changed);
                }
            }

            return(DifferenceType.Unknown);
        }
示例#24
0
        public override DifferenceType Diff(IDifferences differences, MemberMapping mapping)
        {
            ITypeDefinitionMember implMember = mapping[0];
            ITypeDefinitionMember contractMember = mapping[1];
            IMethodDefinition foundMethod;

            if (!(implMember == null && contractMember != null))
                return DifferenceType.Unknown;

            // Nested types are handled separately.
            // @TODO: Events and Properties - should we consider these too (or rely on the fact that dropping one of these will also drop their accessors.) 
            if (!(contractMember is IMethodDefinition || contractMember is IFieldDefinition))
                return DifferenceType.Unknown;

            string incompatibeDifferenceMessage = string.Format("Member '{0}' does not exist in the implementation but it does exist in the contract.", contractMember.FullName());
            string returnTypeChangedMessageFormat = "Member '{0}' does not exist, but there does exist a member with return type '{1}' instead of '{2}'";
            ITypeDefinition contractType = mapping.ContainingType[0];
            if (contractType != null)
            {
                IMethodDefinition contractMethod = contractMember as IMethodDefinition;
                if (contractMethod != null)
                {
                    // If the contract is a Explicit Interface method, we don't need to check if the method is in implementation since that will be catched by different rule.
                    if (contractMethod.IsExplicitInterfaceMethod())
                        return DifferenceType.Unknown;



                    // It is valid to promote a member from a base type up so check to see if it member exits on a base type.
                    var lookForMethodInBaseResult = FindMatchingBase(contractType, contractMethod, out foundMethod);
                    if (lookForMethodInBaseResult == FindMethodResult.Found)
                        return DifferenceType.Unknown;
                    if (lookForMethodInBaseResult == FindMethodResult.ReturnTypeChanged)
                        incompatibeDifferenceMessage = string.Format(returnTypeChangedMessageFormat, foundMethod.FullName(), foundMethod.GetReturnType().FullName(), contractMethod.GetReturnType().FullName());
                }
            }

            differences.AddIncompatibleDifference(this, incompatibeDifferenceMessage);

            return DifferenceType.Added;
        }
示例#25
0
        public override void WriteTo(ITextOutput output, MemberMapping memberMapping)
        {
            var startLoc = output.Location;

            output.Write("switch", TextTokenKind.Keyword);
            output.WriteSpace();
            output.Write("(", TextTokenKind.Operator);
            Condition.WriteTo(output, null);
            output.Write(")", TextTokenKind.Operator);
            var ilRanges = new List <ILRange>(ILRanges);

            ilRanges.AddRange(Condition.GetSelfAndChildrenRecursiveILRanges());
            UpdateMemberMapping(memberMapping, startLoc, output.Location, ilRanges);
            output.WriteSpace();
            WriteHiddenStart(output, memberMapping);
            foreach (CaseBlock caseBlock in this.CaseBlocks)
            {
                caseBlock.WriteTo(output, memberMapping);
            }
            WriteHiddenEnd(output, memberMapping);
        }
示例#26
0
        /// <summary>
        /// Applies a member mapping to this basic block.
        /// </summary>
        /// <param name="mapping">A member mapping.</param>
        /// <returns>A transformed basic block.</returns>
        public BasicBlockData Map(MemberMapping mapping)
        {
            var newParameters = ImmutableList <BlockParameter> .Empty.ToBuilder();

            foreach (var param in Parameters)
            {
                newParameters.Add(param.Map(mapping));
            }

            var newFlowInsns = new List <Instruction>();

            foreach (var insn in Flow.Instructions)
            {
                newFlowInsns.Add(insn.Map(mapping));
            }

            return(new BasicBlockData(
                       newParameters.ToImmutable(),
                       InstructionTags,
                       Flow.WithInstructions(newFlowInsns)));
        }
示例#27
0
            public List <int> Values;             // null for the default case

            public override void WriteTo(ITextOutput output, MemberMapping memberMapping)
            {
                if (this.Values != null)
                {
                    foreach (int i in this.Values)
                    {
                        output.Write("case", TextTokenKind.Keyword);
                        output.WriteSpace();
                        output.Write(string.Format("{0}", i), TextTokenKind.Number);
                        output.WriteLine(":", TextTokenKind.Operator);
                    }
                }
                else
                {
                    output.Write("default", TextTokenKind.Keyword);
                    output.WriteLine(":", TextTokenKind.Operator);
                }
                output.Indent();
                base.WriteTo(output, memberMapping);
                output.Unindent();
            }
示例#28
0
        private void MapByConvention(TypeMapping typeMapping)
        {
            foreach (var convention in this.Conventions)
            {
                var memberPairings = convention.MapByConvention(
                    typeMapping.TypePair.SourceType, typeMapping.TypePair.TargetType);

                foreach (var memberPair in memberPairings)
                {
                    var sourceMember  = memberPair.SourceMemberAccess.Last();
                    var mappingSource = typeMapping.GetMappingSource(sourceMember, memberPair.SourceMemberAccess);

                    var targetMember  = memberPair.TargetMemberAccess.Last();
                    var mappingTarget = typeMapping.GetMappingTarget(targetMember, memberPair.TargetMemberAccess);

                    var mapping = new MemberMapping(typeMapping, mappingSource, mappingTarget);
                    mapping.MappingResolution = MappingResolution.RESOLVED_BY_CONVENTION;

                    typeMapping.MemberMappings[mappingTarget] = mapping;
                }
            }
        }
示例#29
0
        public override void WriteTo(ITextOutput output, MemberMapping memberMapping)
        {
            var startLoc = output.Location;

            output.Write("loop", TextTokenKind.Keyword);
            output.WriteSpace();
            output.Write("(", TextTokenKind.Operator);
            if (this.Condition != null)
            {
                this.Condition.WriteTo(output, null);
            }
            output.Write(")", TextTokenKind.Operator);
            var ilRanges = new List <ILRange>(ILRanges);

            if (this.Condition != null)
            {
                ilRanges.AddRange(this.Condition.GetSelfAndChildrenRecursiveILRanges());
            }
            UpdateMemberMapping(memberMapping, startLoc, output.Location, ilRanges);
            output.WriteSpace();
            this.BodyBlock.WriteTo(output, memberMapping);
        }
示例#30
0
        public override void WriteTo(ITextOutput output, MemberMapping memberMapping)
        {
            var startLoc = output.Location;

            output.Write("if", TextTokenKind.Keyword);
            output.WriteSpace();
            output.Write("(", TextTokenKind.Operator);
            Condition.WriteTo(output, null);
            output.Write(")", TextTokenKind.Operator);
            var ilRanges = new List <ILRange>(ILRanges);

            ilRanges.AddRange(Condition.GetSelfAndChildrenRecursiveILRanges());
            UpdateMemberMapping(memberMapping, startLoc, output.Location, ilRanges);
            output.WriteSpace();
            TrueBlock.WriteTo(output, memberMapping);
            if (FalseBlock != null)
            {
                output.Write("else", TextTokenKind.Keyword);
                output.WriteSpace();
                FalseBlock.WriteTo(output, memberMapping);
            }
        }
示例#31
0
        /// <summary>
        /// Applies a member mapping to this flow graph.
        /// </summary>
        /// <param name="mapping">A member mapping.</param>
        /// <returns>A transformed flow graph.</returns>
        public FlowGraph Map(MemberMapping mapping)
        {
            // Apply the mapping to all instructions.
            var newInstructionMap = ImmutableDictionary
                                    .Create <ValueTag, Instruction>()
                                    .ToBuilder();

            foreach (var insnPair in instructions)
            {
                newInstructionMap[insnPair.Key] = insnPair.Value.Map(mapping);
            }

            // Apply the mapping to all basic blocks.
            var newBlockMap = ImmutableOrderedDictionary
                              .Create <BasicBlockTag, BasicBlockData>()
                              .ToBuilder();

            var newParamTypeMap = ImmutableDictionary
                                  .Create <ValueTag, IType>()
                                  .ToBuilder();

            foreach (var blockPair in blocks)
            {
                var newBlock = blockPair.Value.Map(mapping);
                newBlockMap[blockPair.Key] = newBlock;
                foreach (var newBlockParam in newBlock.Parameters)
                {
                    newParamTypeMap[newBlockParam.Tag] = newBlockParam.Type;
                }
            }

            var result = new FlowGraph(this, new MapMembersUpdate(mapping));

            result.instructions    = newInstructionMap.ToImmutable();
            result.blocks          = newBlockMap.ToImmutable();
            result.blockParamTypes = newParamTypeMap.ToImmutable();
            return(result);
        }
示例#32
0
        public virtual bool Include(MemberMapping member)
        {
            bool anyIncluded = false;

            for (int i = 0; i < member.ElementCount; i++)
            {
                if (member[i] != null && _filter.Include(member[i]))
                {
                    anyIncluded = true;
                }
            }

            if (!anyIncluded)
            {
                return(false);
            }

            if (Include(member.Difference))
            {
                return(true);
            }
            return(false);
        }
        // TODO: Add support for property parameter lists
        public override DifferenceType Diff(IDifferences differences, MemberMapping mapping)
        {
            IMethodDefinition method1 = mapping[0] as IMethodDefinition;
            IMethodDefinition method2 = mapping[1] as IMethodDefinition;

            if (method1 == null && method2 == null)
                return DifferenceType.Unknown;

            if (method1 != null && method2 != null)
                return DifferenceType.Unknown;

            if (method1 != null)
            {
                IMethodDefinition match = FindBestMatch(method1, mapping.ContainingType, 1, 0);

                if (match != null)
                {
                    differences.AddIncompatibleDifference(this,
                        "Cannot change parameter types for method {0} and {1}", method1.GetMethodSignature(), match.GetMethodSignature());
                    return DifferenceType.Changed;
                }
            }

            if (method2 != null)
            {
                IMethodDefinition match = FindBestMatch(method2, mapping.ContainingType, 0, 1);

                if (match != null)
                {
                    differences.AddIncompatibleDifference(this,
                        "Cannot change parameter types for method {0} and {1}", method2.GetMethodSignature(), match.GetMethodSignature());
                    return DifferenceType.Changed;
                }
            }

            return DifferenceType.Unknown;
        }
示例#34
0
        void WriteStructureBody(ILStructure s, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize)
        {
            int childIndex = 0;

            while (inst != null && inst.Offset < s.EndOffset)
            {
                int offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, ref inst, currentMethodMapping, codeSize);
                    WriteStructureFooter(child);
                }
                else
                {
                    inst.WriteTo(output);

                    // add IL code mappings - used in debugger
                    if (currentMethodMapping != null)
                    {
                        currentMethodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            SourceCodeLine      = output.CurrentLine,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset
                            },
                            MemberMapping = currentMethodMapping
                        });
                    }

                    output.WriteLine();
                    inst = inst.Next;
                }
            }
        }
示例#35
0
        public void EndNode(AstNode node)
        {
            if (nodeStack.Pop() != node)
            {
                throw new InvalidOperationException();
            }

            var startLocation = startLocations.Pop();

            // code mappings
            if (currentMemberMapping != null)
            {
                var ranges = node.Annotation <List <ILRange> >();
                if (ranges != null && ranges.Count > 0)
                {
                    // add all ranges
                    foreach (var range in ranges)
                    {
                        currentMemberMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping {
                            ILInstructionOffset = range,
                            StartLocation       = startLocation,
                            EndLocation         = output.Location,
                            MemberMapping       = currentMemberMapping
                        });
                    }
                }
            }


            if (node.Annotation <MemberMapping>() != null)
            {
                output.AddDebuggerMemberMapping(currentMemberMapping);
                currentMemberMapping = parentMemberMappings.Pop();
            }
        }
示例#36
0
        public void MapByConvention(TypeMapping typeMapping, IEnumerable <IMappingConvention> conventions)
        {
            foreach (var convention in conventions)
            {
                var memberPairings = convention.MapByConvention(
                    typeMapping.Source.EntryType, typeMapping.Target.EntryType);

                foreach (var memberPair in memberPairings)
                {
                    var sourceMember  = memberPair.SourceMemberPath.Last();
                    var mappingSource = typeMapping.GetMappingSource(sourceMember, memberPair.SourceMemberPath);

                    var targetMember  = memberPair.TargetMemberPath.Last();
                    var mappingTarget = typeMapping.GetMappingTarget(targetMember, memberPair.TargetMemberPath);

                    var mapping = new MemberMapping(typeMapping, mappingSource, mappingTarget)
                    {
                        MappingResolution = MappingResolution.RESOLVED_BY_CONVENTION
                    };

                    typeMapping.MemberToMemberMappings[mappingTarget] = mapping;
                }
            }
        }
 public bool Include(MemberMapping member)
 {
     return _baseFilter.Include(member) && Include(member.ContainingType);
 }
示例#38
0
		public override void Decompile(MethodDef method, ITextOutput output, DecompilationContext ctx) {
			WriteCommentBegin(output, true);
			output.Write("Method: ", TextTokenKind.Comment);
			output.WriteDefinition(IdentifierEscaper.Escape(method.FullName), method, TextTokenKind.Comment, false);
			WriteCommentEnd(output, true);
			output.WriteLine();

			if (!method.HasBody) {
				return;
			}

			StartKeywordBlock(output, ".body", method);

			ILAstBuilder astBuilder = new ILAstBuilder();
			ILBlock ilMethod = new ILBlock();
			DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
			ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

			if (abortBeforeStep != null) {
				new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
			}

			if (context.CurrentMethodIsAsync) {
				output.Write("async", TextTokenKind.Keyword);
				output.Write("/", TextTokenKind.Operator);
				output.WriteLine("await", TextTokenKind.Keyword);
			}

			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			foreach (ILVariable v in allVariables) {
				output.WriteDefinition(IdentifierEscaper.Escape(v.Name), v, v.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local);
				if (v.Type != null) {
					output.WriteSpace();
					output.Write(":", TextTokenKind.Operator);
					output.WriteSpace();
					if (v.IsPinned) {
						output.Write("pinned", TextTokenKind.Keyword);
						output.WriteSpace();
					}
					v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
				}
				if (v.GeneratedByDecompiler) {
					output.WriteSpace();
					output.Write("[", TextTokenKind.Operator);
					output.Write("generated", TextTokenKind.Keyword);
					output.Write("]", TextTokenKind.Operator);
				}
				output.WriteLine();
			}

			var memberMapping = new MemberMapping(method);
			foreach (ILNode node in ilMethod.Body) {
				node.WriteTo(output, memberMapping);
				if (!node.WritesNewLine)
					output.WriteLine();
			}
			output.AddDebugSymbols(memberMapping);
			EndKeywordBlock(output);
		}
示例#39
0
		public override void EndNode(AstNode node)
		{
			if (nodeStack.Pop() != node)
				throw new InvalidOperationException();
			
			if (node.Annotation<MemberMapping>() != null) {
				output.AddDebugSymbols(currentMemberMapping);
				currentMemberMapping = parentMemberMappings.Pop();
			}
			var mms = node.Annotation<List<Tuple<MemberMapping, List<ILRange>>>>();
			if (mms != null) {
				Debug.Assert(mms == multiMappings);
				if (mms == multiMappings) {
					foreach (var mm in mms)
						output.AddDebugSymbols(mm.Item1);
					multiMappings = null;
				}
			}
		}
示例#40
0
		public override void StartNode(AstNode node)
		{
			if (nodeStack.Count == 0) {
				if (IsUsingDeclaration(node)) {
					firstUsingDeclaration = !IsUsingDeclaration(node.PrevSibling);
					lastUsingDeclaration = !IsUsingDeclaration(node.NextSibling);
				} else {
					firstUsingDeclaration = false;
					lastUsingDeclaration = false;
				}
			}
			nodeStack.Push(node);
			
			MemberMapping mapping = node.Annotation<MemberMapping>();
			if (mapping != null) {
				parentMemberMappings.Push(currentMemberMapping);
				currentMemberMapping = mapping;
			}
			// For ctor/cctor field initializers
			var mms = node.Annotation<List<Tuple<MemberMapping, List<ILRange>>>>();
			if (mms != null) {
				Debug.Assert(multiMappings == null);
				multiMappings = mms;
			}
		}
 public override bool Include(MemberMapping member)
 {
     return false;
 }
示例#42
0
 public override void Visit(MemberMapping mapping)
 {
     Visit(mapping.Differences);
     base.Visit(mapping);
 }
示例#43
0
        void WriteStructureBody(CilBody body, ILStructure s, HashSet<uint> branchTargets, ref int index, MemberMapping debugSymbols, int codeSize, uint baseRva, long baseOffs, IInstructionBytesReader byteReader, MethodDef method)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch = false;
            int childIndex = 0;
            var instructions = body.Instructions;
            while (index < instructions.Count) {
                Instruction inst = instructions[index];
                if (inst.Offset >= s.EndOffset)
                    break;
                uint offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(body, child, branchTargets, ref index, debugSymbols, codeSize, baseRva, baseOffs, byteReader, method);
                    WriteStructureFooter(child);
                } else {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) {
                        output.WriteLine(); // put an empty line after branches, and in front of branch targets
                    }
                    var startLocation = output.Location;
                    inst.WriteTo(output, options, baseRva, baseOffs, byteReader, method);

                    // add IL code mappings - used in debugger
                    if (debugSymbols != null) {
                        var next = index + 1 < instructions.Count ? instructions[index + 1] : null;
                        debugSymbols.MemberCodeMappings.Add(
                            new SourceCodeMapping() {
                                StartLocation = startLocation,
                                EndLocation = output.Location,
                                ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)codeSize : next.Offset),
                                MemberMapping = debugSymbols
                            });
                    }

                    output.WriteLine();

                    prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch
                        || inst.OpCode.FlowControl == FlowControl.Cond_Branch
                        || inst.OpCode.FlowControl == FlowControl.Return
                        || inst.OpCode.FlowControl == FlowControl.Throw;

                    index++;
                }
                isFirstInstructionInStructure = false;
            }
        }
示例#44
0
        public void Disassemble(MethodDef method, MemberMapping debugSymbols)
        {
            // start writing IL code
            CilBody body = method.Body;
            uint codeSize = (uint)body.GetCodeSize();
            uint rva = (uint)method.RVA;
            long offset = method.Module.ToFileOffset(rva);

            if (options.ShowTokenAndRvaComments) {
                output.WriteLine(string.Format("// Header Size: {0} {1}", method.Body.HeaderSize, method.Body.HeaderSize == 1 ? "byte" : "bytes"), TextTokenType.Comment);
                output.WriteLine(string.Format("// Code Size: {0} (0x{0:X}) {1}", codeSize, codeSize == 1 ? "byte" : "bytes"), TextTokenType.Comment);
                if (body.LocalVarSigTok != 0)
                    output.WriteLine(string.Format("// LocalVarSig Token: 0x{0:X8} RID: {1}", body.LocalVarSigTok, body.LocalVarSigTok & 0xFFFFFF), TextTokenType.Comment);
            }
            output.Write(".maxstack", TextTokenType.ILDirective);
            output.WriteSpace();
            output.WriteLine(string.Format("{0}", body.MaxStack), TextTokenType.Number);
            if (method.DeclaringType.Module.EntryPoint == method)
                output.WriteLine (".entrypoint", TextTokenType.ILDirective);

            if (method.Body.HasVariables) {
                output.Write(".locals", TextTokenType.ILDirective);
                output.WriteSpace();
                if (method.Body.InitLocals) {
                    output.Write("init", TextTokenType.Keyword);
                    output.WriteSpace();
                }
                output.WriteLine("(", TextTokenType.Operator);
                output.Indent();
                foreach (var v in method.Body.Variables) {
                    output.Write('[', TextTokenType.Operator);
                    output.WriteDefinition(v.Index.ToString(), v, TextTokenType.Number);
                    output.Write(']', TextTokenType.Operator);
                    output.WriteSpace();
                    v.Type.WriteTo(output);
                    if (!string.IsNullOrEmpty(v.Name)) {
                        output.WriteSpace();
                        output.Write(DisassemblerHelpers.Escape(v.Name), TextTokenType.Local);
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                        output.Write(',', TextTokenType.Operator);
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")", TextTokenType.Operator);
            }
            output.WriteLine();

            uint baseRva = rva == 0 ? 0 : rva + method.Body.HeaderSize;
            long baseOffs = baseRva == 0 ? 0 : method.Module.ToFileOffset(baseRva);
            using (var byteReader = !options.ShowILBytes || options.CreateInstructionBytesReader == null ? null : options.CreateInstructionBytesReader(method)) {
                if (detectControlStructure && body.Instructions.Count > 0) {
                    int index = 0;
                    HashSet<uint> branchTargets = GetBranchTargets(body.Instructions);
                    WriteStructureBody(body, new ILStructure(body), branchTargets, ref index, debugSymbols, method.Body.GetCodeSize(), baseRva, baseOffs, byteReader, method);
                }
                else {
                    var instructions = method.Body.Instructions;
                    for (int i = 0; i < instructions.Count; i++) {
                        var inst = instructions[i];
                        var startLocation = output.Location;
                        inst.WriteTo(output, options, baseRva, baseOffs, byteReader, method);

                        if (debugSymbols != null) {
                            // add IL code mappings - used in debugger
                            var next = i + 1 < instructions.Count ? instructions[i + 1] : null;
                            debugSymbols.MemberCodeMappings.Add(
                                new SourceCodeMapping() {
                                    StartLocation = output.Location,
                                    EndLocation = output.Location,
                                    ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)method.Body.GetCodeSize() : next.Offset),
                                    MemberMapping = debugSymbols
                                });
                        }

                        output.WriteLine();
                    }
                    if (method.Body.HasExceptionHandlers) {
                        output.WriteLine();
                        foreach (var eh in method.Body.ExceptionHandlers) {
                            eh.WriteTo(output, method);
                            output.WriteLine();
                        }
                    }
                }
            }
        }
 public virtual void Visit(MemberMapping member)
 {
 }
 public virtual string GetMemberKey(MemberMapping member)
 {
     return MemberHelper.GetMemberSignature(member.Representative, NameFormattingOptions.Signature | NameFormattingOptions.TypeParameters | NameFormattingOptions.OmitContainingType);
 }