Simplify finding custom attributes

This commit is contained in:
Paul Pacheco 2020-03-26 09:52:39 -05:00
parent d530d7a1e4
commit 7a6b854179
4 changed files with 88 additions and 88 deletions

View File

@ -138,7 +138,7 @@ public static MethodReference MakeHostInstanceGeneric(this MethodReference self,
return Weaver.CurrentAssembly.MainModule.ImportReference(reference);
}
public static CustomAttribute GetCustomAttribute(this MethodDefinition method, string attributeName)
public static CustomAttribute GetCustomAttribute(this ICustomAttributeProvider method, string attributeName)
{
foreach (CustomAttribute ca in method.CustomAttributes)
{
@ -148,5 +148,15 @@ public static CustomAttribute GetCustomAttribute(this MethodDefinition method, s
return null;
}
public static bool HasCustomAttribute(this ICustomAttributeProvider attributeProvider, TypeReference attribute)
{
foreach (CustomAttribute ca in attributeProvider.CustomAttributes)
{
if (ca.AttributeType.FullName == attribute.FullName)
return true;
}
return false;
}
}
}

View File

@ -16,14 +16,9 @@ static void ProcessSyncVars(TypeDefinition td)
// find syncvars
foreach (FieldDefinition fd in td.Fields)
{
foreach (CustomAttribute ca in fd.CustomAttributes)
{
if (ca.AttributeType.FullName == Weaver.SyncVarType.FullName)
{
Weaver.Error($"[SyncVar] {fd} must be inside a NetworkBehaviour. {td} is not a NetworkBehaviour");
}
}
if (fd.HasCustomAttribute(Weaver.SyncVarType))
Weaver.Error($"[SyncVar] {fd} must be inside a NetworkBehaviour. {td} is not a NetworkBehaviour");
if (SyncObjectInitializer.ImplementsSyncObject(fd.FieldType))
{
Weaver.Error($"{fd} is a SyncObject and must be inside a NetworkBehaviour. {td} is not a NetworkBehaviour");

View File

@ -112,43 +112,42 @@ public static void ProcessEvents(TypeDefinition td, List<EventDefinition> events
// find events
foreach (EventDefinition ed in td.Events)
{
foreach (CustomAttribute ca in ed.CustomAttributes)
CustomAttribute ca = ed.GetCustomAttribute(Weaver.SyncEventType.FullName);
if (ca != null)
{
if (ca.AttributeType.FullName == Weaver.SyncEventType.FullName)
if (!ed.Name.StartsWith("Event"))
{
if (!ed.Name.StartsWith("Event"))
{
Weaver.Error($"{ed} must start with Event. Consider renaming it to Event{ed.Name}");
return;
}
if (ed.EventType.Resolve().HasGenericParameters)
{
Weaver.Error($"{ed} must not have generic parameters. Consider creating a new class that inherits from {ed.EventType} instead");
return;
}
events.Add(ed);
MethodDefinition eventFunc = ProcessEventInvoke(td, ed);
if (eventFunc == null)
{
return;
}
td.Methods.Add(eventFunc);
eventInvocationFuncs.Add(eventFunc);
Weaver.DLog(td, "ProcessEvent " + ed);
MethodDefinition eventCallFunc = ProcessEventCall(td, ed, ca);
td.Methods.Add(eventCallFunc);
// original weaver compares .Name, not EventDefinition.
Weaver.WeaveLists.replaceEvents[ed.Name] = eventCallFunc;
Weaver.DLog(td, " Event: " + ed.Name);
break;
Weaver.Error($"{ed} must start with Event. Consider renaming it to Event{ed.Name}");
return;
}
if (ed.EventType.Resolve().HasGenericParameters)
{
Weaver.Error($"{ed} must not have generic parameters. Consider creating a new class that inherits from {ed.EventType} instead");
return;
}
events.Add(ed);
MethodDefinition eventFunc = ProcessEventInvoke(td, ed);
if (eventFunc == null)
{
return;
}
td.Methods.Add(eventFunc);
eventInvocationFuncs.Add(eventFunc);
Weaver.DLog(td, "ProcessEvent " + ed);
MethodDefinition eventCallFunc = ProcessEventCall(td, ed, ca);
td.Methods.Add(eventCallFunc);
// original weaver compares .Name, not EventDefinition.
Weaver.WeaveLists.replaceEvents[ed.Name] = eventCallFunc;
Weaver.DLog(td, " Event: " + ed.Name);
break;
}
}
}

View File

@ -14,38 +14,37 @@ public static class SyncVarProcessor
public static bool CheckForHookFunction(TypeDefinition td, FieldDefinition syncVar, out MethodDefinition foundMethod)
{
foundMethod = null;
foreach (CustomAttribute ca in syncVar.CustomAttributes)
{
if (ca.AttributeType.FullName == Weaver.SyncVarType.FullName)
{
foreach (CustomAttributeNamedArgument customField in ca.Fields)
{
if (customField.Name == "hook")
{
string hookFunctionName = customField.Argument.Value as string;
CustomAttribute ca = syncVar.GetCustomAttribute(Weaver.SyncVarType.FullName);
foreach (MethodDefinition m in td.Methods)
if (ca != null)
{
foreach (CustomAttributeNamedArgument customField in ca.Fields)
{
if (customField.Name == "hook")
{
string hookFunctionName = customField.Argument.Value as string;
foreach (MethodDefinition m in td.Methods)
{
if (m.Name == hookFunctionName)
{
if (m.Name == hookFunctionName)
if (m.Parameters.Count == 2)
{
if (m.Parameters.Count == 2)
if (m.Parameters[0].ParameterType != syncVar.FieldType ||
m.Parameters[1].ParameterType != syncVar.FieldType)
{
if (m.Parameters[0].ParameterType != syncVar.FieldType ||
m.Parameters[1].ParameterType != syncVar.FieldType)
{
Weaver.Error($"{m} should have signature:\npublic void {hookFunctionName}({syncVar.FieldType} oldValue, {syncVar.FieldType} newValue) {{ }}");
return false;
}
foundMethod = m;
return true;
Weaver.Error($"{m} should have signature:\npublic void {hookFunctionName}({syncVar.FieldType} oldValue, {syncVar.FieldType} newValue) {{ }}");
return false;
}
Weaver.Error($"{m} should have signature:\npublic void {hookFunctionName}({syncVar.FieldType} oldValue, {syncVar.FieldType} newValue) {{ }}");
return false;
foundMethod = m;
return true;
}
Weaver.Error($"{m} should have signature:\npublic void {hookFunctionName}({syncVar.FieldType} oldValue, {syncVar.FieldType} newValue) {{ }}");
return false;
}
Weaver.Error($"No hook implementation found for {syncVar}. Add this method to your class:\npublic void {hookFunctionName}({syncVar.FieldType} oldValue, {syncVar.FieldType} newValue) {{ }}");
return false;
}
Weaver.Error($"No hook implementation found for {syncVar}. Add this method to your class:\npublic void {hookFunctionName}({syncVar.FieldType} oldValue, {syncVar.FieldType} newValue) {{ }}");
return false;
}
}
}
@ -301,30 +300,28 @@ public static void ProcessSyncVars(TypeDefinition td, List<FieldDefinition> sync
// find syncvars
foreach (FieldDefinition fd in td.Fields)
{
foreach (CustomAttribute ca in fd.CustomAttributes)
if (fd.HasCustomAttribute(Weaver.SyncVarType))
{
if (ca.AttributeType.FullName == Weaver.SyncVarType.FullName)
TypeDefinition resolvedField = fd.FieldType.Resolve();
if ((fd.Attributes & FieldAttributes.Static) != 0)
{
TypeDefinition resolvedField = fd.FieldType.Resolve();
Weaver.Error($"{fd} cannot be static");
return;
}
if ((fd.Attributes & FieldAttributes.Static) != 0)
{
Weaver.Error($"{fd} cannot be static");
return;
}
if (fd.FieldType.IsArray)
{
Weaver.Error($"{fd} has invalid type. Use SyncLists instead of arrays");
return;
}
if (SyncObjectInitializer.ImplementsSyncObject(fd.FieldType))
{
Log.Warning($"{fd} has [SyncVar] attribute. SyncLists should not be marked with SyncVar");
break;
}
if (fd.FieldType.IsArray)
{
Weaver.Error($"{fd} has invalid type. Use SyncLists instead of arrays");
return;
}
if (SyncObjectInitializer.ImplementsSyncObject(fd.FieldType))
{
Log.Warning($"{fd} has [SyncVar] attribute. SyncLists should not be marked with SyncVar");
}
else
{
syncVars.Add(fd);
ProcessSyncVar(td, fd, syncVarNetIds, 1L << dirtyBitCounter);
@ -336,7 +333,6 @@ public static void ProcessSyncVars(TypeDefinition td, List<FieldDefinition> sync
Weaver.Error($"{td} has too many SyncVars. Consider refactoring your class into multiple components");
return;
}
break;
}
}