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; } }
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; }
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; }
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 }); } }
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); }
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); }
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); }
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); }
/// <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); }
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); }
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); }
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(); } }
/// <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)); } }
/// <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); }
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); }
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); }
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; } }
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(); } }
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); }
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; }
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); }
/// <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))); }
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(); }
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; } } }
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); }
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); } }
/// <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); }
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; }
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; } } }
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(); } }
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); }
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); }
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; } } }
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; }
public override void Visit(MemberMapping mapping) { Visit(mapping.Differences); base.Visit(mapping); }
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; } }
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); }