示例#1
0
 public void Process(TypeDef type, SystemTypeAttribute attribute)
 {
     type.Attributes |= TypeAttributes.System;
     if (attribute.TypeId != TypeInfo.NoTypeId)
     {
         type.StaticTypeId = attribute.TypeId;
     }
 }
示例#2
0
 private static void FilterTypes(Assembly assembly, SystemTypeAttribute filter, ICollection <Type> excludedTypes, List <Type> output)
 {
     output.AddRange(from type in assembly.GetTypes()
                     let isValid = (type.IsValueType && !type.IsEnum) || type.IsClass
                                   where type.IsVisible && isValid
                                   where (FilterConstraintOverride == null || FilterConstraintOverride.Invoke(type)) &&
                                   (filter == null || filter.IsConstraintSatisfied(type))
                                   where excludedTypes == null || !excludedTypes.Contains(type)
                                   select type);
 }
        private static Type[] FindTypesByName(string typeName, SystemTypeAttribute filter)
        {
            List <Type> types = new List <Type>();

            foreach (Type t in GetFilteredTypes(filter))
            {
                if (t.Name.Equals(typeName))
                {
                    types.Add(t);
                }
            }
            return(types.ToArray());
        }
示例#4
0
        private static List <Type> GetFilteredTypes(SystemTypeAttribute filter)
        {
            var types         = new List <Type>();
            var assemblies    = CompilationPipeline.GetAssemblies();
            var excludedTypes = ExcludedTypeCollectionGetter?.Invoke();

            foreach (var assembly in assemblies)
            {
                Assembly compiledAssembly = Assembly.Load(assembly.name);
                FilterTypes(compiledAssembly, filter, excludedTypes, types);
            }

            types.Sort((a, b) => string.Compare(a.FullName, b.FullName, StringComparison.Ordinal));
            return(types);
        }
        private static Type[] FindTypesByName(string typeName, SystemTypeAttribute filter)
        {
            var types         = new List <Type>();
            var filteredTypes = GetFilteredTypes(filter);

            foreach (var type in filteredTypes)
            {
                if (type.Name.Equals(typeName))
                {
                    types.Add(type);
                }
            }

            return(types.ToArray());
        }
        private static Type[] FindTypesByName(string typeName, SystemTypeAttribute filter)
        {
            var types         = new List <Type>();
            var filteredTypes = GetFilteredTypes(filter);

            for (var i = 0; i < filteredTypes.Count; i++)
            {
                if (filteredTypes[i].Name.Equals(typeName))
                {
                    types.Add(filteredTypes[i]);
                }
            }

            return(types.ToArray());
        }
        private static List <Type> GetFilteredTypes(SystemTypeAttribute filter)
        {
            var types         = new List <Type>();
            var excludedTypes = ExcludedTypeCollectionGetter?.Invoke();

            // We prefer using this over CompilationPipeline.GetAssemblies() because
            // some types may come from plugins and other sources that have already
            // been compiled.
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();

            foreach (var assembly in assemblies)
            {
                FilterTypes(assembly, filter, excludedTypes, types);
            }

            types.Sort((a, b) => string.Compare(a.FullName, b.FullName, StringComparison.Ordinal));
            return(types);
        }
        private static void FilterTypes(Assembly assembly, SystemTypeAttribute filter, ICollection <Type> excludedTypes, List <Type> output)
        {
            foreach (var type in assembly.GetLoadableTypes())
            {
                bool isValid = type.IsValueType && !type.IsEnum || type.IsClass;
                if (!type.IsVisible || !isValid)
                {
                    continue;
                }

                if (filter != null && !filter.IsConstraintSatisfied(type))
                {
                    continue;
                }

                if (excludedTypes != null && excludedTypes.Contains(type))
                {
                    continue;
                }

                output.Add(type);
            }
        }
        private static void DrawTypeSelectionControl(Rect position, SerializedProperty property, GUIContent label, SystemTypeAttribute filter)
        {
            try
            {
                Color restoreColor          = GUI.color;
                bool  restoreShowMixedValue = EditorGUI.showMixedValue;
                bool  typeResolved          = string.IsNullOrEmpty(property.stringValue) || ResolveType(property.stringValue) != null;
                EditorGUI.showMixedValue = property.hasMultipleDifferentValues;

                GUI.color = enabledColor;

                if (typeResolved)
                {
                    property.stringValue = DrawTypeSelectionControl(position, label, property.stringValue, filter, true);
                }
                else
                {
                    if (SelectRepairedTypeWindow.WindowOpen)
                    {
                        GUI.color = disabledColor;
                        DrawTypeSelectionControl(position, label, property.stringValue, filter, false);
                    }
                    else
                    {
                        Rect dropdownPosition = new Rect(position.x, position.y, position.width - 90, position.height);
                        Rect buttonPosition   = new Rect(position.x + position.width - 75, position.y, 75, position.height);

                        Color defaultColor = GUI.color;
                        GUI.color            = errorColor;
                        property.stringValue = DrawTypeSelectionControl(dropdownPosition, label, property.stringValue, filter, false);
                        GUI.color            = defaultColor;

                        if (GUI.Button(buttonPosition, "Try Repair", EditorStyles.miniButton))
                        {
                            string typeNameWithoutAssembly  = property.stringValue.Split(new string[] { "," }, StringSplitOptions.None)[0];
                            string typeNameWithoutNamespace = System.Text.RegularExpressions.Regex.Replace(typeNameWithoutAssembly, @"[.\w]+\.(\w+)", "$1");

                            Type[] repairedTypeOptions = FindTypesByName(typeNameWithoutNamespace, filter);
                            if (repairedTypeOptions.Length > 1)
                            {
                                SelectRepairedTypeWindow.Display(repairedTypeOptions, property);
                            }
                            else if (repairedTypeOptions.Length > 0)
                            {
                                property.stringValue = SystemType.GetReference(repairedTypeOptions[0]);
                            }
                            else
                            {
                                EditorUtility.DisplayDialog("No types found", "No types with the name '" + typeNameWithoutNamespace + "' were found.", "OK");
                            }
                        }
                    }
                }

                GUI.color = restoreColor;
                EditorGUI.showMixedValue = restoreShowMixedValue;
            }
            finally
            {
                ExcludedTypeCollectionGetter = null;
            }
        }
        private static string DrawTypeSelectionControl(Rect position, GUIContent label, string classRef, SystemTypeAttribute filter, bool typeResolved)
        {
            if (label != null && label != GUIContent.none)
            {
                position = EditorGUI.PrefixLabel(position, label);
            }

            int controlId = GUIUtility.GetControlID(ControlHint, FocusType.Keyboard, position);

            bool triggerDropDown = false;

            switch (Event.current.GetTypeForControl(controlId))
            {
            case EventType.ExecuteCommand:
                if (Event.current.commandName == "TypeReferenceUpdated")
                {
                    if (selectionControlId == controlId)
                    {
                        if (classRef != selectedReference)
                        {
                            classRef    = selectedReference;
                            GUI.changed = true;
                        }

                        selectionControlId = 0;
                        selectedReference  = null;
                    }
                }

                break;

            case EventType.MouseDown:
                if (GUI.enabled && position.Contains(Event.current.mousePosition))
                {
                    GUIUtility.keyboardControl = controlId;
                    triggerDropDown            = true;
                    Event.current.Use();
                }

                break;

            case EventType.KeyDown:
                if (GUI.enabled && GUIUtility.keyboardControl == controlId)
                {
                    if (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.Space)
                    {
                        triggerDropDown = true;
                        Event.current.Use();
                    }
                }

                break;

            case EventType.Repaint:
                // Remove assembly name and namespace from content of pop-up control.
                var classRefParts = classRef.Split(',');
                var className     = classRefParts[0].Trim();
                className        = className.Substring(className.LastIndexOf(".", StringComparison.Ordinal) + 1);
                TempContent.text = className;

                if (TempContent.text == string.Empty)
                {
                    TempContent.text = "(None)";
                }
                else if (!typeResolved)
                {
                    TempContent.text += " {Missing}";
                }

                EditorStyles.popup.Draw(position, TempContent, controlId);
                break;
            }

            if (triggerDropDown)
            {
                selectionControlId = controlId;
                selectedReference  = classRef;

                DisplayDropDown(position, GetFilteredTypes(filter), ResolveType(classRef), filter?.Grouping ?? TypeGrouping.ByNamespaceFlat);
            }

            return(classRef);
        }
示例#11
0
 private static void DrawTypeSelectionControl(Rect position, SerializedProperty property, GUIContent label, SystemTypeAttribute filter)
 {
     try
     {
         bool restoreShowMixedValue = EditorGUI.showMixedValue;
         EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
         property.stringValue     = DrawTypeSelectionControl(position, label, property.stringValue, filter);
         EditorGUI.showMixedValue = restoreShowMixedValue;
     }
     finally
     {
         ExcludedTypeCollectionGetter = null;
     }
 }
        /// <summary>
        /// Draws the selection control for the type.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="property"></param>
        /// <param name="label"></param>
        /// <param name="filter"></param>
        /// <returns>True, if the class reference was resolved successfully.</returns>
        private static bool DrawTypeSelectionControl(Rect position, SerializedProperty property, GUIContent label, SystemTypeAttribute filter)
        {
            bool isValidClassRef;

            try
            {
                bool restoreShowMixedValue = EditorGUI.showMixedValue;
                EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
                var propertyValue = property.stringValue;
                isValidClassRef          = DrawTypeSelectionControl(position, label, ref propertyValue, filter);
                property.stringValue     = propertyValue;
                EditorGUI.showMixedValue = restoreShowMixedValue;
            }
            finally
            {
                ExcludedTypeCollectionGetter = null;
            }

            return(isValidClassRef);
        }
        /// <summary>
        /// Draws the selection control for the type.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="systemTypeProperty"></param>
        /// <param name="label"></param>
        /// <param name="filter"></param>
        /// <returns>True, if the class reference was resolved successfully.</returns>
        private static void DrawTypeSelectionControl(Rect position, SerializedProperty systemTypeProperty, GUIContent label, SystemTypeAttribute filter)
        {
            try
            {
                var referenceProperty = systemTypeProperty.FindPropertyRelative("reference");
                EditorGUI.showMixedValue = referenceProperty.hasMultipleDifferentValues;
                var restoreShowMixedValue = EditorGUI.showMixedValue;

                if (TypeExtensions.TryResolveType(referenceProperty.stringValue, out var resolvedType))
                {
                    if (resolvedType.GUID != Guid.Empty)
                    {
                        referenceProperty.stringValue = resolvedType.GUID.ToString();
                    }
                    else
                    {
                        var qualifiedNameComponents = resolvedType.AssemblyQualifiedName?.Split(',');
                        Debug.Assert(qualifiedNameComponents?.Length >= 2);
                        referenceProperty.stringValue = $"{qualifiedNameComponents[0]}, {qualifiedNameComponents[1].Trim()}";
                    }
                }

                DrawTypeSelectionControl(position, label, referenceProperty, resolvedType, filter);
                EditorGUI.showMixedValue = restoreShowMixedValue;
            }
            finally
            {
                GroupingOverride             = null;
                FilterConstraintOverride     = null;
                ExcludedTypeCollectionGetter = null;
            }
        }
示例#14
0
        private static bool TypeSearch(SerializedProperty property, ref string typeName, SystemTypeAttribute filter, bool showPickerWindow)
        {
            if (typeName.Contains(Missing))
            {
                return(false);
            }

            var typeNameWithoutAssembly  = typeName.Split(new[] { "," }, StringSplitOptions.None)[0];
            var typeNameWithoutNamespace = System.Text.RegularExpressions.Regex.Replace(typeNameWithoutAssembly, @"[.\w]+\.(\w+)", "$1");
            var repairedTypeOptions      = FindTypesByName(typeNameWithoutNamespace, filter);

            switch (repairedTypeOptions.Length)
            {
            case 0:
                if (showPickerWindow)
                {
                    EditorApplication.delayCall += () =>
                                                   EditorUtility.DisplayDialog(
                        "No types found",
                        $"No types with the name '{typeNameWithoutNamespace}' were found.",
                        "OK");
                }

                return(false);

            case 1:
                typeName = SystemType.GetReference(repairedTypeOptions[0]);
                return(true);

            default:
                if (showPickerWindow)
                {
                    EditorApplication.delayCall += () =>
                                                   SystemTypeRepairWindow.Display(repairedTypeOptions, property);
                }

                return(false);
            }
        }
示例#15
0
        /// <summary>
        /// Draws the selection control for the type.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="systemTypeProperty"></param>
        /// <param name="label"></param>
        /// <param name="filter"></param>
        /// <returns>True, if the class reference was resolved successfully.</returns>
        private static void DrawTypeSelectionControl(Rect position, SerializedProperty systemTypeProperty, GUIContent label, SystemTypeAttribute filter)
        {
            try
            {
                var referenceProperty = systemTypeProperty.FindPropertyRelative("reference");

                EditorGUI.showMixedValue = referenceProperty.hasMultipleDifferentValues;

                var restoreColor          = GUI.color;
                var reference             = referenceProperty.stringValue;
                var restoreShowMixedValue = EditorGUI.showMixedValue;
                var isValidClassRef       = string.IsNullOrEmpty(reference) || TypeExtensions.ResolveType(reference) != null;

                if (!isValidClassRef)
                {
                    isValidClassRef = TypeSearch(referenceProperty, ref reference, filter, false);

                    if (isValidClassRef)
                    {
                        Debug.LogWarning($"Fixed missing class reference for property '{label.text}' on {systemTypeProperty.serializedObject.targetObject.name}");
                    }
                    else
                    {
                        if (!reference.Contains(Missing))
                        {
                            reference += Missing;
                        }
                    }
                }

                if (isValidClassRef)
                {
                    GUI.color = EnabledColor;
                    DrawTypeSelectionControl(position, label, ref reference, filter);
                }
                else
                {
                    if (SystemTypeRepairWindow.WindowOpen)
                    {
                        GUI.color = DisabledColor;
                        DrawTypeSelectionControl(position, label, ref reference, filter);
                    }
                    else
                    {
                        const float leftPadding  = 8f;
                        const float iconSize     = 24f;
                        const float buttonWidth  = 40f;
                        var         errorContent = EditorGUIUtility.IconContent("d_console.erroricon.sml");
                        GUI.Label(new Rect(EditorGUIUtility.currentViewWidth - iconSize - leftPadding, position.y, iconSize, iconSize), errorContent);

                        var dropdownPosition = new Rect(position.x, position.y, position.width - buttonWidth - 28f, position.height);
                        var buttonPosition   = new Rect(EditorGUIUtility.currentViewWidth - buttonWidth - leftPadding - iconSize, position.y, buttonWidth, position.height);

                        DrawTypeSelectionControl(dropdownPosition, label, ref reference, filter);

                        if (GUI.Button(buttonPosition, RepairContent, EditorStyles.miniButton))
                        {
                            TypeSearch(referenceProperty, ref reference, filter, true);
                        }
                    }
                }

                GUI.color = restoreColor;
                referenceProperty.stringValue = reference;
                referenceProperty.serializedObject.ApplyModifiedProperties();
                EditorGUI.showMixedValue = restoreShowMixedValue;
            }
            finally
            {
                FilterConstraintOverride     = null;
                ExcludedTypeCollectionGetter = null;
            }
        }
        /// <summary>
        /// Draws the selection control for the type.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="property"></param>
        /// <param name="label"></param>
        /// <param name="filter"></param>
        /// <returns>True, if the class reference was resolved successfully.</returns>
        private static void DrawTypeSelectionControl(Rect position, SerializedProperty property, GUIContent label, SystemTypeAttribute filter)
        {
            try
            {
                var referenceProperty = property.FindPropertyRelative("reference");

                EditorGUI.showMixedValue = referenceProperty.hasMultipleDifferentValues;

                var restoreColor          = GUI.color;
                var reference             = referenceProperty.stringValue;
                var restoreShowMixedValue = EditorGUI.showMixedValue;
                var isValidClassRef       = string.IsNullOrEmpty(reference) || ResolveType(reference) != null;

                if (!isValidClassRef)
                {
                    isValidClassRef = TypeSearch(referenceProperty, ref reference, filter, false);

                    if (isValidClassRef)
                    {
                        Debug.LogWarning($"Fixed missing class reference for property '{label.text}' on {property.serializedObject.targetObject.name}");
                    }
                    else
                    {
                        if (!reference.Contains(" {missing}"))
                        {
                            reference += " {missing}";
                        }
                    }
                }

                if (isValidClassRef)
                {
                    GUI.color = EnabledColor;
                    DrawTypeSelectionControl(position, label, ref reference, filter);
                }
                else
                {
                    if (SystemTypeRepairWindow.WindowOpen)
                    {
                        GUI.color = DisabledColor;
                        DrawTypeSelectionControl(position, label, ref reference, filter);
                    }
                    else
                    {
                        var errorContent = EditorGUIUtility.IconContent("d_console.erroricon.sml");
                        GUI.Label(new Rect(position.width, position.y, position.width, position.height), errorContent);

                        var dropdownPosition = new Rect(position.x, position.y, position.width - 90, position.height);
                        var buttonPosition   = new Rect(position.width - 75, position.y, 75, position.height);

                        DrawTypeSelectionControl(dropdownPosition, label, ref reference, filter);

                        if (GUI.Button(buttonPosition, "Try Repair", EditorStyles.miniButton))
                        {
                            TypeSearch(referenceProperty, ref reference, filter, true);
                        }
                    }
                }

                GUI.color = restoreColor;
                referenceProperty.stringValue = reference;
                referenceProperty.serializedObject.ApplyModifiedProperties();
                EditorGUI.showMixedValue = restoreShowMixedValue;
            }
            finally
            {
                ExcludedTypeCollectionGetter = null;
            }
        }
示例#17
0
 private static Type[] FindTypesByName(string typeName, SystemTypeAttribute filter)
 {
     return(GetFilteredTypes(filter).Where(type => type.Name.Equals(typeName)).ToArray());
 }
        /// <summary>
        /// Draws the selection control for the type.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="label"></param>
        /// <param name="referenceProperty"></param>
        /// <param name="selectedType"></param>
        /// <param name="filter"></param>
        /// <returns>True, if the class reference was successfully resolved.</returns>
        private static void DrawTypeSelectionControl(Rect position, GUIContent label, SerializedProperty referenceProperty, Type selectedType, SystemTypeAttribute filter)
        {
            if (label != null && label != GUIContent.none)
            {
                position = EditorGUI.PrefixLabel(position, label);
            }

            var triggerDropDown = false;
            var controlId       = GUIUtility.GetControlID(ControlHint, FocusType.Keyboard, position);

            switch (Event.current.GetTypeForControl(controlId))
            {
            case EventType.ExecuteCommand:
                if (Event.current.commandName == TypeReferenceUpdated &&
                    selectionControlId == controlId)
                {
                    if (selectedType != SelectedType)
                    {
                        selectedType = SelectedType;

                        if (selectedType == null)
                        {
                            referenceProperty.stringValue = string.Empty;
                        }
                        else
                        {
                            if (selectedType.GUID != Guid.Empty)
                            {
                                referenceProperty.stringValue = selectedType.GUID.ToString();
                            }
                            else
                            {
                                Debug.LogWarning($"{selectedType.Name} is missing {nameof(System.Runtime.InteropServices.GuidAttribute)}");
                                referenceProperty.stringValue = selectedType.AssemblyQualifiedName;
                            }
                        }

                        GUI.changed = true;
                    }

                    selectionControlId    = 0;
                    SelectedType          = null;
                    CreateNewTypeOverride = null;
                }

                break;

            case EventType.MouseDown:
                if (GUI.enabled && position.Contains(Event.current.mousePosition))
                {
                    GUIUtility.keyboardControl = controlId;
                    triggerDropDown            = true;
                    Event.current.Use();
                }
                else
                {
                    CreateNewTypeOverride = null;
                }

                break;

            case EventType.KeyDown:
                if (GUI.enabled && GUIUtility.keyboardControl == controlId)
                {
                    if (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.Space)
                    {
                        triggerDropDown = true;
                        Event.current.Use();
                    }

                    if (Event.current.keyCode == KeyCode.Escape)
                    {
                        CreateNewTypeOverride = null;
                    }
                }

                break;

            case EventType.Repaint:
                TempContent.text = selectedType == null ? NONE : selectedType.Name;

                if (TempContent.text == string.Empty)
                {
                    TempContent.text = NONE;
                }

                EditorStyles.popup.Draw(position, TempContent, controlId);
                break;
            }

            if (triggerDropDown)
            {
                selectionControlId = controlId;
                SelectedType       = selectedType;

                Type createInterfaceType = null;
                if (filter is ImplementsAttribute implementsAttribute)
                {
                    createInterfaceType = implementsAttribute.InterfaceType;
                }

                DisplayDropDown(position, GetFilteredTypes(filter), selectedType, GroupingOverride ?? filter?.Grouping ?? TypeGrouping.ByNamespaceFlat, CreateNewTypeOverride ?? createInterfaceType);
            }
        }