-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
329 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace FUI | ||
{ | ||
public class BindingAttribute : Attribute { } | ||
|
||
public class CommandAttribute : Attribute { } | ||
|
||
public interface IValueConverter { } | ||
|
||
public interface IValueConverter<T1, T2> { } | ||
|
||
public interface ISynchronizeProperties | ||
{ | ||
void Synchronize(); | ||
} | ||
|
||
public interface IElement { } | ||
} | ||
|
||
namespace FUI.BindingDescriptor | ||
{ | ||
public class ContextDescriptor { } | ||
|
||
public class ContextDescriptor<TViewModel> : ContextDescriptor where TViewModel : FUI.Bindable.ObservableObject { } | ||
|
||
public class CommandBindingDescriptor { } | ||
|
||
public class PropertyBindingDescriptor { } | ||
} | ||
|
||
namespace FUI.Bindable | ||
{ | ||
public class ObservableObject { } | ||
public class BindableProperty<T> { } | ||
public interface IBindableProperty<T> { } | ||
public interface INotifyPropertyChanged { } | ||
public interface INotifyCollectionChanged { } | ||
public interface IReadOnlyObservableList<out T> : IReadOnlyList<T>, INotifyCollectionChanged { } | ||
public class CommandTemplate<T> { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace FUIAnalyzer | ||
{ | ||
internal static class FUITypeSymbolExtensions | ||
{ | ||
/// <summary> | ||
/// 判断一个类型是否是可观察对象 | ||
/// </summary> | ||
public static bool IsObservableObject(this ITypeSymbol type) | ||
{ | ||
return type.Extends(typeof(FUI.Bindable.INotifyPropertyChanged)); | ||
} | ||
|
||
/// <summary> | ||
/// 判断一个类型是否是可观察列表 | ||
/// </summary> | ||
public static bool IsObservableList(this ITypeSymbol type) | ||
{ | ||
return type.Extends(typeof(FUI.Bindable.INotifyCollectionChanged)); | ||
} | ||
|
||
/// <summary> | ||
/// 判断一个类型是否是可观察列表 并获取元素类型 | ||
/// </summary> | ||
/// <param name="type">源类型</param> | ||
/// <param name="elementType">列表元素类型</param> | ||
/// <returns></returns> | ||
public static bool IsObservableList(this ITypeSymbol type, out ITypeSymbol elementType) | ||
{ | ||
elementType = null; | ||
if (!type.IsObservableList()) | ||
{ | ||
return false; | ||
} | ||
|
||
var listType = typeof(FUI.Bindable.IReadOnlyObservableList<>).GetGenericTypeDefinition(); | ||
foreach (var interfaceType in type.AllInterfaces) | ||
{ | ||
if (interfaceType.IsGenericType && interfaceType.ConstructedFrom.Matches(listType)) | ||
{ | ||
elementType = interfaceType.TypeArguments[0]; | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// 判断一个类型是否是可观察属性 | ||
/// </summary> | ||
public static bool IsBindableProperty(this ITypeSymbol type, out ITypeSymbol propertyValueType) | ||
{ | ||
propertyValueType = null; | ||
var bindablePropertyType = typeof(FUI.Bindable.IBindableProperty<>).GetGenericTypeDefinition(); | ||
foreach (var interfaceType in type.AllInterfaces) | ||
{ | ||
if (interfaceType.IsGenericType && interfaceType.ConstructedFrom.Matches(bindablePropertyType)) | ||
{ | ||
propertyValueType = interfaceType.TypeArguments[0]; | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// 判断一个类型是否是命令 | ||
/// </summary> | ||
public static bool IsCommand(this ITypeSymbol type, out IReadOnlyList<ITypeSymbol> arguments) | ||
{ | ||
var commandType = typeof(FUI.Bindable.CommandTemplate<>).GetGenericTypeDefinition(); | ||
arguments = null; | ||
foreach (var t in type.GetBaseTypesAndThis()) | ||
{ | ||
if (!(t is INamedTypeSymbol named)) | ||
{ | ||
continue; | ||
} | ||
|
||
if (named.IsGenericType && named.ConstructedFrom.Matches(commandType)) | ||
{ | ||
var args = named.TypeArguments; | ||
if (args.Length != 1) | ||
{ | ||
return false; | ||
} | ||
|
||
var actionType = args[0] as INamedTypeSymbol; | ||
if (actionType == null) | ||
{ | ||
return false; | ||
} | ||
|
||
arguments = actionType.TypeArguments; | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// 判断一个类型是否是值转换器 | ||
/// </summary> | ||
/// <param name="type">类型</param> | ||
/// <param name="valueType">值转换器 值类型</param> | ||
/// <param name="targetType">值转换器 目标类型</param> | ||
/// <returns></returns> | ||
public static bool IsValueConverter(this ITypeSymbol type, out ITypeSymbol valueType, out ITypeSymbol targetType) | ||
{ | ||
valueType = null; | ||
targetType = null; | ||
|
||
var valueConverterType = typeof(FUI.IValueConverter<,>).GetGenericTypeDefinition(); | ||
|
||
foreach (var interfaceType in type.AllInterfaces) | ||
{ | ||
if (interfaceType.IsGenericType && interfaceType.ConstructedFrom.Matches(valueConverterType)) | ||
{ | ||
valueType = interfaceType.TypeArguments[0]; | ||
targetType = interfaceType.TypeArguments[1]; | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// 判断一个类型是否是绑定上下文描述器 | ||
/// </summary> | ||
/// <param name="type">目标类型</param> | ||
/// <param name="viewModelType">viewModel类型</param> | ||
public static bool IsContextDescriptor(this ITypeSymbol type, out ITypeSymbol viewModelType) | ||
{ | ||
viewModelType = null; | ||
var descriptorType = typeof(FUI.BindingDescriptor.ContextDescriptor<>).GetGenericTypeDefinition(); | ||
foreach (var t in type.GetBaseTypesAndThis()) | ||
{ | ||
if (!(t is INamedTypeSymbol named)) | ||
{ | ||
continue; | ||
} | ||
|
||
if (named.IsGenericType && named.ConstructedFrom.Matches(descriptorType)) | ||
{ | ||
viewModelType = named.TypeArguments[0]; | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} | ||
} |
Oops, something went wrong.