public override void VisitCastExpression(CastExpressionSyntax node) { var ci = m_ClassInfoStack.Peek(); var oper = m_Model.GetOperation(node) as IConversionExpression; if (null != oper && oper.UsesOperatorMethod) { IMethodSymbol msym = oper.OperatorMethod; InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node.Expression }; ii.Init(msym, arglist, m_Model); AddReferenceAndTryDeriveGenericTypeInstance(ci, oper.Type); OutputOperatorInvoke(ii, node); } else { CodeBuilder.Append("typecast("); VisitExpressionSyntax(node.Expression); var typeInfo = m_Model.GetTypeInfo(node.Type); var type = typeInfo.Type; CodeBuilder.Append(", "); OutputType(type, node, ci, "cast"); CodeBuilder.Append(")"); } }
public override void VisitPostfixUnaryExpression(PostfixUnaryExpressionSyntax node) { var oper = m_Model.GetOperation(node) as IHasOperatorMethodExpression; if (null != oper && oper.UsesOperatorMethod) { IMethodSymbol msym = oper.OperatorMethod; InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node.Operand }; ii.Init(msym, arglist, m_Model); OutputOperatorInvoke(ii, node); } else { string op = node.OperatorToken.Text; if (op == "++" || op == "--") { VisitExpressionSyntax(node.Operand); m_PostfixUnaryExpressions.Enqueue(node); } else { CodeBuilder.Append("("); CodeBuilder.Append(op); CodeBuilder.Append(" "); VisitExpressionSyntax(node.Operand); CodeBuilder.Append(")"); } } }
public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node) { var oper = m_Model.GetOperation(node) as IHasOperatorMethodExpression; if (null != oper && oper.UsesOperatorMethod) { IMethodSymbol msym = oper.OperatorMethod; InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node.Operand }; ii.Init(msym, arglist, m_Model); OutputOperatorInvoke(ii, node); } else { string op = node.OperatorToken.Text; if (op == "++" || op == "--") { CodeBuilder.Append("(function() "); VisitExpressionSyntax(node.Operand); CodeBuilder.Append(" = "); VisitExpressionSyntax(node.Operand); CodeBuilder.Append(" "); CodeBuilder.Append(op == "++" ? "+" : "-"); CodeBuilder.Append(" 1; return "); VisitExpressionSyntax(node.Operand); CodeBuilder.Append("; end)()"); } else { ProcessUnaryOperator(node, ref op); string functor; if (s_UnaryFunctor.TryGetValue(op, out functor)) { CodeBuilder.AppendFormat("{0}(", functor); VisitExpressionSyntax(node.Operand); } else { CodeBuilder.Append("("); CodeBuilder.Append(op); CodeBuilder.Append(" "); VisitExpressionSyntax(node.Operand); } CodeBuilder.Append(")"); } } }
internal void OutputExpressionSyntax(ExpressionSyntax node, IConversionExpression opd) { if (null != opd && opd.UsesOperatorMethod && !(node is CastExpressionSyntax)) { IMethodSymbol msym = opd.OperatorMethod; InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node }; ii.Init(msym, arglist, m_Model); OutputOperatorInvoke(ii, node); } else { VisitExpressionSyntax(node); } }
public override void VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) { var ci = m_ClassInfoStack.Peek(); var oper = m_Model.GetOperation(node); var objectCreate = oper as IObjectCreationExpression; if (null != objectCreate) { var typeSymInfo = objectCreate.Type; var sym = objectCreate.Constructor; m_ObjectCreateStack.Push(typeSymInfo); string fullTypeName = ClassInfo.GetFullName(typeSymInfo); //处理ref/out参数 InvocationInfo ii = new InvocationInfo(); ii.Init(sym, node.ArgumentList, m_Model); AddReferenceAndTryDeriveGenericTypeInstance(ci, sym); bool isCollection = IsImplementationOfSys(typeSymInfo, "ICollection"); bool isExternal = typeSymInfo.ContainingAssembly != m_SymbolTable.AssemblySymbol; string ctor = NameMangling(sym); string localName = string.Format("__compiler_newobject_{0}", node.GetLocation().GetLineSpan().StartLinePosition.Line); if (ii.ReturnArgs.Count > 0) { CodeBuilder.Append("(function() "); CodeBuilder.AppendFormat("local {0}; {1}", localName, localName); CodeBuilder.Append(", "); OutputExpressionList(ii.ReturnArgs); CodeBuilder.Append(" = "); } if (isCollection) { bool isDictionary = IsImplementationOfSys(typeSymInfo, "IDictionary"); bool isList = IsImplementationOfSys(typeSymInfo, "IList"); if (isDictionary) { //字典对象的处理 CodeBuilder.AppendFormat("new{0}dictionary({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } else if (isList) { //列表对象的处理 CodeBuilder.AppendFormat("new{0}list({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } else { //集合对象的处理 CodeBuilder.AppendFormat("new{0}collection({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } } else { CodeBuilder.AppendFormat("new{0}object({1}, ", isExternal ? "extern" : string.Empty, fullTypeName); if (isExternal) { CodeBuilder.AppendFormat("\"{0}\", ", fullTypeName); } } if (string.IsNullOrEmpty(ctor)) { CodeBuilder.Append("nil"); } else { CodeBuilder.AppendFormat("\"{0}\"", ctor); } if (isExternal) { ClassSymbolInfo csi; if (m_SymbolTable.ClassSymbols.TryGetValue(fullTypeName, out csi)) { if (csi.ExtensionClasses.Count > 0) { CodeBuilder.Append(", (function(obj)"); foreach (var pair in csi.ExtensionClasses) { string refname = pair.Key; CodeBuilder.AppendFormat(" {0}.__install_{1}(obj);", fullTypeName, refname.Replace(".", "_")); } CodeBuilder.Append(" end)"); } else { CodeBuilder.Append(", nil"); } } else { CodeBuilder.Append(", nil"); } } if (null != node.Initializer) { CodeBuilder.Append(", "); if (!isCollection) { CodeBuilder.Append("{"); } VisitInitializerExpression(node.Initializer); if (!isCollection) { CodeBuilder.Append("}"); } } else { CodeBuilder.Append(", {}"); } if (ii.Args.Count + ii.DefaultValueArgs.Count + ii.GenericTypeArgs.Count > 0) { CodeBuilder.Append(", "); } OutputArgumentList(ii.Args, ii.DefaultValueArgs, ii.GenericTypeArgs, ii.ArrayToParams, false, node); CodeBuilder.Append(")"); if (ii.ReturnArgs.Count > 0) { CodeBuilder.Append("; "); CodeBuilder.AppendFormat("return {0}; end)()", localName); } m_ObjectCreateStack.Pop(); } else { var methodBinding = oper as IMethodBindingExpression; if (null != methodBinding) { var typeSymInfo = methodBinding.Type; var msym = methodBinding.Method; if (null != msym) { string manglingName = NameMangling(msym); var mi = new MethodInfo(); mi.Init(msym, node); CodeBuilder.Append("(function("); string paramsString = string.Join(", ", mi.ParamNames.ToArray()); CodeBuilder.Append(paramsString); CodeBuilder.Append(") "); if (!msym.ReturnsVoid) { CodeBuilder.Append("return "); } if (msym.IsStatic) { AddReferenceAndTryDeriveGenericTypeInstance(ci, msym); string className = ClassInfo.GetFullName(msym.ContainingType); CodeBuilder.Append(className); CodeBuilder.Append("."); } else { CodeBuilder.Append("this:"); } CodeBuilder.Append(manglingName); CodeBuilder.AppendFormat("({0}) end)", paramsString); } else { VisitArgumentList(node.ArgumentList); } } else { var typeParamObjCreate = oper as ITypeParameterObjectCreationExpression; if (null != typeParamObjCreate) { CodeBuilder.Append("newtypeparamobject("); OutputType(typeParamObjCreate.Type, node, ci, "new"); CodeBuilder.Append(")"); } else { Log(node, "Unknown ObjectCreationExpressionSyntax !"); } } } }
public override void VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node) { CodeBuilder.Append("condaccess("); VisitExpressionSyntax(node.Expression); CodeBuilder.Append(", "); var elementBinding = node.WhenNotNull as ElementBindingExpressionSyntax; if (null != elementBinding) { var oper = m_Model.GetOperation(node.WhenNotNull); var symInfo = m_Model.GetSymbolInfo(node.WhenNotNull); var sym = symInfo.Symbol; var psym = sym as IPropertySymbol; if (null != sym && sym.IsStatic) { var ci = m_ClassInfoStack.Peek(); AddReferenceAndTryDeriveGenericTypeInstance(ci, sym); } if (null != psym && psym.IsIndexer) { CodeBuilder.Append("(function() return "); CodeBuilder.AppendFormat("get{0}{1}indexer(", psym.ContainingAssembly == m_SymbolTable.AssemblySymbol ? string.Empty : "extern", psym.IsStatic ? "static" : "instance"); if (psym.IsStatic) { string fullName = ClassInfo.GetFullName(psym.ContainingType); CodeBuilder.Append(fullName); } else { VisitExpressionSyntax(node.Expression); } CodeBuilder.Append(", "); if (!psym.IsStatic) { string fnOfIntf = "nil"; CheckExplicitInterfaceAccess(psym.GetMethod, ref fnOfIntf); CodeBuilder.AppendFormat("{0}, ", fnOfIntf); } string manglingName = NameMangling(psym.GetMethod); CodeBuilder.AppendFormat("\"{0}\", ", manglingName); InvocationInfo ii = new InvocationInfo(); List <ExpressionSyntax> args = new List <ExpressionSyntax> { node.WhenNotNull }; ii.Init(psym.GetMethod, args, m_Model); OutputArgumentList(ii.Args, ii.DefaultValueArgs, ii.GenericTypeArgs, ii.ArrayToParams, false, elementBinding); CodeBuilder.Append(")"); CodeBuilder.Append("; end)"); } else if (oper.Kind == OperationKind.ArrayElementReferenceExpression) { CodeBuilder.Append("(function() return "); VisitExpressionSyntax(node.Expression); CodeBuilder.Append("["); VisitExpressionSyntax(node.WhenNotNull); CodeBuilder.Append(" + 1]"); CodeBuilder.Append("; end)"); } else if (null != sym) { CodeBuilder.Append("(function() return "); CodeBuilder.AppendFormat("get{0}{1}element(", sym.ContainingAssembly == m_SymbolTable.AssemblySymbol ? string.Empty : "extern", sym.IsStatic ? "static" : "instance"); if (sym.IsStatic) { string fullName = ClassInfo.GetFullName(sym.ContainingType); CodeBuilder.Append(fullName); } else { VisitExpressionSyntax(node.Expression); } CodeBuilder.Append(", "); CodeBuilder.AppendFormat("\"{0}\", ", sym.Name); VisitExpressionSyntax(node.WhenNotNull); CodeBuilder.Append(")"); CodeBuilder.Append("; end)"); } else { ReportIllegalSymbol(node, symInfo); } } else { CodeBuilder.Append("(function() return "); VisitExpressionSyntax(node.Expression); VisitExpressionSyntax(node.WhenNotNull); CodeBuilder.Append("; end)"); } CodeBuilder.Append(")"); }
public override void VisitBinaryExpression(BinaryExpressionSyntax node) { var ci = m_ClassInfoStack.Peek(); var oper = m_Model.GetOperation(node) as IHasOperatorMethodExpression; if (null != oper && oper.UsesOperatorMethod) { IMethodSymbol msym = oper.OperatorMethod; var castOper = oper as IConversionExpression; if (null != castOper) { InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node.Left }; ii.Init(msym, arglist, m_Model); OutputOperatorInvoke(ii, node); } else { InvocationInfo ii = new InvocationInfo(); var arglist = new List <ExpressionSyntax>() { node.Left, node.Right }; ii.Init(msym, arglist, m_Model); OutputOperatorInvoke(ii, node); } } else { string op = node.OperatorToken.Text; ProcessBinaryOperator(node, ref op); string functor; if (s_BinaryFunctor.TryGetValue(op, out functor)) { CodeBuilder.AppendFormat("{0}(", functor); VisitExpressionSyntax(node.Left); CodeBuilder.Append(", "); if (op == "as" || op == "is") { var typeInfo = m_Model.GetTypeInfo(node.Right); var type = typeInfo.Type; OutputType(type, node, ci, op); } else if (op == "??") { var rightOper = m_Model.GetOperation(node.Right); bool rightIsConst = null != rightOper && rightOper.ConstantValue.HasValue; if (rightIsConst) { CodeBuilder.Append("true, "); VisitExpressionSyntax(node.Right); } else { CodeBuilder.Append("false, (function() return "); VisitExpressionSyntax(node.Right); CodeBuilder.Append("; end)"); } } else { VisitExpressionSyntax(node.Right); } CodeBuilder.Append(")"); } else if (op == "+") { ProcessAddOrStringConcat(node.Left, node.Right); } else if (op == "==" || op == "~=") { ProcessEqualOrNotEqual(op, node.Left, node.Right); } else { CodeBuilder.Append("("); VisitExpressionSyntax(node.Left); CodeBuilder.AppendFormat(" {0} ", op); VisitExpressionSyntax(node.Right); CodeBuilder.Append(")"); } } }