Skip to content

Use tuple element name and dynamic type information for local from PDB #3112

@ElektroKill

Description

@ElektroKill

Currently, the decompiler will emit a tuple type with no element names for local variables. Some which where of type dynamic in source will also appear as object variables due to the decompiling not being able to establish that the variable was in fact dynamic.

Example:

public static void Main(string[] args) {
	dynamic obj = GetDynamicAnonymousObject();
	Console.WriteLine((object)obj);
	UseDynamic((object)obj);

	(int d, int e) tuple = GetTuple();
	Console.WriteLine(tuple);
	UseTuple(tuple);

	(int, int) tuple2 = GetTuple();
	Console.WriteLine(tuple2);
	UseTuple(tuple2);

	(int, int g) tuple3 = GetTuple();
	Console.WriteLine(tuple3);
	UseTuple(tuple3);
}

public static dynamic GetDynamicAnonymousObject() {
	return new { Name = "John", Age = 30 };
}

public static (int a, int b) GetTuple() {
	return (1, 2);
}

public static void UseDynamic(dynamic dynamic) {
	var obj = ((object)dynamic).ToString();
}

public static void UseTuple((int a, int b) tuple) {
	var obj = tuple.ToString();
}

Decompiled code:

public static void Main(string[] args)
{
	object obj = GetDynamicAnonymousObject();
	Console.WriteLine(obj);
	UseDynamic(obj);
	(int, int) tuple = GetTuple();
	Console.WriteLine(tuple);
	UseTuple(tuple);
	(int, int) tuple2 = GetTuple();
	Console.WriteLine(tuple2);
	UseTuple(tuple2);
	(int, int) tuple3 = GetTuple();
	Console.WriteLine(tuple3);
	UseTuple(tuple3);
}

public static dynamic GetDynamicAnonymousObject()
{
	return new
	{
		Name = "John",
		Age = 30
	};
}

public static (int a, int b) GetTuple()
{
	return (1, 2);
}

public static void UseDynamic(dynamic dynamic)
{
	((object)dynamic).ToString();
}

public static void UseTuple((int a, int b) tuple)
{
	tuple.ToString();
}

The decompiled code loses the dynamic type and the tuple element names as they are not present in the compiled assembly. However, they are present in the PDB (both PortablePdb and WindowsPdb support this extra information)
image
(image taken using ILSpy built from source after applying the patch from #3111)

This information could be utilized by the decompiler for more accurate decompilation in cases when this information is present.

Proposed solution:

  • Modify IDebugInfoProvider to add an additional method to retrieve "additional" local information (tuple element names and dynamic type info) -Something like bool TryGetName(MethodDefinitionHandle method, int index, out string[] tupleElementNames, out bool[] dynamicFlags)
  • Implement a new TypeVisitor which will apply the extra data from the PDB to the type system types.
  • Call the above method and visitor in ILReader.CreateILVariable after the type has been resolved in the type system to add additional information to the type.

If there are no objections the proposed suggestion, I will open a PR :D

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions