internal void Init(IMethodSymbol sym, SyntaxNode node) { 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()); } } 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); if (arrTypeSym.ElementType.IsValueType && !SymbolTable.IsBasicType(arrTypeSym.ElementType) && !CsDslTranslater.IsImplementationOfSys(arrTypeSym.ElementType, "IEnumerator")) { string ns = ClassInfo.GetNamespaces(arrTypeSym.ElementType); if (SymbolTable.Instance.IsCs2DslSymbol(arrTypeSym.ElementType)) { NeedFuncInfo = true; } else if (ns != "System") { NeedFuncInfo = true; } } } ParamNames.Add("..."); ParamTypes.Add(ClassInfo.GetFullName(param.Type)); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); OriginalParamsName = param.Name; //遇到变参直接结束(变参set_Item会出现后面带一个value参数的情形,在函数实现里处理) break; } else if (param.RefKind == RefKind.Ref) { 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)) { ValueParams.Add(ParamNames.Count); NeedFuncInfo = true; } else if (ns != "System") { ExternValueParams.Add(ParamNames.Count); NeedFuncInfo = true; } } //ref参数与out参数在形参处理时机制相同,实参时out参数传入__cs2dsl_out(适应脚本引擎与dotnet反射的调用规则) ParamNames.Add(param.Name); ParamTypes.Add(ClassInfo.GetFullName(param.Type)); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ReturnParamNames.Add(param.Name); } 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反射的调用规则) ParamNames.Add(param.Name); ParamTypes.Add(ClassInfo.GetFullName(param.Type)); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); ReturnParamNames.Add(param.Name); } else { 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)) { ValueParams.Add(ParamNames.Count); NeedFuncInfo = true; } else if (ns != "System") { ExternValueParams.Add(ParamNames.Count); NeedFuncInfo = true; } } ParamNames.Add(param.Name); ParamTypes.Add(ClassInfo.GetFullName(param.Type)); ParamTypeKinds.Add("TypeKind." + param.Type.TypeKind.ToString()); } 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()); } } 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); }
internal void OutputInvocation(StringBuilder codeBuilder, CsDslTranslater cs2dsl, ExpressionSyntax exp, bool isMemberAccess, SemanticModel model, SyntaxNode node) { IMethodSymbol sym = MethodSymbol; string mname = cs2dsl.NameMangling(IsExtensionMethod && null != sym.ReducedFrom ? sym.ReducedFrom : sym); string prestr = string.Empty; if (isMemberAccess) { string fnOfIntf = "null"; bool isExplicitInterfaceInvoke = cs2dsl.CheckExplicitInterfaceAccess(sym, ref fnOfIntf); if (sym.MethodKind == MethodKind.DelegateInvoke) { var memberAccess = node as MemberAccessExpressionSyntax; if (null != memberAccess) { codeBuilder.Append("callinstance("); cs2dsl.OutputExpressionSyntax(exp); codeBuilder.AppendFormat(", \"{0}\"", memberAccess.Name); prestr = ", "; } else { //error; } } else if (isExplicitInterfaceInvoke) { codeBuilder.Append("invokewithinterface("); cs2dsl.OutputExpressionSyntax(exp); codeBuilder.Append(", "); codeBuilder.AppendFormat("{0}, \"{1}\"", fnOfIntf, mname); prestr = ", "; } else if (IsExtensionMethod) { codeBuilder.Append("callstatic("); codeBuilder.AppendFormat("{0}, \"{1}\", ", ClassKey, mname); } else if (IsBasicValueMethod) { string ckey = CalcInvokeTarget(IsEnumClass, ClassKey, cs2dsl, exp, model); codeBuilder.Append("invokeforbasicvalue("); cs2dsl.OutputExpressionSyntax(exp); codeBuilder.Append(", "); codeBuilder.AppendFormat("{0}, {1}, \"{2}\"", IsEnumClass ? "true" : "false", ckey, mname); prestr = ", "; } else if (IsArrayStaticMethod) { codeBuilder.Append("invokearraystaticmethod("); if (null == FirstRefArray) { codeBuilder.Append("null, "); } else { cs2dsl.OutputExpressionSyntax(FirstRefArray); codeBuilder.Append(", "); } if (null == SecondRefArray) { codeBuilder.Append("null, "); } else { cs2dsl.OutputExpressionSyntax(SecondRefArray); codeBuilder.Append(", "); } codeBuilder.AppendFormat("\"{0}\"", mname); prestr = ", "; } else { if (sym.IsStatic) { codeBuilder.Append("callstatic("); codeBuilder.Append(ClassKey); } else { codeBuilder.Append("callinstance("); cs2dsl.OutputExpressionSyntax(exp); } codeBuilder.AppendFormat(", \"{0}\"", mname); prestr = ", "; } } else { if (sym.MethodKind == MethodKind.DelegateInvoke) { cs2dsl.OutputExpressionSyntax(exp); codeBuilder.Append("("); } else if (sym.IsStatic) { codeBuilder.Append("callstatic("); codeBuilder.Append(ClassKey); codeBuilder.AppendFormat(", \"{0}\"", mname); prestr = ", "; } else { codeBuilder.Append("callinstance("); codeBuilder.Append("this"); codeBuilder.AppendFormat(", \"{0}\"", mname); prestr = ", "; } } if (Args.Count + DefaultValueArgs.Count + GenericTypeArgs.Count > 0) { codeBuilder.Append(prestr); } bool useTypeNameString = false; if (IsComponentGetOrAdd && SymbolTable.DslComponentByString) { var tArgs = sym.TypeArguments; if (tArgs.Length > 0 && SymbolTable.Instance.IsCs2DslSymbol(tArgs[0])) { useTypeNameString = true; } } if (IsExtensionMethod) { var args = new List <ExpressionSyntax>(); args.Add(exp); args.AddRange(Args); cs2dsl.OutputArgumentList(args, DefaultValueArgs, GenericTypeArgs, ArrayToParams, useTypeNameString, node, ArgConversions.ToArray()); } else { cs2dsl.OutputArgumentList(Args, DefaultValueArgs, GenericTypeArgs, ArrayToParams, useTypeNameString, node, ArgConversions.ToArray()); } codeBuilder.Append(")"); }
public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { var ci = m_ClassInfoStack.Peek(); var localSym = m_Model.GetDeclaredSymbol(node) as ILocalSymbol; if (null != localSym && localSym.HasConstantValue) { if (null != node.Initializer) { CodeBuilder.AppendFormat("{0}local({1}); {2}", GetIndentString(), node.Identifier.Text, node.Identifier.Text); } else { CodeBuilder.AppendFormat("{0}local({1})", GetIndentString(), node.Identifier.Text); } CodeBuilder.Append(" = "); OutputConstValue(localSym.ConstantValue, localSym); CodeBuilder.AppendLine(";"); return; } bool dslToObject = false; ITypeSymbol type = null; if (null != node.Initializer) { type = m_Model.GetTypeInfoEx(node.Initializer.Value).Type; if (null != localSym && null != localSym.Type && null != type) { dslToObject = InvocationInfo.IsDslToObject(localSym.Type, type); } } VisitLocalVariableDeclarator(ci, node, dslToObject); if (null != node.Initializer) { var rightSymbolInfo = m_Model.GetSymbolInfoEx(node.Initializer.Value); var rightSym = rightSymbolInfo.Symbol; if (null != type && type.IsValueType && !dslToObject && !SymbolTable.IsBasicType(type) && !CsDslTranslater.IsImplementationOfSys(type, "IEnumerator")) { if (null != rightSym && (rightSym.Kind == SymbolKind.Method || rightSym.Kind == SymbolKind.Property || rightSym.Kind == SymbolKind.Field || rightSym.Kind == SymbolKind.Local) && SymbolTable.Instance.IsCs2DslSymbol(rightSym)) { MarkNeedFuncInfo(); if (SymbolTable.Instance.IsCs2DslSymbol(type)) { CodeBuilder.AppendFormat("{0}{1} = wrapstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(type)); CodeBuilder.AppendLine(); } else { string ns = ClassInfo.GetNamespaces(type); if (ns != "System") { CodeBuilder.AppendFormat("{0}{1} = wrapexternstruct({2}, {3});", GetIndentString(), node.Identifier.Text, node.Identifier.Text, ClassInfo.GetFullName(type)); CodeBuilder.AppendLine(); } } } } } }