Exemple #1
0
        public bool CheckFieldForUnityImplicits([NotNull] IField field, [NotNull] IPsiModule module)
        {
            ITypeElement containingType = field.GetContainingType();

            if (containingType == null)
            {
                return(false);
            }
            bool serializable = containingType.HasAttributeInstance(new ClrTypeName("System.SerializableAttribute"), true);
            bool unityObject  = containingType.GetSuperTypes().Any(t => IsUnityImplicitType(t, module));

            if (!serializable && !unityObject)
            {
                return(false);
            }
            if (field.GetAccessRights() == AccessRights.PUBLIC)
            {
                return(true);
            }
            foreach (KeyValuePair <string, string> pair in m_unitySettings.UnityUsageAttributes.EnumIndexedValues())
            {
                bool hasAtttribute = field.HasAttributeInstance(new ClrTypeName(pair.Value), true);
                if (hasAtttribute)
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #2
0
        // NOTE: This method assumes that the type is not a descendant of UnityEngine.Object!
        private bool IsSerializableType([CanBeNull] ITypeElement type, [NotNull] IProject project, bool isTypeUsage,
                                        bool hasSerializeReference = false)
        {
            if (!(type is IStruct || type is IClass))
            {
                return(false);
            }

            if (isTypeUsage)
            {
                // Type usage (e.g. field declaration) is stricter. Means it must be a concrete type with no type
                // parameters, unless the type usage is for [SerializeReference], which allows abstract types
                if (type is IModifiersOwner modifiersOwner && modifiersOwner.IsAbstract && !hasSerializeReference)
                {
                    return(false);
                }

                // Unity 2020.1 allows fields to have generic types. It's currently undocumented, but there are no
                // limitations on the number of type parameters, or even nested type parameters. The base type needs to
                // be serializable, but type parameters don't (if a non-serializable type parameter is used as a field,
                // it just isn't serialised).
                // https://blogs.unity3d.com/2020/03/17/unity-2020-1-beta-is-now-available-for-feedback/
                var unityVersion = myUnityVersion.GetActualVersion(project);
                if (unityVersion < new Version(2020, 1) && type is ITypeParametersOwner typeParametersOwner &&
                    typeParametersOwner.TypeParameters.Count > 0)
                {
                    return(false);
                }
            }

            if (type is IClass @class && @class.IsStaticClass())
            {
                return(false);
            }

            // System.Dictionary is special cased and excluded. We can see this in UnitySerializationLogic.cs in the
            // reference source repo. It also excludes anything with a full name beginning "System.", which includes
            // "System.Version" (which is marked [Serializable]). However, it doesn't exclude string, int, etc.
            // TODO: Rewrite this whole section to properly mimic UnitySerializationLogic.cs
            var name = type.GetClrName();

            if (Equals(name, KnownTypes.SystemVersion) || Equals(name, PredefinedType.GENERIC_DICTIONARY_FQN))
            {
                return(false);
            }

            using (CompilationContextCookie.GetExplicitUniversalContextIfNotSet())
                return(type.HasAttributeInstance(PredefinedType.SERIALIZABLE_ATTRIBUTE_CLASS, true));
        }
Exemple #3
0
        // NOTE: This method assumes that the type is not a descendant of UnityEngine.Object!
        private bool IsSerializableType([CanBeNull] ITypeElement type, [NotNull] IProject project, bool isTypeUsage)
        {
            if (!(type is IStruct || type is IClass))
            {
                return(false);
            }

            if (isTypeUsage)
            {
                // Type usage (e.g. field declaration) is stricter. Means it must be a concrete type with no type
                // parameters
                if (type is IModifiersOwner modifiersOwner && modifiersOwner.IsAbstract)
                {
                    return(false);
                }

                // Unity 2020.1 allows fields to have generic types. It's currently undocumented, but there are no
                // limitations on the number of type parameters, or even nested type parameters. The base type needs to
                // be serializable, but type parameters don't (if a non-serializable type parameter is used as a field,
                // it just isn't serialised).
                // https://blogs.unity3d.com/2020/03/17/unity-2020-1-beta-is-now-available-for-feedback/
                var unityVersion = myUnityVersion.GetActualVersion(project);
                if (unityVersion < new Version(2020, 1) && type is ITypeParametersOwner typeParametersOwner &&
                    typeParametersOwner.TypeParameters.Count > 0)
                {
                    return(false);
                }
            }

            if (type is IClass @class && @class.IsStaticClass())
            {
                return(false);
            }

            // System.Version seems to be special cased. In Mono, it's marked as [Serializable], but in netstandard,
            // it's not. Which means that depending on what runtime you're using, you could potentially get different
            // fields serialised. However, it never shows up in Inspector, so it's a good indication that it's handled
            // specially.
            if (Equals(type.GetClrName(), KnownTypes.SystemVersion))
            {
                return(false);
            }

            return(type.HasAttributeInstance(PredefinedType.SERIALIZABLE_ATTRIBUTE_CLASS, true));
        }
Exemple #4
0
        private static bool IsTestFixture(ITypeElement typeElement)
        {
            if (!(typeElement is IClass) && !(typeElement is IStruct))
            {
                return(false);
            }

            if (typeElement.AllTypeParameters.Any())
            {
                return(false); // type should be concrete
            }
            var modifiersOwner = (IModifiersOwner)typeElement;

            if (modifiersOwner.IsAbstract || modifiersOwner.GetAccessRights() == AccessRights.INTERNAL)
            {
                return(false);
            }

            if (typeElement.HasAttributeInstance(TestFixtureAttribute, false))
            {
                return(true);
            }

            var @class = typeElement as IClass;

            if (@class != null)
            {
                var visited = new HashSet <IClass>();
                while ((@class = @class.GetSuperClass()) != null)
                {
                    if (visited.Contains(@class))
                    {
                        break;
                    }
                    visited.Add(@class);
                    if (@class.HasAttributeInstance(TestFixtureAttribute, false))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #5
0
        public bool IsSerializableType([CanBeNull] ITypeElement type)
        {
            // A class or struct with the `[System.Serializable]` attribute
            // Should not be abstract, static or generic
            // We'll ignore abstract or generic because it might be being used as a base class
            // TODO: Add a warning if the serializable class isn't inherited
            var clazz = type as IClass;

            if (clazz?.IsStaticClass() == true)
            {
                return(false);
            }

            if (type?.IsClassLike() == true)
            {
                return(type.HasAttributeInstance(PredefinedType.SERIALIZABLE_ATTRIBUTE_CLASS, true));
            }

            return(false);
        }
Exemple #6
0
 public static bool IsZoneClass(ITypeElement typeElement)
 {
     return(typeElement.HasAttributeInstance(new ClrTypeName(ZoneAttributeNameFull), false));
 }