public void Process(TypeDef type, SystemTypeAttribute attribute) { type.Attributes |= TypeAttributes.System; if (attribute.TypeId != TypeInfo.NoTypeId) { type.StaticTypeId = attribute.TypeId; } }
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()); }
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); }
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; } }
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); } }
/// <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; } }
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); } }