public JsNode VisitMemberResolveResult(MemberResolveResult res) { var me = res.Member; JsNode node2; bool enumValuesAsNames; if (me == null) //TODO: dynamics { throw new NotImplementedException(); //var node3 = Js.Member(node.MemberName); //if (node.Target != null) // node3.PreviousMember = VisitExpression(node.Target); //return node3; } else if (Sk.IsEntityFunctionProperty(res.Member, res))//(Entity)node.entity)) { var pe = (IProperty)me; var xxx = new CSharpInvocationResolveResult(res.TargetResult, pe.Getter, null); node2 = Visit(xxx); return(node2); } else if (me.IsEnumMember() && Sk.UseJsonEnums(me, out enumValuesAsNames)) { var me2 = (IField)me; if (enumValuesAsNames) { return(Js.String(SkJs.GetEntityJsName(me2))); } else { return(Js.Value(me2.ConstantValue)); } } //TODO: Support a way to override this (JsField.ConstantInlining=false) else if (res.IsCompileTimeConstant && !me.IsEnumMember()) { return(Js.Value(res.ConstantValue)); } else { var node3 = SkJs.EntityToMember(me); node2 = node3; if (res.TargetResult != null && !me.IsStatic()) { var instanceContext = VisitExpression(res.TargetResult); if (node3.Name.IsNullOrEmpty()) //support Name="" { node2 = instanceContext; } else { node3.PreviousMember = instanceContext; } } } return(node2); }
public override JsNode _VisitClass(ITypeDefinition ce) { var unit = new JsUnit { Statements = new List <JsStatement>() }; ExportTypeNamespace(unit, ce); var members = GetMembersToExport(ce); VisitToUnit(unit, members); var baseCe = ce.GetBaseTypeDefinition(); if (baseCe != null && Sk.IsNativeType(baseCe) && !Sk.IsGlobalType(baseCe) && !Sk.OmitInheritance(ce)) { unit.Statements.Add(Js.Member("$Inherit").Invoke(SkJs.EntityToMember(ce), SkJs.EntityToMember(baseCe)).Statement()); } return(unit); }
public JsNode VisitMemberResolveResult(MemberResolveResult res) { var me = res.Member; JsNode node2; bool enumValuesAsNames; if (me == null) //TODO: dynamics { throw new NotImplementedException(); //var node3 = Js.Member(node.MemberName); //if (node.Target != null) // node3.PreviousMember = VisitExpression(node.Target); //return node3; } else if (Sk.IsEntityFunctionProperty(res.Member, res))//(Entity)node.entity)) { var pe = (IProperty)me; var xxx = new CSharpInvocationResolveResult(res.TargetResult, pe.Getter, null); var fn = res.GetFirstNode(); qiucw.InvokeRR2Location.Add(xxx, new qiucw.InvocationLocation { FileName = fn.GetFileName(), Line = fn.StartLocation.Line }); { node2 = Visit(xxx); } qiucw.InvokeRR2Location.Remove(xxx); return(node2); } else if (me.IsEnumMember() && Sk.UseJsonEnums(me, out enumValuesAsNames)) { var me2 = (IField)me; if (enumValuesAsNames) { return(Js.String(SkJs.GetEntityJsName(me2))); } else { return(Js.Value(me2.ConstantValue)); } } //TODO: Support a way to override this (JsField.ConstantInlining=false) else if (res.IsCompileTimeConstant && !me.IsEnumMember()) { var nodes = res.GetNodes(); if (nodes.IsNotNullOrEmpty()) { if (nodes[0] != null) { bool isPrimitiveExpr = nodes[0] is PrimitiveExpression; if (!isPrimitiveExpr) { return(Js.Value(res.ConstantValue, string.Format(" /* {0} */", nodes[0].ToString()))); } } } return(Js.Value(res.ConstantValue)); } else { var node3 = SkJs.EntityToMember(me); qiucw.CheckAddInvocation(res, node3.Name); node2 = node3; if (res.TargetResult != null && !me.IsStatic()) { var instanceContext = VisitExpression(res.TargetResult); if (node3.Name.IsNullOrEmpty()) //support Name="" { node2 = instanceContext; } else { node3.PreviousMember = instanceContext; } } } return(node2); }
public JsNode VisitMethodGroupResolveResult(MethodGroupResolveResult res) { var info = res.GetInfo(); IMethod me; if (info != null && info.Conversion != null && info.Conversion.Method != null) { me = info.Conversion.Method; } else //happens when invoking a method with overloads, and a parameter is dynamic { var list = res.Methods.ToList(); if (list.Count == 0) { throw new Exception("Method group not resolved to any method"); } else if (list.Count == 1) { me = list[0]; } else { me = list[0]; } //TODO: verify all methods has the same js name } var isExtensionMethodStyle = me.IsExtensionMethod && !(res.TargetResult is TypeResolveResult) && info != null && info.Conversion != null && info.Conversion.DelegateCapturesFirstArgument;//TODO: IsExtensionMethodStyle(new CsInvocationExpression { entity = me, expression = node }); JsExpression firstPrm = null; if (isExtensionMethodStyle) { firstPrm = (JsExpression)Visit(res.TargetResult); } var node2 = SkJs.EntityToMember(me); JsExpression node3; JsExpression instanceContext = null; if (me.IsStatic || res.TargetResult == null) //getting ThisResolveResult even on static methods, getting TargetResult=null when MethodGroupResolveResult when using delegates { node3 = node2; } else { instanceContext = VisitExpression(res.TargetResult); node3 = instanceContext.Member(node2); } if (info != null && (instanceContext != null || firstPrm != null)) { var conv = info.Conversion; if (info.ConversionTargetType != null && !UseNativeFunctions(info.ConversionTargetType))//delegate type { var parentMethod = info.Nodes.FirstOrDefault().GetCurrentMethod(); if (parentMethod == null || !Sk.ForceDelegatesAsNativeFunctions(parentMethod)) { if (parentMethod == null) { Log.Warn(info.Nodes.FirstOrDefault(), "GetParentMethod() returned null"); } var func = (JsExpression)node2; if (instanceContext != null) { node3 = CreateJsDelegate(instanceContext, func); } else if (firstPrm != null) { node3 = CreateJsExtensionDelegate(firstPrm, func); } } } } return(node3); }
public JsNode VisitMethodGroupResolveResult(MethodGroupResolveResult res) { var info = res.GetInfo(); IMethod me; if (info != null && info.Conversion != null && info.Conversion.Method != null) { me = info.Conversion.Method; } else //happens when invoking a method with overloads, and a parameter is dynamic { var list = res.Methods.ToList(); if (list.Count == 0) { throw new Exception("Method group not resolved to any method"); } else if (list.Count == 1) { me = list[0]; } else { me = list[0]; } //TODO: verify all methods has the same js name } var isExtensionMethodStyle = me.IsExtensionMethod && !(res.TargetResult is TypeResolveResult) && info != null && info.Conversion != null && info.Conversion.DelegateCapturesFirstArgument;//TODO: IsExtensionMethodStyle(new CsInvocationExpression { entity = me, expression = node }); JsExpression firstPrm = null; if (isExtensionMethodStyle) { firstPrm = (JsExpression)Visit(res.TargetResult); } var node2 = SkJs.EntityToMember(me); JsExpression node3; JsExpression instanceContext = null; if (me.IsStatic || res.TargetResult == null) //getting ThisResolveResult even on static methods, getting TargetResult=null when MethodGroupResolveResult when using delegates { node3 = node2; } else { instanceContext = VisitExpression(res.TargetResult); node3 = instanceContext.Member(node2); } if (info != null && (instanceContext != null || firstPrm != null)) { if (info.ConversionTargetType != null && !UseNativeFunctions(info.ConversionTargetType))//delegate type { var parentMethod = info.Nodes.FirstOrDefault().GetCurrentMethod(); if (parentMethod == null || !Sk.ForceDelegatesAsNativeFunctions(parentMethod)) { if (parentMethod == null) { Log.Warn(info.Nodes.FirstOrDefault(), "GetParentMethod() returned null"); } var func = (JsExpression)node2; if (instanceContext != null) { node3 = CreateJsDelegate(instanceContext, func); } else if (firstPrm != null) { node3 = CreateJsExtensionDelegate(firstPrm, func); } } } } // 其实以下的处理,也可以改代码,改成 Lambda 写法即可 // 这样子引用的并不是同一个函数,可能会造成内存泄露 if (res.TypeArguments.Count > 0 && info.Conversion.IsImplicit && me is SpecializedMethod) { var delegateFunc = node3 as JsInvocationExpression; var sme = (SpecializedMethod)me; var pars = sme.TypeArguments.Select(type => SkJs.EntityTypeRefToMember(type, false)).ToList(); pars.AddRange(sme.Parameters.Select(t => new JsCodeExpression { Code = JsIdentifier(t.Name), })); var body = delegateFunc == null?node3.Invoke(pars.ToArray()) : delegateFunc.Arguments[1].Invoke(pars.ToArray()); var func = new JsFunction() { Parameters = sme.Parameters.Select(t => JsIdentifier(t.Name)).ToList(), }; JsStatement st; if (sme.ReturnType.IsVoid()) { st = new JsExpressionStatement { Expression = body }; } else { st = new JsReturnStatement { Expression = body }; } func.Block = new JsBlock { Statements = new List <JsStatement> { st } }; if (delegateFunc == null) { node3 = func; } else { delegateFunc.Arguments[1] = func; } } return(node3); }
public JsNode VisitInvocationResolveResult(CSharpInvocationResolveResult res) { Res = res; ProcessMember(); if (MethodAtt != null && MethodAtt.InlineCode != null) { return(Js.CodeExpression(MethodAtt.InlineCode)); } var conditional = ProcessConditional(); if (conditional) { return(null); } bool omittedCalls; var omittedCallsNode = ProcessOmitCalls(out omittedCalls); if (omittedCalls) { return(omittedCallsNode); } JsMember = SkJs.EntityToMember(Member); qiucw.CheckAddInvocation(res, JsMember.Name); ProcessTarget(); ProcessPrmBindings(); ProcessNativeParams(); ProcessByRefs1(); PrmBindings.ForEach(t => t.JsCallResult = VisitExpression(t.Binding.CallResult)); Node2 = new JsInvocationExpression { Member = JsMember, Arguments = PrmBindings.Select(t => t.JsCallResult).ToList(), }; ProcessByRefs2(); ProcessExtensionImplementedInInstance(); TransformIntoBaseMethodCallIfNeeded(Res, Node2); ProcessArgsCustomization(); ProcessGenericMethodArgs(); var inlineCodeExpression = ProcessInlineCodeExpression(); if (inlineCodeExpression != null) { return(inlineCodeExpression); } var omittedDotOperator = ProcessOmitDotOperator(); if (omittedDotOperator != null) { return(omittedDotOperator); } ProcessRemoveEmptyPreviousMemberName(); var indexerAccess = ProcessIndexer(); if (indexerAccess != null) { return(indexerAccess); } ProcessByRefs3(); return(Node2); }
protected JsBlock ExportMethodBody(IMethod me) { if (CompilerConfiguration.Current.EnableLogging) { Log.Debug("JsTypeImporter: Visit Method: " + me.ToString()); } var nativeCode = Sk.GetNativeCode(me); if (nativeCode != null) { var block = Js.Block().Add(Js.CodeStatement(nativeCode)); //TODO: double semicolon? return(block); } var def = me.GetDefinition(); if (def == null || def.IsNull) { if (me.IsAutomaticEventAccessor()) { if (me.IsEventAddAccessor()) { var node = GenerateAutomaticEventAccessor((IEvent)me.GetOwner(), false); return(node.Block); } else if (me.IsEventRemoveAccessor()) { var node = GenerateAutomaticEventAccessor((IEvent)me.GetOwner(), true); return(node.Block); } } else if (me.IsAutomaticPropertyAccessor()) { var bf = Js.Member(AutoPropertyPrefix + SkJs.GetEntityJsName(me.AccessorOwner)); if (!me.IsStatic) { bf.PreviousMember = Js.This(); } else if (!Sk.IsGlobalMethod(me)) { bf.PreviousMember = SkJs.EntityToMember(me.DeclaringTypeDefinition); } if (me.IsGetter()) { return(Js.Block().Add(Js.Return(bf))); } else { return(Js.Block().Add(bf.Assign(Js.Member("value")).Statement())); } } return(null); } var block2 = (JsBlock)AstNodeConverter.Visit(def); block2.ContainsYield = false; if (def.Descendants.OfType <YieldReturnStatement>().FirstOrDefault() != null) { block2.ContainsYield = true; if (!AstNodeConverter.SupportClrYield) { if (block2.Statements == null) { block2.Statements = new List <JsStatement>(); } //block2.Statements.Insert(0, Js.Var("$yield", Js.NewJsonArray()).Statement()); //block2.Statements.Add(AstNodeConverter.GenerateYieldReturnStatement(me)); } } return(block2); }