internal void Init(IMethodSymbol sym, SyntaxNode node) { IsAnonymousOrLambdaMethod = node is SimpleLambdaExpressionSyntax || node is ParenthesizedLambdaExpressionSyntax || node is AnonymousMethodExpressionSyntax; TryCatchUsingOrLoopSwitchStack.Clear(); TempReturnAnalysisStack.Clear(); ParamNames.Clear(); ReturnParamNames.Clear(); OriginalParamsName = string.Empty; ExistYield = false; ExistTopLevelReturn = false; ExistTry = false; TryUsingLayer = 0; ReturnVarName = string.Empty; SemanticInfo = sym; SyntaxNode = node; if (!sym.IsExtensionMethod && sym.IsGenericMethod) { //不是扩展方法,泛型参数放在参数表最前面 foreach (var param in sym.TypeParameters) { ParamNames.Add(param.Name); if (param.ConstraintTypes.Length > 0) { ParamTypes.Add(ClassInfo.GetFullName(param.ConstraintTypes[0])); } else if (param.HasReferenceTypeConstraint) { ParamTypes.Add("System.Object"); } else if (param.HasValueTypeConstraint) { ParamTypes.Add("System.ValueType"); } else { ParamTypes.Add("null"); } ParamTypeKinds.Add("TypeKind." + param.TypeKind.ToString()); ParamRefOrOuts.Add(0); ParamIsExterns.Add(false); } } bool first = true; foreach (var param in sym.Parameters) { if (param.IsParams) { var arrTypeSym = param.Type as IArrayTypeSymbol; if (null != arrTypeSym) { string elementType = ClassInfo.GetFullName(arrTypeSym.ElementType); string elementTypeKind = "TypeKind." + arrTypeSym.ElementType.TypeKind.ToString(); ParamsElementInfo = string.Format("{0}, {1}", elementType, elementTypeKind); } ParamNames.Add("..."); ParamTypes.Add(ClassInfo.GetFullName(param.Type)); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ParamRefOrOuts.Add(0); ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type)); OriginalParamsName = param.Name; //遇到变参直接结束(变参set_Item会出现后面带一个value参数的情形,在函数实现里处理) break; } else if (param.RefKind == RefKind.Ref) { //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则) var fn = ClassInfo.GetFullName(param.Type); ParamNames.Add(param.Name); ParamTypes.Add(fn); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ParamRefOrOuts.Add(1); ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type)); ReturnParamNames.Add(param.Name); ReturnParamTypes.Add(fn); ReturnParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ReturnParamRefOrOuts.Add(1); ReturnParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type)); } else if (param.RefKind == RefKind.Out) { if (param.Type.IsValueType && !SymbolTable.IsBasicType(param.Type) && !CsDslTranslater.IsImplementationOfSys(param.Type, "IEnumerator")) { string ns = ClassInfo.GetNamespaces(param.Type); if (SymbolTable.Instance.IsCs2DslSymbol(param.Type)) { OutValueParams.Add(ParamNames.Count); NeedFuncInfo = true; } else if (ns != "System") { OutExternValueParams.Add(ParamNames.Count); NeedFuncInfo = true; } } //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则) var fn = ClassInfo.GetFullName(param.Type); ParamNames.Add(param.Name); ParamTypes.Add(fn); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ParamRefOrOuts.Add(2); ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type)); ReturnParamNames.Add(param.Name); ReturnParamTypes.Add(fn); ReturnParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ReturnParamRefOrOuts.Add(2); ReturnParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type)); } else { ParamNames.Add(param.Name); ParamTypes.Add(ClassInfo.GetFullName(param.Type)); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ParamRefOrOuts.Add(0); ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type)); } if (first && sym.IsExtensionMethod && sym.IsGenericMethod) { //扩展方法的泛型参数放在第一个参数后 foreach (var tp in sym.TypeParameters) { ParamNames.Add(tp.Name); if (tp.ConstraintTypes.Length > 0) { ParamTypes.Add(ClassInfo.GetFullName(tp.ConstraintTypes[0])); } else if (tp.HasReferenceTypeConstraint) { ParamTypes.Add("System.Object"); } else if (tp.HasValueTypeConstraint) { ParamTypes.Add("System.ValueType"); } else { ParamTypes.Add("null"); } ParamTypeKinds.Add("TypeKind." + tp.TypeKind.ToString()); ParamRefOrOuts.Add(0); ParamIsExterns.Add(!SymbolTable.Instance.IsCs2DslSymbol(param.Type)); } } first = false; } if (!sym.ReturnsVoid) { string returnType = ClassInfo.GetFullName(sym.ReturnType); if (returnType.StartsWith("System.Collections") && (sym.ReturnType.Name == "IEnumerable" || sym.ReturnType.Name == "IEnumerator")) { var analysis = new YieldAnalysis(); analysis.Visit(node); ExistYield = analysis.YieldCount > 0; } } ReturnValueCount = ReturnParamNames.Count + (sym.ReturnsVoid ? 0 : 1); if (!NeedFuncInfo && ClassInfo.HasAttribute(sym, "Cs2Dsl.NeedFuncInfoAttribute")) { NeedFuncInfo = true; } }
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 == "System.Object" || BaseClassKey == "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); }
public override void VisitIdentifierName(IdentifierNameSyntax node) { string name = node.Identifier.Text; if (m_ClassInfoStack.Count > 0) { ClassInfo classInfo = m_ClassInfoStack.Peek(); SymbolInfo symbolInfo = m_Model.GetSymbolInfoEx(node); var sym = symbolInfo.Symbol; if (null != sym) { bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(sym); if (sym.Kind == SymbolKind.NamedType || sym.Kind == SymbolKind.Namespace) { string fullName = ClassInfo.GetFullName(sym); CodeBuilder.Append(fullName); if (sym.Kind == SymbolKind.NamedType) { var namedType = sym as INamedTypeSymbol; AddReferenceAndTryDeriveGenericTypeInstance(classInfo, namedType); } return; } else if (sym.Kind == SymbolKind.Field || sym.Kind == SymbolKind.Property || sym.Kind == SymbolKind.Event) { var fsym = sym as IFieldSymbol; var psym = sym as IPropertySymbol; string fullName = ClassInfo.GetFullName(sym.ContainingType); if (sym.IsStatic) { if (isExtern && null != fsym && fsym.Type.IsValueType && !SymbolTable.IsBasicType(fsym.Type)) { MarkNeedFuncInfo(); CodeBuilder.AppendFormat("getexternstaticstructmember(SymbolKind.{0}, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name); } else if (isExtern && null != psym && psym.Type.IsValueType && !SymbolTable.IsBasicType(psym.Type)) { MarkNeedFuncInfo(); CodeBuilder.AppendFormat("getexternstaticstructmember(SymbolKind.{0}, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name); } else { CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, {2}, \"{3}\")", isExtern ? "getexternstatic" : "getstatic", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name); } return; } else if (IsNewObjMember(name)) { if (isExtern && null != fsym && fsym.Type.IsValueType && !SymbolTable.IsBasicType(fsym.Type)) { MarkNeedFuncInfo(); CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, newobj, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, name); } else if (isExtern && null != psym && psym.Type.IsValueType && !SymbolTable.IsBasicType(psym.Type)) { MarkNeedFuncInfo(); CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, newobj, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, name); } else { CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, newobj, {2}, \"{3}\")", isExtern ? "getexterninstance" : "getinstance", SymbolTable.Instance.GetSymbolKind(sym), fullName, name); } return; } else if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType)) { if (isExtern && null != fsym && fsym.Type.IsValueType && !SymbolTable.IsBasicType(fsym.Type)) { MarkNeedFuncInfo(); CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, this, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name); } else if (isExtern && null != psym && psym.Type.IsValueType && !SymbolTable.IsBasicType(psym.Type)) { MarkNeedFuncInfo(); CodeBuilder.AppendFormat("getexterninstancestructmember(SymbolKind.{0}, this, {1}, \"{2}\")", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name); } else { CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, this, {2}, \"{3}\")", isExtern ? "getexterninstance" : "getinstance", SymbolTable.Instance.GetSymbolKind(sym), fullName, sym.Name); } return; } } else if (sym.Kind == SymbolKind.Method) { var msym = sym as IMethodSymbol; string manglingName = NameMangling(msym); var mi = new MethodInfo(); mi.Init(msym, node); string fullName = ClassInfo.GetFullName(sym.ContainingType); if (sym.IsStatic && node.Parent is InvocationExpressionSyntax) { CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, {2}, \"{3}\")", isExtern ? "getexternstatic" : "getstatic", SymbolTable.Instance.GetSymbolKind(sym), fullName, manglingName); return; } else if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType)) { if (node.Parent is InvocationExpressionSyntax) { CodeBuilder.AppendFormat("{0}(SymbolKind.{1}, this, {2}, \"{3}\")", isExtern ? "getexterninstance" : "getinstance", SymbolTable.Instance.GetSymbolKind(sym), fullName, manglingName); } else { string srcPos = GetSourcePosForVar(node); string delegationKey = string.Format("{0}:{1}", fullName, manglingName); if (msym.IsStatic) { CodeBuilder.AppendFormat("builddelegation(\"{0}\", \"{1}\", {2}, {3}, {4})", srcPos, delegationKey, fullName, manglingName, "true"); } else { CodeBuilder.AppendFormat("builddelegation(\"{0}\", \"{1}\", this, {2}, {3})", srcPos, delegationKey, manglingName, "false"); } } return; } } } else { string fn; SymbolKind kind; if (IsNewObjMember(name, out fn, out kind)) { CodeBuilder.AppendFormat("getinstance(SymbolKind.{0}, newobj, {1}, \"{2}\")", kind.ToString(), fn, name); return; } ReportIllegalSymbol(node, symbolInfo); } } CodeBuilder.Append(name); }
private void BuildInterfaceInfo(INamedTypeSymbol typeSym, CSharpCompilation compilation, SymbolTable symTable) { foreach (var intf in typeSym.AllInterfaces) { if (!InterfaceSymbols.Contains(intf)) { InterfaceSymbols.Add(intf); } foreach (var sym in intf.GetMembers()) { var msym = sym as IMethodSymbol; if (null != msym) { var implSym = typeSym.FindImplementationForInterfaceMember(sym) as IMethodSymbol; if (null != implSym) { string name = symTable.NameMangling(msym); name = ClassInfo.CalcNameWithFullTypeName(name, sym.ContainingType); string implName = symTable.NameMangling(implSym); if (!InterfaceMethodMap.ContainsKey(name)) { InterfaceMethodMap.Add(name, implName); } } } var psym = sym as IPropertySymbol; if (null != psym && !psym.IsIndexer) { var implSym = typeSym.FindImplementationForInterfaceMember(sym) as IPropertySymbol; if (null != implSym && !psym.IsIndexer) { string name = SymbolTable.GetPropertyName(psym); name = ClassInfo.CalcNameWithFullTypeName(name, sym.ContainingType); string implName = SymbolTable.GetPropertyName(implSym); if (!InterfaceMethodMap.ContainsKey(name)) { InterfaceMethodMap.Add(name, implName); } } } var esym = sym as IEventSymbol; if (null != esym) { var implSym = typeSym.FindImplementationForInterfaceMember(sym) as IEventSymbol; if (null != implSym) { string name = SymbolTable.GetEventName(esym); name = ClassInfo.CalcNameWithFullTypeName(name, sym.ContainingType); string implName = SymbolTable.GetEventName(implSym); if (!InterfaceMethodMap.ContainsKey(name)) { InterfaceMethodMap.Add(name, implName); } } } } } if (typeSym.TypeKind != TypeKind.Interface) { foreach (var sym in typeSym.GetMembers()) { var msym = sym as IMethodSymbol; if (null != msym && msym.ExplicitInterfaceImplementations.Length > 0) { foreach (var implSym in msym.ExplicitInterfaceImplementations) { string fn = ClassInfo.GetFullName(implSym.ContainingType); ClassSymbolInfo csi; if (symTable.ClassSymbols.TryGetValue(fn, out csi)) { if (!csi.ExplicitInterfaceImplementationMethods.Contains(implSym)) { csi.ExplicitInterfaceImplementationMethods.Add(implSym); } } } } var psym = sym as IPropertySymbol; if (null != psym && !psym.IsIndexer && psym.ExplicitInterfaceImplementations.Length > 0) { foreach (var implSym in psym.ExplicitInterfaceImplementations) { string fn = ClassInfo.GetFullName(implSym.ContainingType); ClassSymbolInfo csi; if (symTable.ClassSymbols.TryGetValue(fn, out csi)) { if (!csi.ExplicitInterfaceImplementationProperties.Contains(implSym)) { csi.ExplicitInterfaceImplementationProperties.Add(implSym); } } } } var esym = sym as IEventSymbol; if (null != esym && esym.ExplicitInterfaceImplementations.Length > 0) { foreach (var implSym in esym.ExplicitInterfaceImplementations) { string fn = ClassInfo.GetFullName(implSym.ContainingType); ClassSymbolInfo csi; if (symTable.ClassSymbols.TryGetValue(fn, out csi)) { if (!csi.ExplicitInterfaceImplementationEvents.Contains(implSym)) { csi.ExplicitInterfaceImplementationEvents.Add(implSym); } } } } } } }