private void Init(IMethodSymbol sym) { MethodSymbol = sym; Args.Clear(); ArgConversions.Clear(); ReturnArgs.Clear(); GenericTypeArgs.Clear(); ClassKey = ClassInfo.GetFullName(sym.ContainingType); GenericClassKey = ClassInfo.GetFullNameWithTypeParameters(sym.ContainingType); IsEnumClass = sym.ContainingType.TypeKind == TypeKind.Enum || ClassKey == SymbolTable.PrefixExternClassName("System.Enum"); IsExtensionMethod = sym.IsExtensionMethod && SymbolTable.Instance.IsCs2DslSymbol(sym); IsBasicValueMethod = SymbolTable.IsBasicValueMethod(sym); IsArrayStaticMethod = ClassKey == SymbolTable.PrefixExternClassName("System.Array") && sym.IsStatic; if ((ClassKey == SymbolTable.PrefixExternClassName("UnityEngine.GameObject") || ClassKey == SymbolTable.PrefixExternClassName("UnityEngine.Component")) && (sym.Name.StartsWith("GetComponent") || sym.Name.StartsWith("AddComponent"))) { IsComponentGetOrAdd = true; } if (sym.IsGenericMethod) { foreach (var arg in sym.TypeArguments) { GenericTypeArgs.Add(arg); } } }
internal void Init(INamedTypeSymbol sym, ClassSymbolInfo info) { IsEnum = sym.TypeKind == TypeKind.Enum; IsEntryClass = HasAttribute(sym, "Cs2Dsl.EntryAttribute"); IsValueType = sym.IsValueType; IsInnerOfGenericType = IsInnerClassOfGenericType(sym); ExistConstructor = false; ExistStaticConstructor = false; SemanticInfo = sym; ClassSemanticInfo = info; Key = GetFullName(sym); BaseKey = GetFullName(sym.BaseType); if (BaseKey == "System.Object" || BaseKey == "System.ValueType") { BaseKey = string.Empty; } GenericTypeKey = ClassInfo.GetFullNameWithTypeParameters(sym); References.Clear(); IgnoreReferences.Clear(); }
internal static string CalcMethodMangling(IMethodSymbol methodSym) { IAssemblySymbol assemblySym = SymbolTable.Instance.AssemblySymbol; if (null == methodSym) { return(string.Empty); } StringBuilder sb = new StringBuilder(); string name = GetMethodName(methodSym); if (!string.IsNullOrEmpty(name) && name[0] == '.') { name = name.Substring(1); } sb.Append(name); if (SymbolTable.Instance.IsCs2DslSymbol(methodSym)) { foreach (var param in methodSym.Parameters) { sb.Append("__"); if (param.RefKind == RefKind.Ref) { sb.Append("Ref_"); } else if (param.RefKind == RefKind.Out) { sb.Append("Out_"); } var oriparam = param.OriginalDefinition; if (oriparam.Type.Kind == SymbolKind.ArrayType) { sb.Append("Arr_"); var arrSym = oriparam.Type as IArrayTypeSymbol; string fn; if (arrSym.ElementType.TypeKind == TypeKind.TypeParameter) { fn = ClassInfo.GetFullNameWithTypeParameters(arrSym.ElementType); } else { fn = ClassInfo.GetFullName(arrSym.ElementType); } sb.Append(fn.Replace('.', '_')); } else if (oriparam.Type.TypeKind == TypeKind.TypeParameter) { string fn = ClassInfo.GetFullNameWithTypeParameters(oriparam.Type); sb.Append(fn.Replace('.', '_')); } else { string fn = ClassInfo.GetFullName(oriparam.Type); sb.Append(fn.Replace('.', '_')); } } } return(sb.ToString()); }
internal string NameMangling(IMethodSymbol sym) { string ret = GetMethodName(sym); if (!string.IsNullOrEmpty(ret) && ret[0] == '.') { ret = ret.Substring(1); } string key = ClassInfo.GetFullNameWithTypeParameters(sym.ContainingType); ClassSymbolInfo csi; if (m_ClassSymbols.TryGetValue(key, out csi)) { bool isMangling; csi.SymbolOverloadFlags.TryGetValue(ret, out isMangling); if (isMangling) { ret = CalcMethodMangling(sym); } } return(ret); }
private void Init(IMethodSymbol sym) { MethodSymbol = sym; CheckInvocation(sym); Args.Clear(); ArgConversions.Clear(); ReturnArgs.Clear(); GenericTypeArgs.Clear(); ClassKey = ClassInfo.GetFullName(sym.ContainingType); GenericClassKey = ClassInfo.GetFullNameWithTypeParameters(sym.ContainingType); IsEnumClass = sym.ContainingType.TypeKind == TypeKind.Enum || ClassKey == SymbolTable.PrefixExternClassName("System.Enum"); IsExtensionMethod = sym.IsExtensionMethod && SymbolTable.Instance.IsCs2DslSymbol(sym); IsBasicValueMethod = SymbolTable.IsBasicValueMethod(sym); IsArrayStaticMethod = ClassKey == SymbolTable.PrefixExternClassName("System.Array") && sym.IsStatic; IsExternMethod = !SymbolTable.Instance.IsCs2DslSymbol(sym); if ((ClassKey == SymbolTable.PrefixExternClassName("UnityEngine.GameObject") || ClassKey == SymbolTable.PrefixExternClassName("UnityEngine.Component")) && (sym.Name.StartsWith("GetComponent") || sym.Name.StartsWith("AddComponent"))) { IsComponentGetOrAdd = true; } NonGenericMethodSymbol = null; PostPositionGenericTypeArgs = false; if (sym.IsGenericMethod) { bool existNonGenericVersion = true; var ctype = sym.ContainingType; var syms = ctype.GetMembers(sym.Name); if (null != syms) { foreach (var isym in syms) { var msym = isym as IMethodSymbol; if (null != msym && !msym.IsGenericMethod && msym.Parameters.Length == sym.Parameters.Length + sym.TypeParameters.Length) { existNonGenericVersion = true; for (int i = 0; i < sym.TypeParameters.Length; ++i) { var psym = msym.Parameters[i]; if (psym.Type.Name != "Type") { existNonGenericVersion = false; break; } } for (int i = 0; i < sym.Parameters.Length; ++i) { var psym1 = msym.Parameters[i + sym.TypeParameters.Length]; var psym2 = sym.Parameters[i]; if (psym1.Type.Name != psym2.Type.Name) { existNonGenericVersion = false; break; } } if (existNonGenericVersion) { NonGenericMethodSymbol = msym; PostPositionGenericTypeArgs = false; } else { existNonGenericVersion = true; for (int i = 0; i < sym.Parameters.Length; ++i) { var psym1 = msym.Parameters[i]; var psym2 = sym.Parameters[i]; if (psym1.Type.Name != psym2.Type.Name) { existNonGenericVersion = false; break; } } for (int i = 0; i < sym.TypeParameters.Length; ++i) { var psym = msym.Parameters[i + sym.Parameters.Length]; if (psym.Type.Name != "Type") { existNonGenericVersion = false; break; } } if (existNonGenericVersion) { NonGenericMethodSymbol = msym; PostPositionGenericTypeArgs = true; } } if (existNonGenericVersion) { break; } } } } if (existNonGenericVersion) { foreach (var arg in sym.TypeArguments) { GenericTypeArgs.Add(arg); } } } ExternOverloadedMethodSignature = string.Empty; if (IsExternMethod) { var syms = sym.ContainingType.GetMembers(sym.Name); if (null != syms) { int mcount = 0; foreach (var isym in syms) { var msym = isym as IMethodSymbol; var fn = ClassInfo.GetFullName(msym.ContainingType); if (null != msym && msym.DeclaredAccessibility == Accessibility.Public && !msym.IsImplicitlyDeclared) { ++mcount; } } if (mcount > 1) { ExternOverloadedMethodSignature = SymbolTable.CalcOverloadedMethodSignature(sym, NonGenericMethodSymbol); } } } }
private void VisitTypeDeclarationSyntax(TypeDeclarationSyntax node) { INamedTypeSymbol declSym = m_Model.GetDeclaredSymbol(node); SymbolTable.Instance.AddGenericTypeDefine(ClassInfo.GetFullNameWithTypeParameters(declSym), node); }
internal void Init(IMethodSymbol sym, SemanticModel model) { MethodSymbol = sym; Model = model; Args.Clear(); DslToObjectArgs.Clear(); ArgConversions.Clear(); DefaultValueArgs.Clear(); DslToObjectDefArgs.Clear(); ReturnArgs.Clear(); ReturnValueArgFlags.Clear(); ReturnArgOperations.Clear(); ReturnArgSymbols.Clear(); GenericTypeArgs.Clear(); ClassKey = ClassInfo.GetFullName(sym.ContainingType); GenericClassKey = ClassInfo.GetFullNameWithTypeParameters(sym.ContainingType); IsEnumClass = sym.ContainingType.TypeKind == TypeKind.Enum || ClassKey == "System.Enum"; IsExtensionMethod = sym.IsExtensionMethod; IsBasicValueMethod = SymbolTable.IsBasicValueMethod(sym); IsArrayStaticMethod = ClassKey == "System.Array" && sym.IsStatic; IsExternMethod = !SymbolTable.Instance.IsCs2DslSymbol(sym); if ((ClassKey == "UnityEngine.GameObject" || ClassKey == "UnityEngine.Component") && (sym.Name.StartsWith("GetComponent") || sym.Name.StartsWith("AddComponent"))) { IsComponentGetOrAdd = true; } NonGenericMethodSymbol = null; PostPositionGenericTypeArgs = false; ExternOverloadedMethodSignature = string.Empty; if (IsExternMethod) { var syms = sym.ContainingType.GetMembers(sym.Name); if (sym.IsGenericMethod) { bool existNonGenericVersion = false; if (null != syms) { //寻找匹配的非泛型版本 foreach (var isym in syms) { var msym = isym as IMethodSymbol; if (null != msym && !msym.IsGenericMethod && msym.Parameters.Length == sym.Parameters.Length + sym.TypeParameters.Length) { existNonGenericVersion = true; for (int i = 0; i < sym.TypeParameters.Length; ++i) { var psym = msym.Parameters[i]; if (psym.Type.Name != "Type") { existNonGenericVersion = false; break; } } for (int i = 0; i < sym.Parameters.Length; ++i) { var psym1 = msym.Parameters[i + sym.TypeParameters.Length]; var psym2 = sym.Parameters[i]; if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter) { existNonGenericVersion = false; break; } } if (existNonGenericVersion) { NonGenericMethodSymbol = msym; PostPositionGenericTypeArgs = false; } else { existNonGenericVersion = true; for (int i = 0; i < sym.Parameters.Length; ++i) { var psym1 = msym.Parameters[i]; var psym2 = sym.Parameters[i]; if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter) { existNonGenericVersion = false; break; } } for (int i = 0; i < sym.TypeParameters.Length; ++i) { var psym = msym.Parameters[i + sym.Parameters.Length]; if (psym.Type.Name != "Type") { existNonGenericVersion = false; break; } } if (existNonGenericVersion) { NonGenericMethodSymbol = msym; PostPositionGenericTypeArgs = true; } } if (existNonGenericVersion) { break; } } } if (!existNonGenericVersion) { //寻找匹配的变参版本 foreach (var isym in syms) { var msym = isym as IMethodSymbol; if (null != msym && !msym.IsGenericMethod && msym.Parameters.Length > 0 && msym.Parameters.Length <= sym.Parameters.Length) { bool existParamsVersion = true; var lastPsym = msym.Parameters[msym.Parameters.Length - 1]; if (lastPsym.IsParams) { for (int i = 0; i < msym.Parameters.Length; ++i) { var psym1 = msym.Parameters[i]; var psym2 = sym.Parameters[i]; if (i < msym.Parameters.Length - 1 && psym1.Type.Name != psym2.Type.Name) { existParamsVersion = false; break; } } } if (existParamsVersion) { NonGenericMethodSymbol = msym; break; } } } } } if (existNonGenericVersion) { foreach (var arg in sym.TypeArguments) { GenericTypeArgs.Add(arg); } } else { //没有找到参数匹配的非泛型版本,则不传递泛型参数类型 //这样处理可以适应2类可能有效的情形: //1、如果有多个重载函数,其中有一个object类型变参,则其他泛型参数版本会适配到这个非泛型变参版本 //2、有一些方法不需要明确传递泛型参数类型(比如普通实参可推导出泛型参数类型并且泛型参数类型在函数中不明确使用) } } if (null != syms) { int mcount = 0; if (sym.MethodKind == MethodKind.Constructor && sym.ContainingType.IsValueType) { //值类型构造总是按重载处理,默认构造总是会生成 mcount = 2; } else { foreach (var isym in syms) { var msym = isym as IMethodSymbol; if (msym.Parameters.Length == 0) { if (msym.Name == "GetType") { continue; } if (msym.Name == "GetHashCode") { continue; } } var fn = ClassInfo.GetFullName(msym.ContainingType); if (null != msym && msym.IsStatic == sym.IsStatic && msym.DeclaredAccessibility == Accessibility.Public && !msym.IsImplicitlyDeclared && !msym.IsGenericMethod && !ClassInfo.HasAttribute(msym, "System.ObsoleteAttribute")) { bool existPointer = false; foreach (var partype in msym.Parameters) { if (partype.Type.TypeKind == TypeKind.Pointer) { existPointer = true; break; } } if (!existPointer) { ++mcount; } } } } if (mcount > 1) { ExternOverloadedMethodSignature = SymbolTable.CalcExternOverloadedMethodSignature(sym, NonGenericMethodSymbol); } } SymbolTable.Instance.TryAddExternReference(sym); if (!sym.ReturnsVoid) { SymbolTable.Instance.TryAddExternReference(sym.ReturnType); } foreach (var p in sym.Parameters) { if (p.Kind != SymbolKind.TypeParameter) { SymbolTable.Instance.TryAddExternReference(p.Type); } } } else if (sym.IsGenericMethod) { foreach (var arg in sym.TypeArguments) { GenericTypeArgs.Add(arg); } } if (sym.IsGenericMethod) { foreach (var t in sym.TypeArguments) { if (t.TypeKind != TypeKind.TypeParameter) { SymbolTable.Instance.TryAddExternReference(t); } } } }