//专门用于SymbolTable::IsCs2DslSymbol与分析外部文件的类定义时使用的函数(防止递归调用与数据构建过程中查询数据) internal static string SpecialGetFullTypeName(ITypeSymbol type, bool isExtern) { if (null == type) { return(string.Empty); } if (type.ContainingAssembly == SymbolTable.Instance.AssemblySymbol) { if (isExtern) { return(SymbolTable.PrefixExternClassName(CalcFullName(type, true))); } else { return(CalcFullName(type, true)); } } else { return(SymbolTable.PrefixExternClassName(CalcFullNameWithTypeParameters(type, true))); } }
internal static T GetAttributeArgument <T>(ISymbol sym, string fullName, int index) { if (null == sym) { return(default(T)); } foreach (var attr in sym.GetAttributes()) { string fn = GetFullName(attr.AttributeClass); if (fn == fullName || fn == SymbolTable.PrefixExternClassName(fullName)) { var args = attr.ConstructorArguments; int ct = args.Length; if (index >= 0 && index < ct) { var arg = args[index]; return((T)Convert.ChangeType(arg.Value, typeof(T))); } } } return(default(T)); }
private void BuildInheritTypeTreeRecursively(INamedTypeSymbol typeSym) { string key = ClassInfo.GetFullName(typeSym); TypeTreeNode typeTreeNode; if (!m_TypeTreeNodes.TryGetValue(key, out typeTreeNode)) { typeTreeNode = new TypeTreeNode(); typeTreeNode.Type = typeSym; m_TypeTreeNodes.Add(key, typeTreeNode); } var baseType = typeSym.BaseType; if (null != baseType) { string baseClassKey = ClassInfo.GetFullName(baseType); if (baseClassKey == SymbolTable.PrefixExternClassName("System.Object") || baseClassKey == SymbolTable.PrefixExternClassName("System.ValueType")) { } else { TypeTreeNode baseTypeTreeNode; if (!m_TypeTreeNodes.TryGetValue(baseClassKey, out baseTypeTreeNode)) { baseTypeTreeNode = new TypeTreeNode(); baseTypeTreeNode.Type = baseType; m_TypeTreeNodes.Add(baseClassKey, baseTypeTreeNode); } typeTreeNode.BaseTypeNode = baseTypeTreeNode; baseTypeTreeNode.ChildTypeNodes.Add(typeTreeNode); } } foreach (var newSym in typeSym.GetTypeMembers()) { BuildInheritTypeTreeRecursively(newSym); } }
internal static T GetAttributeArgument <T>(ISymbol sym, string fullName, string argName) { if (null == sym) { return(default(T)); } foreach (var attr in sym.GetAttributes()) { string fn = GetFullName(attr.AttributeClass); if (fn == fullName || fn == SymbolTable.PrefixExternClassName(fullName)) { var args = attr.NamedArguments; foreach (var pair in args) { if (pair.Key == argName) { var arg = pair.Value; return((T)Convert.ChangeType(arg.Value, typeof(T))); } } } } return(default(T)); }
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 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 static bool IsBasicValueMethod(IMethodSymbol sym) { bool ret = false; if (null != sym && !sym.IsStatic && null != sym.ContainingType) { if (sym.ContainingType.TypeKind == TypeKind.Enum || ClassInfo.GetFullName(sym.ContainingType) == SymbolTable.PrefixExternClassName("System.Enum")) { ret = true; } else { string type = ClassInfo.GetFullName(sym.ContainingType); ret = IsBasicType(type, true); } } return(ret); }
internal void Init(INamedTypeSymbol typeSym, CSharpCompilation compilation, SymbolTable symTable) { if (typeSym.TypeKind == TypeKind.Error) { Logger.Instance.ReportIllegalType(typeSym); return; } IsInterface = typeSym.TypeKind == TypeKind.Interface; foreach (var intf in typeSym.AllInterfaces) { string key = ClassInfo.GetFullName(intf); ClassSymbolInfo isi; if (!symTable.ClassSymbols.TryGetValue(key, out isi)) { isi = new ClassSymbolInfo(); symTable.ClassSymbols.Add(key, isi); isi.Init(intf, compilation, symTable); } } ClassKey = ClassInfo.GetFullName(typeSym); BaseClassKey = ClassInfo.GetFullName(typeSym.BaseType); if (BaseClassKey == SymbolTable.PrefixExternClassName("System.Object") || BaseClassKey == SymbolTable.PrefixExternClassName("System.ValueType")) { BaseClassKey = string.Empty; } ExistConstructor = false; ExistStaticConstructor = false; if (typeSym.GetAttributes().Length > 0) { ExistAttributes = true; } Dictionary <string, int> memberCounts = new Dictionary <string, int>(); SymbolTable.Instance.CalcMemberCount(ClassKey, memberCounts); bool fieldUseExplicitTypeParams = false; bool staticUseExplicitTypeParams = false; TypeSymbol = typeSym; var members = typeSym.GetMembers(); foreach (var sym in members) { var fsym = sym as IFieldSymbol; if (null != fsym) { FieldSymbols.Add(fsym); if (fsym.GetAttributes().Length > 0) { ExistAttributes = true; } CheckFieldUseExplicitTypeParam(fsym, compilation, ref fieldUseExplicitTypeParams, ref staticUseExplicitTypeParams); } } foreach (var sym in members) { var msym = sym as IMethodSymbol; if (null != msym) { if (msym.MethodKind == MethodKind.Constructor && !msym.IsImplicitlyDeclared) { ExistConstructor = true; } else if (msym.MethodKind == MethodKind.StaticConstructor && !msym.IsImplicitlyDeclared) { ExistStaticConstructor = true; } MethodSymbols.Add(msym); if (msym.GetAttributes().Length > 0) { ExistAttributes = true; } string name = msym.Name; if (name[0] == '.') { name = name.Substring(1); } bool isOverloaded; int count; if (memberCounts.TryGetValue(name, out count)) { isOverloaded = count > 1; } else { isOverloaded = false; } if (!SymbolOverloadFlags.ContainsKey(name)) { SymbolOverloadFlags.Add(name, isOverloaded); } else { SymbolOverloadFlags[name] = isOverloaded; } continue; } var psym = sym as IPropertySymbol; if (null != psym && !psym.IsIndexer) { PropertySymbols.Add(psym); if (psym.GetAttributes().Length > 0) { ExistAttributes = true; } continue; } var esym = sym as IEventSymbol; if (null != esym) { EventSymbols.Add(esym); if (esym.GetAttributes().Length > 0) { ExistAttributes = true; } continue; } } BuildInterfaceInfo(typeSym, compilation, symTable); }
internal void Init(IMethodSymbol sym, SyntaxNode node) { ParamNames.Clear(); ReturnParamNames.Clear(); OutParamNames.Clear(); OriginalParamsName = string.Empty; ExistYield = false; ExistTopLevelReturn = false; ExistTryCatch = false; TryCatchLayer = 0; ReturnVarName = string.Empty; SemanticInfo = sym; SyntaxNode = node; if (sym.IsGenericMethod) { foreach (var param in sym.TypeParameters) { ParamNames.Add(param.Name); GenericMethodTypeParamNames.Add(param.Name); } } foreach (var param in sym.Parameters) { if (param.IsParams) { var arrTypeSym = param.Type as IArrayTypeSymbol; if (null != arrTypeSym && arrTypeSym.ElementType.TypeKind == TypeKind.Struct) { string ns = ClassInfo.GetNamespaces(arrTypeSym.ElementType); if (SymbolTable.Instance.IsCs2DslSymbol(arrTypeSym.ElementType)) { ParamsIsValueType = true; } else if (ns != "System") { ParamsIsExternValueType = true; } } ParamNames.Add("..."); OriginalParamsName = param.Name; //遇到变参直接结束(变参set_Item会出现后面带一个value参数的情形,在函数实现里处理) break; } else if (param.RefKind == RefKind.Ref) { //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则) ParamNames.Add(string.Format("ref({0})", param.Name)); ReturnParamNames.Add(param.Name); } else if (param.RefKind == RefKind.Out) { //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则) ParamNames.Add(string.Format("out({0})", param.Name)); ReturnParamNames.Add(param.Name); OutParamNames.Add(param.Name); } else { if (param.Type.TypeKind == TypeKind.Struct) { string ns = ClassInfo.GetNamespaces(param.Type); if (SymbolTable.Instance.IsCs2DslSymbol(param.Type)) { ValueParams.Add(ParamNames.Count); } else if (ns != "System") { ExternValueParams.Add(ParamNames.Count); } } ParamNames.Add(param.Name); } } if (!sym.ReturnsVoid) { var returnType = ClassInfo.GetFullName(sym.ReturnType); if (returnType.StartsWith(SymbolTable.PrefixExternClassName("System.Collections")) && (sym.ReturnType.Name == "IEnumerable" || sym.ReturnType.Name == "IEnumerator")) { var analysis = new YieldAnalysis(); analysis.Visit(node); ExistYield = analysis.YieldCount > 0; } } }
internal void Init(INamedTypeSymbol sym, ClassSymbolInfo info) { IsEnum = sym.TypeKind == TypeKind.Enum; IsEntryClass = HasAttribute(sym, "Cs2Lua.EntryAttribute"); IsValueType = sym.IsValueType; IsInnerOfGenericType = IsInnerClassOfGenericType(sym); ExistConstructor = false; ExistStaticConstructor = false; SemanticInfo = sym; ClassSemanticInfo = info; Key = GetFullName(sym); BaseKey = GetFullName(sym.BaseType); if (BaseKey == SymbolTable.PrefixExternClassName("System.Object") || BaseKey == SymbolTable.PrefixExternClassName("System.ValueType")) { BaseKey = string.Empty; } GenericTypeKey = ClassInfo.GetFullNameWithTypeParameters(sym); References.Clear(); IgnoreReferences.Clear(); }