Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata for Injected Properties #19

Open
ds5678 opened this issue Jan 16, 2023 · 1 comment
Open

Metadata for Injected Properties #19

ds5678 opened this issue Jan 16, 2023 · 1 comment

Comments

@ds5678
Copy link
Collaborator

ds5678 commented Jan 16, 2023

Motivation

Injected properties currently can't be (easily) used outside the pass they're created in. This prevents them from being used in other passes, such as the equality comparison pass.

Design Concept

sealed class InjectedProperty
{
	InjectedPropertyType Type { get; }
	string Name { get; }
}
abstract class InjectedPropertyType
{
	abstract TypeSignature Signature { get; }
	abstract IMethodDefOrRef EqualsMethod { get; }
	//etc
}

Other considerations

Existing properties on UnityAssetBase and UnityObjectBase may need metadata, too.

ds5678 added a commit that referenced this issue Mar 21, 2023
@ds5678
Copy link
Collaborator Author

ds5678 commented Jun 2, 2023

internal static class PropertyInjector
{
	public static void InjectFullProperty(ClassGroupBase group, TypeSignature propertySignature, string propertyName, bool nullable)
	{
		InjectedInterfaceProperty interfaceProperty;
		{
			PropertyDefinition property = group.Interface.AddFullProperty(propertyName, InterfaceUtils.InterfacePropertyDeclaration, propertySignature);
			if (nullable)
			{
				property.AddNullableAttributesForMaybeNull();
			}
			interfaceProperty = new InjectedInterfaceProperty(property, group);
			group.InterfaceProperties.Add(interfaceProperty);
		}

		foreach (GeneratedClassInstance instance in group.Instances)
		{
			TypeDefinition type = instance.Type;
			FieldDefinition field = type.AddField(propertySignature, $"m_{propertyName}");
			PropertyDefinition property = type.ImplementFullProperty(propertyName, InterfaceUtils.InterfacePropertyImplementation, null, field);
			if (nullable)
			{
				field.AddNullableAttributesForMaybeNull();
				property.AddNullableAttributesForMaybeNull();
			}
			instance.Properties.Add(new InjectedClassProperty(property, field, interfaceProperty, instance));
		}
	}

	private sealed class InjectedInterfaceProperty : InterfaceProperty
	{
		public InjectedInterfaceProperty(PropertyDefinition definition, ClassGroupBase group) : base(definition, group)
		{
		}
		public override bool IsInjected => true;
	}
	private sealed class InjectedClassProperty : ClassProperty
	{
		public InjectedClassProperty(PropertyDefinition definition, FieldDefinition backingField, InjectedInterfaceProperty @base, GeneratedClassInstance @class) : base(definition, backingField, @base, @class)
		{
		}
		public override bool IsInjected => true;
	}
}

ds5678 added a commit that referenced this issue Aug 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant