diff --git a/Assets/Mirror/Editor/Weaver/Processors/MessageClassProcessor.cs b/Assets/Mirror/Editor/Weaver/Processors/MessageClassProcessor.cs index 131a6a560..f0c250436 100644 --- a/Assets/Mirror/Editor/Weaver/Processors/MessageClassProcessor.cs +++ b/Assets/Mirror/Editor/Weaver/Processors/MessageClassProcessor.cs @@ -56,18 +56,6 @@ static void GenerateSerialization(TypeDefinition td) if (field.IsStatic || field.IsPrivate || field.IsSpecialName) continue; - if (field.FieldType.Resolve().HasGenericParameters && !field.FieldType.FullName.StartsWith("System.ArraySegment`1", System.StringComparison.Ordinal)) - { - Weaver.Error($"{field} cannot have generic type {field.FieldType}. Consider creating a class that derives the generic type"); - return; - } - - if (field.FieldType.Resolve().IsInterface) - { - Weaver.Error($"{field} has unsupported type. Use a concrete class instead of interface {field.FieldType}"); - return; - } - MethodReference writeFunc = Writers.GetWriteFunc(field.FieldType); if (writeFunc != null) { diff --git a/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs b/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs index 6c54025b6..65722a329 100644 --- a/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs +++ b/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs @@ -684,16 +684,6 @@ public static bool ProcessMethodsValidateParameters(MethodReference md, CustomAt Weaver.Error($"{md} cannot have optional parameters"); return false; } - if (p.ParameterType.Resolve().IsAbstract) - { - Weaver.Error($"{md} has invalid parameter {p}. Use concrete type instead of abstract type {p.ParameterType}"); - return false; - } - if (p.ParameterType.IsByReference) - { - Weaver.Error($"{md} has invalid parameter {p}. Use supported type instead of reference type {p.ParameterType}"); - return false; - } // TargetRPC is an exception to this rule and can have a NetworkConnection as first parameter if (p.ParameterType.FullName == Weaver.NetworkConnectionType.FullName && !(ca.AttributeType.FullName == Weaver.TargetRpcType.FullName && i == 0)) @@ -701,14 +691,6 @@ public static bool ProcessMethodsValidateParameters(MethodReference md, CustomAt Weaver.Error($"{md} has invalid parameer {p}. Cannot pass NeworkConnections"); return false; } - if (p.ParameterType.Resolve().IsDerivedFrom(Weaver.ComponentType)) - { - if (p.ParameterType.FullName != Weaver.NetworkIdentityType.FullName) - { - Weaver.Error($"{md} has invalid parameter {p}. Cannot pass components in remote method calls"); - return false; - } - } } return true; } diff --git a/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs b/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs index 5ce176601..ffad90c55 100644 --- a/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs +++ b/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs @@ -294,36 +294,12 @@ public static void ProcessSyncVars(TypeDefinition td, List sync { TypeDefinition resolvedField = fd.FieldType.Resolve(); - if (resolvedField.IsDerivedFrom(Weaver.NetworkBehaviourType)) - { - Weaver.Error($"{fd} has invalid type. SyncVars cannot be NetworkBehaviours"); - return; - } - - if (resolvedField.IsDerivedFrom(Weaver.ScriptableObjectType)) - { - Weaver.Error($"{fd} has invalid type. SyncVars cannot be scriptable objects"); - return; - } - if ((fd.Attributes & FieldAttributes.Static) != 0) { Weaver.Error($"{fd} cannot be static"); return; } - if (resolvedField.HasGenericParameters) - { - Weaver.Error($"{fd} has invalid type. SyncVars cannot have generic parameters"); - return; - } - - if (resolvedField.IsInterface) - { - Weaver.Error($"{fd} has invalid type. Use a concrete type instead of interface {fd.FieldType}"); - return; - } - if (fd.FieldType.IsArray) { Weaver.Error($"{fd} has invalid type. Use SyncLists instead of arrays"); diff --git a/Assets/Mirror/Editor/Weaver/Readers.cs b/Assets/Mirror/Editor/Weaver/Readers.cs index a50798d45..dfc5961d6 100644 --- a/Assets/Mirror/Editor/Weaver/Readers.cs +++ b/Assets/Mirror/Editor/Weaver/Readers.cs @@ -34,11 +34,30 @@ public static MethodReference GetReadFunc(TypeReference variable, int recursionC Weaver.Error($"{variable} is not a supported type"); return null; } - + if (td.IsDerivedFrom(Weaver.ScriptableObjectType)) + { + Weaver.Error($"Cannot generate reader for scriptable object {variable}. Use a supported type or provide a custom reader"); + return null; + } + if (td.IsDerivedFrom(Weaver.ComponentType)) + { + Weaver.Error($"Cannot generate reader for component type {variable}. Use a supported type or provide a custom reader"); + return null; + } if (variable.IsByReference) { // error?? - Weaver.Error($"{variable} is not a supported reference type"); + Weaver.Error($"Cannot pass type {variable} by reference"); + return null; + } + if (td.HasGenericParameters && !td.FullName.StartsWith("System.ArraySegment`1", System.StringComparison.Ordinal)) + { + Weaver.Error($"Cannot generate reader for generic variable {variable}. Use a concrete type or provide a custom reader"); + return null; + } + if (td.IsInterface) + { + Weaver.Error($"Cannot generate reader for interface variable {variable}. Use a concrete type or provide a custom reader"); return null; } diff --git a/Assets/Mirror/Editor/Weaver/Writers.cs b/Assets/Mirror/Editor/Weaver/Writers.cs index 040960d28..1763be872 100644 --- a/Assets/Mirror/Editor/Weaver/Writers.cs +++ b/Assets/Mirror/Editor/Weaver/Writers.cs @@ -31,9 +31,36 @@ public static MethodReference GetWriteFunc(TypeReference variable, int recursion if (variable.IsByReference) { // error?? - Weaver.Error($"{variable} has unsupported type. Use one of Mirror supported types instead"); + Weaver.Error($"Cannot pass {variable} by reference"); return null; } + TypeDefinition td = variable.Resolve(); + if (td == null) + { + Weaver.Error($"{variable} is not a supported type. Use a supported type or provide a custom writer"); + return null; + } + if (td.IsDerivedFrom(Weaver.ScriptableObjectType)) + { + Weaver.Error($"Cannot generate writer for scriptable object {variable}. Use a supported type or provide a custom writer"); + return null; + } + if (td.IsDerivedFrom(Weaver.ComponentType)) + { + Weaver.Error($"Cannot generate writer for component type {variable}. Use a supported type or provide a custom writer"); + return null; + } + if (td.HasGenericParameters && !td.FullName.StartsWith("System.ArraySegment`1", System.StringComparison.Ordinal)) + { + Weaver.Error($"Cannot generate writer for generic type {variable}. Use a concrete type or provide a custom writer"); + return null; + } + if (td.IsInterface) + { + Weaver.Error($"Cannot generate writer for interface {variable}. Use a concrete type or provide a custom writer"); + return null; + } + MethodDefinition newWriterFunc; @@ -112,18 +139,6 @@ static MethodDefinition GenerateStructWriterFunction(TypeReference variable, int if (field.IsStatic || field.IsPrivate) continue; - if (field.FieldType.Resolve().HasGenericParameters) - { - Weaver.Error($"{field} has unsupported type. Create a derived class instead of using generics"); - return null; - } - - if (field.FieldType.Resolve().IsInterface) - { - Weaver.Error($"{field} has unsupported type. Use a concrete class instead of an interface"); - return null; - } - MethodReference writeFunc = GetWriteFunc(field.FieldType, recursionCount + 1); if (writeFunc != null) { diff --git a/Assets/Mirror/Tests/WeaverTest.cs b/Assets/Mirror/Tests/WeaverTest.cs index 2d95af3aa..dbd4f732c 100644 --- a/Assets/Mirror/Tests/WeaverTest.cs +++ b/Assets/Mirror/Tests/WeaverTest.cs @@ -177,16 +177,16 @@ public void SyncVarsWrongHookType() public void SyncVarsDerivedNetworkBehaviour() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/MySyncVar MirrorTest.MirrorTestPlayer::invalidVar has invalid type. SyncVars cannot be NetworkBehaviours")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for component type MirrorTest.MirrorTestPlayer/MySyncVar. Use a supported type or provide a custom writer")); } [Test] public void SyncVarsDerivedScriptableObject() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/MySyncVar MirrorTest.MirrorTestPlayer::invalidVar has invalid type. SyncVars cannot be scriptable objects")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for scriptable object MirrorTest.MirrorTestPlayer/MySyncVar. Use a supported type or provide a custom writer")); } [Test] @@ -201,24 +201,24 @@ public void SyncVarsStatic() public void SyncVarsGenericParam() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/MySyncVar`1 MirrorTest.MirrorTestPlayer::invalidVar has invalid type. SyncVars cannot have generic parameters")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for generic type MirrorTest.MirrorTestPlayer/MySyncVar`1. Use a concrete type or provide a custom writer")); } [Test] public void SyncVarsInterface() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/MySyncVar MirrorTest.MirrorTestPlayer::invalidVar has invalid type. Use a concrete type instead of interface MirrorTest.MirrorTestPlayer/MySyncVar")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for interface MirrorTest.MirrorTestPlayer/MySyncVar. Use a concrete type or provide a custom writer")); } [Test] public void SyncVarsDifferentModule() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: UnityEngine.TextMesh MirrorTest.MirrorTestPlayer::invalidVar has unsupported type. Use a supported Mirror type instead")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for component type UnityEngine.TextMesh. Use a supported type or provide a custom writer")); } [Test] @@ -292,16 +292,16 @@ public void SyncListStructGenericGeneric() public void SyncListStructMemberGeneric() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/MyGenericStruct`1 MirrorTest.MirrorTestPlayer/MyStruct::potato has unsupported type. Create a derived class instead of using generics")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(3)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for generic type MirrorTest.MirrorTestPlayer/MyGenericStruct`1. Use a concrete type or provide a custom writer")); } [Test] public void SyncListStructMemberInterface() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/IPotato MirrorTest.MirrorTestPlayer/MyStruct::potato has unsupported type. Use a concrete class instead of an interface")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(3)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for interface MirrorTest.MirrorTestPlayer/IPotato. Use a concrete type or provide a custom writer")); } [Test] @@ -404,24 +404,24 @@ public void NetworkBehaviourTargetRpcParamOptional() public void NetworkBehaviourTargetRpcParamRef() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::TargetRpcCantHaveParamRef(Mirror.NetworkConnection,System.Int32&) has invalid parameter monkeys. Use supported type instead of reference type System.Int32&")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(4)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot pass System.Int32& by reference")); } [Test] public void NetworkBehaviourTargetRpcParamAbstract() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::TargetRpcCantHaveParamAbstract(Mirror.NetworkConnection,MirrorTest.MirrorTestPlayer/AbstractClass) has invalid parameter monkeys. Use concrete type instead of abstract type MirrorTest.MirrorTestPlayer/AbstractClass")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(3)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/AbstractClass can't be deserialized bcause i has no default constructor")); } [Test] public void NetworkBehaviourTargetRpcParamComponent() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::TargetRpcCantHaveParamComponent(Mirror.NetworkConnection,MirrorTest.MirrorTestPlayer/ComponentClass) has invalid parameter monkeyComp. Cannot pass components in remote method calls")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(4)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for component type MirrorTest.MirrorTestPlayer/ComponentClass. Use a supported type or provide a custom writer")); } [Test] @@ -483,24 +483,24 @@ public void NetworkBehaviourClientRpcParamOptional() public void NetworkBehaviourClientRpcParamRef() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::RpcCantHaveParamRef(System.Int32&) has invalid parameter monkeys. Use supported type instead of reference type System.Int32&")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(4)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot pass System.Int32& by reference")); } [Test] public void NetworkBehaviourClientRpcParamAbstract() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::RpcCantHaveParamAbstract(MirrorTest.MirrorTestPlayer/AbstractClass) has invalid parameter monkeys. Use concrete type instead of abstract type MirrorTest.MirrorTestPlayer/AbstractClass")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(3)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/AbstractClass can't be deserialized bcause i has no default constructor")); } [Test] public void NetworkBehaviourClientRpcParamComponent() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::RpcCantHaveParamComponent(MirrorTest.MirrorTestPlayer/ComponentClass) has invalid parameter monkeyComp. Cannot pass components in remote method calls")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(4)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for component type MirrorTest.MirrorTestPlayer/ComponentClass. Use a supported type or provide a custom writer")); } [Test] @@ -539,24 +539,24 @@ public void NetworkBehaviourCmdParamOptional() public void NetworkBehaviourCmdParamRef() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::CmdCantHaveParamRef(System.Int32&) has invalid parameter monkeys. Use supported type instead of reference type System.Int32&")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(4)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot pass System.Int32& by reference")); } [Test] public void NetworkBehaviourCmdParamAbstract() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::CmdCantHaveParamAbstract(MirrorTest.MirrorTestPlayer/AbstractClass) has invalid parameter monkeys. Use concrete type instead of abstract type MirrorTest.MirrorTestPlayer/AbstractClass")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(3)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.MirrorTestPlayer/AbstractClass can't be deserialized bcause i has no default constructor")); } [Test] public void NetworkBehaviourCmdParamComponent() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: System.Void MirrorTest.MirrorTestPlayer::CmdCantHaveParamComponent(MirrorTest.MirrorTestPlayer/ComponentClass) has invalid parameter monkeyComp. Cannot pass components in remote method calls")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(4)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for component type MirrorTest.MirrorTestPlayer/ComponentClass. Use a supported type or provide a custom writer")); } [Test] @@ -794,16 +794,16 @@ public void MessageInvalidDeserializeFieldType() public void MessageMemberGeneric() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.HasGeneric`1 MirrorTest.PrefabClone::invalidField cannot have generic type MirrorTest.HasGeneric`1. Consider creating a class that derives the generic type")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for generic type MirrorTest.HasGeneric`1. Use a concrete type or provide a custom writer")); } [Test] public void MessageMemberInterface() { Assert.That(CompilationFinishedHook.WeaveFailed, Is.True); - Assert.That(m_weaverErrors.Count, Is.EqualTo(1)); - Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: MirrorTest.SuperCoolInterface MirrorTest.PrefabClone::invalidField has unsupported type. Use a concrete class instead of interface MirrorTest.SuperCoolInterface")); + Assert.That(m_weaverErrors.Count, Is.EqualTo(2)); + Assert.That(m_weaverErrors[0], Is.EqualTo("Mirror.Weaver error: Cannot generate writer for interface MirrorTest.SuperCoolInterface. Use a concrete type or provide a custom writer")); } #endregion }