MemberConverter GetMemberConverter(ITypeDefinition ce) { MemberConverter export; var isExtJs = Sk.IsExtJsType(ce); var isGlobal = Sk.IsGlobalType(ce) && !isExtJs; var isNative = Sk.IsNativeType(ce) && !isExtJs; if (isGlobal) { if (GlobalConverter == null) { GlobalConverter = new MemberConverter_Global(); } export = GlobalConverter; } else if (isNative) { if (NativeConverter == null) { NativeConverter = new MemberConverter_Native(); } export = NativeConverter; } else if (isExtJs) { if (ExtJsConverter == null) { ExtJsConverter = new MemberConverter_ExtJs(); } export = ExtJsConverter; } else { if (ClrConverter == null) { ClrConverter = new MemberConverter_Clr(); } export = ClrConverter; } OnConfigureMemberConverter(export); return(export); }
void TransformIntoBaseMethodCallIfNeeded(CSharpInvocationResolveResult res, JsInvocationExpression node2) { var target = res.TargetResult as ThisResolveResult; if (target != null && target.CausesNonVirtualInvocation) //base. { //var info = res.GetInfo(); //var node = info.Nodes.FirstOrDefault(); var ce = target.Type;// node.FindThisEntity(); if (ce != null && Sk.IsExtJsType(ce.GetDefinitionOrArrayType())) { node2.Member = Js.This().Member("callParent"); if (node2.Arguments.IsNotNullOrEmpty()) { node2.Arguments = new List <JsExpression> { Js.NewJsonArray(node2.Arguments.ToArray()) } } ; //var me2 = (node2.Member as JsMemberExpression); //me2.Name = "callParent"; return; } IMethod me2; var me = res.Member; if (me is IProperty) { me2 = ((IProperty)me).Getter; } else if (me is IMethod) { me2 = (IMethod)res.Member; } else { throw new Exception("Can't resolve method from member: " + res.Member); } var member = SkJs.EntityMethodToJsFunctionRef(me2); member = member.Member("call"); node2.Member = member; if (node2.Arguments == null) { node2.Arguments = new List <JsExpression>(); } node2.Arguments.Insert(0, Js.This()); } } void ProcessByRefs1() { ByRefs = new List <ByReferenceResolveResult>(); ByRefIndexes = new List <int>(); RefToRefs = new List <int>(); var c = 0; foreach (var bin in PrmBindings) { var binding = bin.Binding; var byRef = binding.CallResult as ByReferenceResolveResult; if (byRef == null) { c++; continue; } var x = byRef.ElementResult as LocalResolveResult; if (x != null && x.Variable != null && x.Variable.Type.Kind == TypeKind.ByReference) { if (binding.Parameter.IsRef || binding.Parameter.IsOut) { RefToRefs.Add(c); } c++; continue; } ByRefs.Add(byRef); ByRefIndexes.Add(c); c++; } } void ProcessByRefs2() { var c = 0; for (var i = 0; i < Node2.Arguments.Count; i++) { if (Node2.Arguments[i] is JsMemberExpression) { JsMemberExpression jsmex = Node2.Arguments[i] as JsMemberExpression; if (RefToRefs.Contains(i)) { Node2.Arguments[i] = jsmex.PreviousMember; //remove the .Value ref wrapper } else if (ByRefIndexes.Contains(i)) { Node2.Arguments[i] = Js.Member(RefIndexToName(c)); c++; } } else if (Node2.Arguments[i] is JsIndexerAccessExpression) { if (ByRefIndexes.Contains(i)) { Node2.Arguments[i] = Js.Member(RefIndexToName(c)); c++; } } } } void ProcessByRefs3() { if (ByRefs.IsNotNullOrEmpty()) { var func = Js.Function(); //It must assigned to a temporary variable, because typed arrays do not acceppt json. //调整原来使用临时对象.Value的赋值方式,修改为Object.defineProperty定义get|set方法的实现 //临时对象统一调用jsclr里的$Ref方法进行创建 for (var i = 0; i < ByRefs.Count; i++) { var byRef = ByRefs[i]; var expr = VisitExpression(byRef); if (expr is JsMemberExpression) { var memberExpr = expr as JsMemberExpression; if (memberExpr.PreviousMember != null) { var refFuncInvoke = new JsInvocationExpression { Member = new JsMemberExpression { Name = "$Ref" }, Arguments = new List <JsExpression> { memberExpr.PreviousMember, Js.String(memberExpr.Name) } }; func.Add(Js.Var(RefIndexToName(i), refFuncInvoke).Statement()); } else { //如果是局部变量的话使用旧实现方式 var refFuncInvoke = new JsInvocationExpression { Member = new JsMemberExpression { Name = "$Ref" }, Arguments = new List <JsExpression> { Js.Member("null"), memberExpr } }; func.Add(Js.Var(RefIndexToName(i), refFuncInvoke).Statement()); } } else if (expr is JsIndexerAccessExpression) { var indexerExpr = expr as JsIndexerAccessExpression; var indexArg = indexerExpr.Arguments[0]; var refFuncInvoke = new JsInvocationExpression { Member = new JsMemberExpression { Name = "$Ref" }, Arguments = new List <JsExpression> { indexerExpr.Member, indexArg } }; func.Add(Js.Var(RefIndexToName(i), refFuncInvoke).Statement()); } } func.Add(Js.Var("$res", Node2).Statement()); for (var i = 0; i < ByRefs.Count; i++) { var byRef = ByRefs[i]; var memberExpr = VisitExpression(byRef) as JsMemberExpression; if (memberExpr != null && memberExpr.PreviousMember == null) { func.Add(memberExpr.Assign(Js.Member(RefIndexToName(i)).Member("Value")).Statement()); } } func.Add(Js.Return(Js.Member("$res"))); Node2 = Importer.WrapFunctionAndInvoke(Res, func); } }
protected JsBlock ExportConstructorBody(IMethod ctor) { var ctorNode = (ConstructorDeclaration)ctor.GetDeclaration(); BlockStatement ccc = null; if (ctorNode != null) { ccc = ctorNode.Body; } //var ccc = ctor.GetDefinition();//.decl as CsConstructor; //var ccc = ctor.GetDefinition(); var block2 = (JsBlock)AstNodeConverter.Visit(ccc); if (block2 == null) { block2 = new JsBlock { Statements = new List <JsStatement>() } } ; var ce = ctor.GetDeclaringTypeDefinition(); var isClr = Sk.IsClrType(ce); var isPrototype = Sk.IsNativeType(ce); var statements = new List <JsStatement>(); //instance fields initializations if (!Sk.InlineFields(ce)) { var isGlobal = Sk.IsGlobalType(ce); var fields = GetExportedDeclaredAndGeneratedFields(ce, ctor.IsStatic); //var fields = ctor.GetDeclaringTypeDefinition().GetFields(null, GetMemberOptions.IgnoreInheritedMembers).Where(t => t.IsStatic() == ctor.IsStatic).ToList(); //fields = fields.Where(ShouldExportField).ToList(); //fields.AddRange(GeneratePropertyFields(ctor.DeclaringTypeDefinition, ctor.IsStatic)); //var props = ctor.GetDeclaringTypeDefinition().GetProperties(null, GetMemberOptions.IgnoreInheritedMembers).Where(t => t.IsStatic() == ctor.IsStatic).ToList(); //props = props.Where(t=>Sk.IsNativeField(t)).ToList(); //props = props.Where(t => Sk.IsJsExported(t)).ToList(); //var fieldsAndProperties = fields.Cast<IEntity>().Concat(props.Cast<IEntity>()); var initializers = fields.Select(fe => ExportInitializer(fe, null, isGlobal, false)).Cast <JsStatement>().ToList(); if (initializers.Contains(null)) { Log.Warn("Some field initializers were not exported"); } statements.AddRange(initializers.Where(t => t != null)); } if (!ctor.IsStatic) { //base/this ctor invocation var invocation = GetConstructorBaseOrThisInvocation2(ctor); if (invocation != null) { var baseThisCe = invocation.Member.DeclaringType; var isBaseClr = Sk.IsClrType(baseThisCe.GetDefinition()); var isBasePrototype = Sk.IsNativeType(baseThisCe.GetDefinition()) && !Sk.IsJsonMode(baseThisCe.GetDefinition()) && !Sk.IsGlobalType(baseThisCe.GetDefinition()); //happens when prototype inherits from json if (isBaseClr == isClr && isBasePrototype == isPrototype) //base and derived are both prototype, or both are clr { var newObjExp2 = AstNodeConverter.VisitExpression(invocation); JsInvocationExpression invocation2; if (newObjExp2 is JsNewObjectExpression) { var newObjExp = (JsNewObjectExpression)newObjExp2; invocation2 = newObjExp.Invocation; } else if (newObjExp2 is JsInvocationExpression) { invocation2 = (JsInvocationExpression)newObjExp2; } else { throw new Exception("Unexpected node: " + newObjExp2); } if (Sk.IsExtJsType(ce)) { var invocation3 = Js.This().Member("callParent").Invoke(); if (invocation2.Arguments.IsNotNullOrEmpty()) { invocation3.Arguments = new List <JsExpression> { Js.NewJsonArray(invocation2.Arguments.NotNull().ToArray()) } } ; statements.Add(invocation3.Statement()); } else { JsRefactorer.ToCallWithContext(invocation2, new JsThis()); statements.Add(invocation2.Statement()); } } } } if (block2.Statements == null) { block2.Statements = new List <JsStatement>(); } block2.Statements.InsertRange(0, statements); return(block2); } void ExportConstructorParameters(IMethod ctor, JsFunction func) { var ce = ctor.GetDeclaringTypeDefinition(); var list = new List <string>(); if (!Sk.IgnoreTypeArguments(ce)) { //danel var gprms = ce.TypeParameters.ToList();//.GetGenericArguments().Where(ga => ga.isGenericParam()).ToList(); if (gprms.IsNotNullOrEmpty()) { var i = 0; foreach (var gprm in gprms) { func.Parameters.Add(gprm.Name); if (!ctor.IsStatic && func.Block != null) { func.Block.Statements.Insert(i, Js.This().Member(gprm.Name).Assign(Js.Member(gprm.Name)).Statement()); i++; } } } } var prms = ctor.Parameters; if (prms != null) { func.Parameters.AddRange(prms.Select(t => t.Name)); } }