public static EditorScriptCompilationOptions GetAdditionalEditorScriptCompilationOptions(
            AssembliesType assembliesType)
        {
            var options = GetAdditionalEditorScriptCompilationOptions();

            if (EditorUserBuildSettings.development && (assembliesType == AssembliesType.Player || assembliesType == AssembliesType.PlayerWithoutTestAssemblies))
            {
                options |= EditorScriptCompilationOptions.BuildingDevelopmentBuild;
            }


            switch (assembliesType)
            {
            case AssembliesType.Editor:
                options |= EditorScriptCompilationOptions.BuildingIncludingTestAssemblies;
                options |= EditorScriptCompilationOptions.BuildingForEditor;
                break;

            case AssembliesType.Player:
                options |= EditorScriptCompilationOptions.BuildingIncludingTestAssemblies;
                options &= ~EditorScriptCompilationOptions.BuildingForEditor;
                break;

            case AssembliesType.PlayerWithoutTestAssemblies:
                options &= ~EditorScriptCompilationOptions.BuildingIncludingTestAssemblies;
                options &= ~EditorScriptCompilationOptions.BuildingForEditor;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(assembliesType));
            }

            return(options);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Collects all assemblies - transitively that are valid for the specified type `Player` or `Editor`
        /// </summary>
        /// <param name="assemblyTypes">The assembly type</param>
        /// <returns>The list of assemblies valid for this platform</returns>
        private static List <System.Reflection.Assembly> GetAssemblyList(AssembliesType assemblyTypes)
        {
            // TODO: Not sure there is a better way to match assemblies returned by CompilationPipeline.GetAssemblies
            // with runtime assemblies contained in the AppDomain.CurrentDomain.GetAssemblies()

            // Filter the assemblies
            var assemblyList = CompilationPipeline.GetAssemblies(assemblyTypes);

            var assemblyNames = new HashSet <string>();

            foreach (var assembly in assemblyList)
            {
                CollectAssemblyNames(assembly, assemblyNames);
            }

            var allAssemblies = new HashSet <System.Reflection.Assembly>();

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (!assemblyNames.Contains(assembly.GetName().Name))
                {
                    continue;
                }
                CollectAssembly(assembly, allAssemblies);
            }

            return(allAssemblies.ToList());
        }
Ejemplo n.º 3
0
 private void OnGUI()
 {
     using (var toolBarScope = new EditorGUILayout.HorizontalScope(EditorStyles.toolbar))
     {
         using (var changeCheckScope = new EditorGUI.ChangeCheckScope())
         {
             type = (AssembliesType)EditorGUILayout.EnumPopup(type, EditorStyles.toolbarPopup);
             if (changeCheckScope.changed)
             {
                 EditorPrefs.SetInt(EDITOR_PREFS_TYPE, (int)type);
                 UpdateAssembliesList();
             }
         }
         GUILayout.FlexibleSpace();
     }
     using (var scrollScope = new EditorGUILayout.ScrollViewScope(scrollPositionViewAssemblies))
     {
         scrollPositionViewAssemblies = scrollScope.scrollPosition;
         using (var verticalScope = new EditorGUILayout.VerticalScope())
         {
             foreach (var property in assemblyPropertyList)
             {
                 property.Render();
             }
         }
     }
 }
        private static Type GetType(AssembliesType assembliesType, string typeFullName)
        {
            var assemblies = CompilationPipeline.GetAssemblies(assembliesType);

            return(assemblies.Select(assembly => GenericAssembly.LoadFile(assembly.outputPath))
                   .Select(genericAssembly => genericAssembly.GetType(typeFullName))
                   .FirstOrDefault(type => type != null));
        }
        public static Assembly[] GetAssemblies(AssembliesType assembliesType)
        {
            var options = EditorCompilationInterface.GetAdditionalEditorScriptCompilationOptions();

            switch (assembliesType)
            {
            case AssembliesType.Editor:
                return(GetEditorAssemblies(EditorCompilationInterface.Instance, options, null));

            case AssembliesType.Player:
                return(GetPlayerAssemblies(EditorCompilationInterface.Instance, options, null));

            default:
                throw new ArgumentOutOfRangeException("assembliesType");
            }
        }
