Пример #1
0
        private static bool ContainsVariable(this ScopeDebugInformation debugInfo, VariableDefinition variable)
        {
            // Note: just checking for index might not be sufficient
            var hasVariable = debugInfo.Variables.Any(x => x.Index == variable.Index);

            if (hasVariable)
            {
                return(true);
            }

            // Important: check nested scopes
            for (var i = 0; i < debugInfo.Scopes.Count; i++)
            {
                if (ContainsVariable(debugInfo.Scopes[i], variable))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
        static ScopeDebugInformation ReadScopeAndLocals(PdbScope scope, MethodDebugInformation info)
        {
            var parent = new ScopeDebugInformation();

            parent.Start = new InstructionOffset((int)scope.offset);
            parent.End   = new InstructionOffset((int)(scope.offset + scope.length));

            if (!scope.slots.IsNullOrEmpty())
            {
                parent.variables = new Collection <VariableDebugInformation> (scope.slots.Length);

                foreach (PdbSlot slot in scope.slots)
                {
                    var index    = (int)slot.slot;
                    var variable = new VariableDebugInformation(index, slot.name);
                    if (slot.flags == 4)
                    {
                        variable.IsDebuggerHidden = true;
                    }
                    parent.variables.Add(variable);
                }
            }

            if (!scope.constants.IsNullOrEmpty())
            {
                parent.constants = new Collection <ConstantDebugInformation> (scope.constants.Length);

                foreach (var constant in scope.constants)
                {
                    parent.constants.Add(new ConstantDebugInformation(
                                             constant.name,
                                             (TypeReference)info.method.Module.LookupToken((int)constant.token),
                                             constant.value));
                }
            }

            parent.scopes = ReadScopeAndLocals(scope.scopes, info);

            return(parent);
        }
Пример #3
0
        public void RemoveVariableWithDebugInfo()
        {
            var object_ref = new TypeReference("System", "Object", null, null, false);
            var method     = new MethodDefinition("foo", MethodAttributes.Static, object_ref);
            var body       = new MethodBody(method);
            var il         = body.GetILProcessor();

            il.Emit(OpCodes.Ret);

            var x  = new VariableDefinition(object_ref);
            var y  = new VariableDefinition(object_ref);
            var z  = new VariableDefinition(object_ref);
            var z2 = new VariableDefinition(object_ref);

            body.Variables.Add(x);
            body.Variables.Add(y);
            body.Variables.Add(z);
            body.Variables.Add(z2);

            var scope = new ScopeDebugInformation(body.Instructions [0], body.Instructions [0]);

            method.DebugInformation = new MethodDebugInformation(method)
            {
                Scope = scope
            };
            scope.Variables.Add(new VariableDebugInformation(x.index, nameof(x)));
            scope.Variables.Add(new VariableDebugInformation(y.index, nameof(y)));
            scope.Variables.Add(new VariableDebugInformation(z.index, nameof(z)));
            scope.Variables.Add(new VariableDebugInformation(z2, nameof(z2)));

            body.Variables.Remove(y);

            Assert.AreEqual(3, scope.Variables.Count);
            Assert.AreEqual(x.Index, scope.Variables [0].Index);
            Assert.AreEqual(nameof(x), scope.Variables [0].Name);
            Assert.AreEqual(z.Index, scope.Variables [1].Index);
            Assert.AreEqual(nameof(z), scope.Variables [1].Name);
            Assert.AreEqual(z2.Index, scope.Variables [2].Index);
            Assert.AreEqual(nameof(z2), scope.Variables [2].Name);
        }
Пример #4
0
        ScopeDebugInformation ReadScopeAndLocals(PdbScope scope, MethodDebugInformation info)
        {
            var parent = new ScopeDebugInformation();

            parent.Start = new InstructionOffset((int)scope.offset);
            parent.End   = new InstructionOffset((int)(scope.offset + scope.length));

            if (!scope.slots.IsNullOrEmpty())
            {
                parent.variables = new Collection <VariableDebugInformation> (scope.slots.Length);

                foreach (PdbSlot slot in scope.slots)
                {
                    if ((slot.flags & 1) != 0)                     // parameter names
                    {
                        continue;
                    }

                    var index    = (int)slot.slot;
                    var variable = new VariableDebugInformation(index, slot.name);
                    if ((slot.flags & 4) != 0)
                    {
                        variable.IsDebuggerHidden = true;
                    }
                    parent.variables.Add(variable);
                }
            }

            if (!scope.constants.IsNullOrEmpty())
            {
                parent.constants = new Collection <ConstantDebugInformation> (scope.constants.Length);

                foreach (var constant in scope.constants)
                {
                    var type  = info.Method.Module.Read(constant, (c, r) => r.ReadConstantSignature(new MetadataToken(c.token)));
                    var value = constant.value;

                    // Object "null" is encoded as integer
                    if (type != null && !type.IsValueType && value is int && (int)value == 0)
                    {
                        value = null;
                    }

                    parent.constants.Add(new ConstantDebugInformation(constant.name, type, value));
                }
            }

            if (!scope.usedNamespaces.IsNullOrEmpty())
            {
                ImportDebugInformation import;
                if (imports.TryGetValue(scope, out import))
                {
                    parent.import = import;
                }
                else
                {
                    import = GetImport(scope, info.Method.Module);
                    imports.Add(scope, import);
                    parent.import = import;
                }
            }

            parent.scopes = ReadScopeAndLocals(scope.scopes, info);

            return(parent);
        }
Пример #5
0
        void DefineScope(ScopeDebugInformation scope, MethodDebugInformation info, out MetadataToken import_parent)
        {
            var start_offset = scope.Start.Offset;
            var end_offset   = scope.End.IsEndOfMethod
                                ? info.code_size
                                : scope.End.Offset;

            import_parent = new MetadataToken(0u);

            writer.OpenScope(start_offset);

            if (scope.Import != null && scope.Import.HasTargets && !import_info_to_parent.TryGetValue(info.scope.Import, out import_parent))
            {
                foreach (var target in scope.Import.Targets)
                {
                    switch (target.Kind)
                    {
                    case ImportTargetKind.ImportNamespace:
                        writer.UsingNamespace("U" + target.@namespace);
                        break;

                    case ImportTargetKind.ImportType:
                        writer.UsingNamespace("T" + TypeParser.ToParseable(target.type));
                        break;

                    case ImportTargetKind.DefineNamespaceAlias:
                        writer.UsingNamespace("A" + target.Alias + " U" + target.@namespace);
                        break;

                    case ImportTargetKind.DefineTypeAlias:
                        writer.UsingNamespace("A" + target.Alias + " T" + TypeParser.ToParseable(target.type));
                        break;
                    }
                }

                import_info_to_parent.Add(info.scope.Import, info.method.MetadataToken);
            }

            var sym_token = info.local_var_token.ToInt32();

            if (!scope.variables.IsNullOrEmpty())
            {
                for (int i = 0; i < scope.variables.Count; i++)
                {
                    var variable = scope.variables [i];
                    DefineLocalVariable(variable, sym_token, start_offset, end_offset);
                }
            }

            if (!scope.constants.IsNullOrEmpty())
            {
                for (int i = 0; i < scope.constants.Count; i++)
                {
                    var constant = scope.constants [i];
                    DefineConstant(constant);
                }
            }

            if (!scope.scopes.IsNullOrEmpty())
            {
                for (int i = 0; i < scope.scopes.Count; i++)
                {
                    MetadataToken _;
                    DefineScope(scope.scopes [i], info, out _);
                }
            }

            writer.CloseScope(end_offset);
        }