Ejemplo n.º 6
0
        internal static Assembly[] GetAssemblies(EditorCompilation editorCompilation, AssembliesType assembliesType)
        {
            var options = EditorCompilationInterface.GetAdditionalEditorScriptCompilationOptions();

            switch (assembliesType)
            {
            case AssembliesType.Editor:
                return(GetEditorAssemblies(editorCompilation, options | EditorScriptCompilationOptions.BuildingIncludingTestAssemblies, null));

            case AssembliesType.Player:
                return(GetPlayerAssemblies(editorCompilation, options | EditorScriptCompilationOptions.BuildingIncludingTestAssemblies, null));

            case AssembliesType.PlayerWithoutTestAssemblies:
                return(GetPlayerAssemblies(editorCompilation, options, null));

            default:
                throw new ArgumentOutOfRangeException("assembliesType");
            }
        }
Ejemplo n.º 7
0
 public static Assembly[] GetAssemblies(AssembliesType assembliesType)
 {
     return(GetAssemblies(EditorCompilationInterface.Instance, assembliesType));
 }
Ejemplo n.º 8
0
 private void OnEnable()
 {
     type = (AssembliesType)EditorPrefs.GetInt(EDITOR_PREFS_TYPE);
     UpdateAssembliesList();
 }
Ejemplo n.º 9
0
        public static List <BurstCompileTarget> FindExecuteMethods(AssembliesType assemblyTypes)
        {
            var methodsToCompile    = new List <BurstCompileTarget>();
            var methodsToCompileSet = new HashSet <MethodInfo>();

            var valueTypes          = new List <TypeToVisit>();
            var interfaceToProducer = new Dictionary <Type, Type>();

            var assemblyList = GetAssemblyList(assemblyTypes);
            //Debug.Log("Filtered Assembly List: " + string.Join(", ", assemblyList.Select(assembly => assembly.GetName().Name)));

            // Find all ways to execute job types (via producer attributes)
            var typesVisited = new HashSet <string>();
            var typesToVisit = new HashSet <string>();

            foreach (var assembly in assemblyList)
            {
                var types = new List <Type>();
                try
                {
                    types.AddRange(assembly.GetTypes());
                    // Collect all generic type instances (excluding indirect instances)
                    CollectGenericTypeInstances(assembly, types);
                }
                catch (Exception ex)
                {
                    Debug.LogWarning("Unexpected exception while collecting types in assembly `" + assembly.FullName + "` Exception: " + ex);
                }

                for (var i = 0; i < types.Count; i++)
                {
                    var t = types[i];
                    if (typesToVisit.Add(t.FullName))
                    {
                        // Because the list of types returned by CollectGenericTypeInstances does not detect nested generic classes that are not
                        // used explicitly, we need to create them if a declaring type is actually used
                        // so for example if we have:
                        // class MyClass<T> { class MyNestedClass { } }
                        // class MyDerived : MyClass<int> { }
                        // The CollectGenericTypeInstances will return typically the type MyClass<int>, but will not list MyClass<int>.MyNestedClass
                        // So the following code is correcting this in order to fully query the full graph of generic instance types, including indirect types
                        var nestedTypes = t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
                        foreach (var nestedType in nestedTypes)
                        {
                            if (t.IsGenericType && !t.IsGenericTypeDefinition)
                            {
                                var parentGenericTypeArguments = t.GetGenericArguments();
                                // Only create nested types that are closed generic types (full generic instance types)
                                // It happens if for example the parent class is `class MClass<T> { class MyNestedGeneric<T1> {} }`
                                // In that case, MyNestedGeneric<T1> is closed in the context of MClass<int>, so we don't process them
                                if (nestedType.GetGenericArguments().Length == parentGenericTypeArguments.Length)
                                {
                                    var instanceNestedType = nestedType.MakeGenericType(parentGenericTypeArguments);
                                    types.Add(instanceNestedType);
                                }
                            }
                            else
                            {
                                types.Add(nestedType);
                            }
                        }
                    }
                }

                foreach (var t in types)
                {
                    // If the type has been already visited, don't try to visit it
                    if (!typesVisited.Add(t.FullName) || (t.IsGenericTypeDefinition && !t.IsInterface))
                    {
                        continue;
                    }

                    try
                    {
                        // collect methods with types having a [BurstCompile] attribute
                        bool visitStaticMethods = HasBurstCompileAttribute(t);
                        bool isValueType        = false;

                        if (t.IsInterface)
                        {
                            object[] attrs = t.GetCustomAttributes(typeof(JobProducerTypeAttribute), false);
                            if (attrs.Length == 0)
                            {
                                continue;
                            }

                            JobProducerTypeAttribute attr = (JobProducerTypeAttribute)attrs[0];

                            interfaceToProducer.Add(t, attr.ProducerType);

                            //Debug.Log($"{t} has producer {attr.ProducerType}");
                        }
                        else if (t.IsValueType)
                        {
                            // NOTE: Make sure that we don't use a value type generic definition (e.g `class Outer<T> { struct Inner { } }`)
                            // We are only working on plain type or generic type instance!
                            if (!t.IsGenericTypeDefinition)
                            {
                                isValueType = true;
                            }
                        }

                        if (isValueType || visitStaticMethods)
                        {
                            valueTypes.Add(new TypeToVisit(t, visitStaticMethods));
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.LogWarning("Unexpected exception while inspecting type `" + t +
                                         "` IsConstructedGenericType: " + t.IsConstructedGenericType +
                                         " IsGenericTypeDef: " + t.IsGenericTypeDefinition +
                                         " IsGenericParam: " + t.IsGenericParameter +
                                         " Exception: " + ex);
                    }
                }
            }

            //Debug.Log($"Mapped {interfaceToProducer.Count} producers; {valueTypes.Count} value types");

            // Revisit all types to find things that are compilable using the above producers.
            foreach (var typePair in valueTypes)
            {
                var type = typePair.Type;

                // collect static [BurstCompile] methods
                if (typePair.CollectStaticMethods)
                {
                    try
                    {
                        var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        foreach (var method in methods)
                        {
                            if (HasBurstCompileAttribute(method))
                            {
                                var target = new BurstCompileTarget(method, type, null, true);
                                methodsToCompile.Add(target);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.LogException(ex);
                    }
                }

                // If the type is not a value type, we don't need to proceed with struct Jobs
                if (!type.IsValueType)
                {
                    continue;
                }

                // Otherwise try to find if we have an interface producer setup on the class
                foreach (var interfaceType in type.GetInterfaces())
                {
                    var genericLessInterface = interfaceType;
                    if (interfaceType.IsGenericType)
                    {
                        genericLessInterface = interfaceType.GetGenericTypeDefinition();
                    }

                    Type foundProducer;
                    if (interfaceToProducer.TryGetValue(genericLessInterface, out foundProducer))
                    {
                        var genericParams = new List <Type> {
                            type
                        };
                        if (interfaceType.IsGenericType)
                        {
                            genericParams.AddRange(interfaceType.GenericTypeArguments);
                        }

                        try
                        {
                            var executeType   = foundProducer.MakeGenericType(genericParams.ToArray());
                            var executeMethod = executeType.GetMethod("Execute");
                            if (executeMethod == null)
                            {
                                throw new InvalidOperationException($"Burst reflection error. The type `{executeType}` does not contain an `Execute` method");
                            }

                            // We will not try to record more than once a method in the methods to compile
                            // This can happen if a job interface is inheriting from another job interface which are using in the end the same
                            // job producer type
                            if (methodsToCompileSet.Add(executeMethod))
                            {
                                var target = new BurstCompileTarget(executeMethod, type, interfaceType, false);
                                methodsToCompile.Add(target);
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.LogException(ex);
                        }
                    }
                }
            }

            return(methodsToCompile);
        }
Ejemplo n.º 10
0
        private static UnityEditor.Compilation.Assembly FindUnityAssembly(string name, AssembliesType type)
        {
            UnityEditor.Compilation.Assembly   foundAssembly = null;
            UnityEditor.Compilation.Assembly[] assemblies    = CompilationPipeline.GetAssemblies(type);
            foreach (UnityEditor.Compilation.Assembly asm in assemblies)
            {
                if (asm.name == name)
                {
                    foundAssembly = asm;
                    break;
                }
            }

            return(foundAssembly);
        }
        internal static ScriptAssembly[] GetScriptAssemblies(IEditorCompilation editorCompilation, AssembliesType assembliesType, string[] extraScriptingDefines = null)
        {
            var options = EditorCompilationInterface.GetAdditionalEditorScriptCompilationOptions(assembliesType);

            return(GetScriptAssemblies(editorCompilation, options, extraScriptingDefines));
        }
 internal static Assembly[] GetAssemblies(EditorCompilation editorCompilation, AssembliesType assembliesType, string[] extraScriptingDefines = null)
 {
     return(ToAssemblies(GetScriptAssemblies(editorCompilation, assembliesType, extraScriptingDefines)));
 }