//InvocationExpression GetConstructorBaseOrThisInvocation(IMethod ctor) //{ // var ctorNode = (ConstructorDeclaration)ctor.GetDeclaration(); // InvocationExpression node = null; // if (ctorNode != null && ctorNode.Initializer != null && !ctorNode.Initializer.IsNull) // { // var xxx = (CSharpInvocationResolveResult)ctorNode.Initializer.Resolve(); // //throw new NotImplementedException(); // //danel // var baseCtor = xxx.Member; // var id = new IdentifierExpression(baseCtor.Name); // id.SetResolveResult(new MemberResolveResult(null, baseCtor)); // node = new InvocationExpression(id); // node.SetResolveResult(xxx); // //{ entity = ctorNode.invoked_method, Target = ctorNode.invoked_method.Access() }; // //node.SetResolveResult( // // node.Arguments.AddRange(ctorNode.Initializer.Arguments); // } // else // { // var ce = ctor.GetDeclaringTypeDefinition(); // if (Sk.OmitInheritance(ce)) // return null; // var baseType = GetBaseClassIfValid(ce, true); // if (baseType != null) // { // var baseCtor = baseType.GetConstructor(); // if (baseCtor != null) // { // //danel // //throw new NotImplementedException(); // var id = new IdentifierExpression(baseCtor.Name); // id.SetResolveResult(new MemberResolveResult(null, baseCtor)); // node = new InvocationExpression(id);// { entity = baseCtor, expression = baseCtor.Access() }; // node.SetResolveResult(new CSharpInvocationResolveResult(null, baseCtor, null)); // } // } // } // return node; //} InvocationResolveResult GetConstructorBaseOrThisInvocation2(IMethod ctor) { var ctorNode = (ConstructorDeclaration)ctor.GetDeclaration(); InvocationResolveResult node = null; if (ctorNode != null && ctorNode.Initializer != null && !ctorNode.Initializer.IsNull) { var xxx = (CSharpInvocationResolveResult)ctorNode.Initializer.Resolve(); return(xxx); } else { var ce = ctor.GetDeclaringTypeDefinition(); if (Sk.OmitInheritance(ce)) { return(null); } var baseType = GetBaseClassIfValid(ce, true); if (baseType != null) { var baseCtor = baseType.GetConstructors(t => t.Parameters.Count == 0, GetMemberOptions.IgnoreInheritedMembers).Where(t => !t.IsStatic).FirstOrDefault(); if (baseCtor != null) { return(baseCtor.AccessSelf().Invoke()); } } } return(node); }
private List <JsClrAttribute> ExportAttributes(IEntity parent, IList <IAttribute> attributes) { var list = new List <JsClrAttribute>(); if (attributes == null || attributes.Count == 0) { return(list); } var list2 = attributes.Where(t => { { var attCtor = t.Constructor; if (attCtor == null) { Log.Warn(t.GetParent(), "Cannot resolve attribute constructor"); return(false); } var attType = attCtor.GetDeclaringTypeDefinition(); if (!Sk.IsJsExported(attType)) { return(false); } } return(true); }).ToList(); if (list2.Count > 0) { list.AddRange(list2.Select(t => ExportAttribute(parent, t))); } return(list); }
protected bool ShouldExportProperty(IProperty pe) { if (pe.IsIndexer) { return(!pe.IsExplicitInterfaceImplementation); } if (pe.IsExplicitInterfaceImplementation) { return(false); } var att = pe.GetMetadata <JsPropertyAttribute>(); if (att != null && !att.Export) { return(false); } if (Sk.IsNativeField(pe)) { return(false); } //{ // if (Sk.InlineFields(pe.GetDeclaringTypeDefinition())) // return true; // return false; //} return(true); }
protected IEnumerable <IMember> GetExportedDeclaredAndGeneratedFields(ITypeDefinition ce, bool isStatic) { foreach (var pe in ce.GetFields(t => t.IsStatic == isStatic, GetMemberOptions.IgnoreInheritedMembers)) { if (!Sk.IsJsExported(pe)) { continue; } yield return(pe); } foreach (var pe in ce.GetEvents(t => t.IsStatic == isStatic, GetMemberOptions.IgnoreInheritedMembers)) { if (!Sk.IsJsExported(pe)) { continue; } yield return(pe); } foreach (var fe in GeneratePropertyFields(ce, isStatic)) { yield return(fe); } }
void ProcessNativeParams() { if (Sk.IsNativeParams(Method)) { var binding = PrmBindings.Where(t => t.Binding.Parameter.IsParams).FirstOrDefault(); if (binding != null) { if (binding.Binding.CallResult is ArrayCreateResolveResult) { var arrayRes = (ArrayCreateResolveResult)binding.Binding.CallResult; PrmBindings.Remove(binding); if (arrayRes.InitializerElements.IsNotNullOrEmpty()) { foreach (var init in arrayRes.InitializerElements) { var b = binding.Binding.Clone(); b.CallResult = init; PrmBindings.Add(new PrmBinding { Binding = b, JsCallResult = binding.JsCallResult }); } } } else { Importer.Log.Warn(Res.GetFirstNode(), "Invalid params parameter passed to method with NativeParams=true"); } } } }
public override JsNode ExportMethod(IMethod me) { if (Sk.IsGlobalMethod(me)) { return(CreateGlobalMemberConverter().ExportMethod(me)); } var node = base.ExportMethod(me); if (node == null) { return(node); } if (!node.Is(JsNodeType.Function)) { return(node); } var func = (JsFunction)node; func.Name = null; var ce = me.GetDeclaringTypeDefinition(); var member = ExportTypePrefix(ce, me.IsStatic); member = member.Member(SkJs.GetEntityJsName(me)); if (LongFunctionNames) { func.Name = SkJs.GetLongFunctionName(me); } var st = member.Assign(func).Statement(); return(st); }
protected JsJsonObjectExpression VisitEnumToJson(ITypeDefinition ce) { bool valuesAsNames; Sk.UseJsonEnums(ce, out valuesAsNames); //var valuesAsNames = att != null && att.ValuesAsNames; var constants = ce.GetConstants().ToList(); if (!valuesAsNames && constants.Where(t => t.ConstantValue == null).FirstOrDefault() != null) { var value = 0L; foreach (var c in constants) { if (c.ConstantValue == null) { c.SetConstantValue(value); } else { value = Convert.ToInt64(c.ConstantValue); } value++; } } constants.RemoveAll(t => !Sk.IsJsExported(t)); var json = new JsJsonObjectExpression { NamesValues = new List <JsJsonNameValue>() }; json.NamesValues.AddRange(constants.Select(t => VisitEnumField(t, valuesAsNames))); return(json); }
protected List <IMethod> GetAccessorsToExport(IProperty pe) { var list = new List <IMethod>(); if (pe.IsAutomaticProperty() && !Sk.IsNativeField(pe)) { list.Add(pe.Getter); list.Add(pe.Setter); } else { var exportGetter = (pe.Getter != null && !pe.Getter.GetDeclarationBody().IsNull); var exportSetter = (pe.Setter != null && !pe.Setter.GetDeclarationBody().IsNull); if (exportGetter) { list.Add(pe.Getter); } if (exportSetter) { list.Add(pe.Setter); } } list.RemoveAll(t => !Sk.IsJsExported(t)); return(list); }
public JsNode VisitCSharpInvocationResolveResult(CSharpInvocationResolveResult res) { if (res.Member.IsConstructor()) { if (res.Type is AnonymousType) { //TODO: check context class JsType.NativeJsons var json = InitializersToJson(res.InitializerStatements, res.Type); var parentType = res.GetParentType(); if (parentType != null && !Sk.UseNativeJsons(parentType)) { return(Js.Member("$CreateAnonymousObject").Invoke(json)); } return(json); } else { return(VisitInvocationResolveResultAsCtor(res)); } } else { return(VisitInvocationResolveResult(res)); } }
public JsNode VisitNamedExpression(NamedExpression node) { var name = new JsJsonMember { Name = node.Name }; if (name.Name.IsNullOrEmpty()) { throw new NotImplementedException(); //if (d.expression.e == cs_node.n_simple_name) // name.Name = ((CsSimpleName)d.expression).identifier.identifier; //else if (d.expression.e == cs_node.n_primary_expression_member_access) // name.Name = ((CsPrimaryExpressionMemberAccess)d.expression).identifier.identifier; } var value = VisitExpression(node.Expression); var ce = node.GetParentType(); var nativeJson = Sk.UseNativeJsons(ce.GetDefinitionOrArrayType()); if (!nativeJson) { name.Name = "get_" + name.Name; value = new JsFunction { Block = new JsBlock { Statements = new List <JsStatement> { new JsReturnStatement { Expression = value } } } }; } return(new JsJsonNameValue { Name = name, Value = value }); }
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); }
JsMemberExpression ExportTypePrefix(ITypeDefinition ce, bool isStatic) { var me = Js.Members(GetJsTypeName(ce)); if (!isStatic) { me = me.MemberOrSelf(Sk.GetPrototypeName(ce)); } return(me); }
private JsNode Unary(OperatorResolveResult res) { if (res.UserDefinedOperatorMethod != null && !Sk.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition)) { var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0]); return(Visit(fake)); } var isProperty = false; var meRes = res.Operands[0] as MemberResolveResult; if (meRes != null && meRes.Member != null && IsEntityFunctionProperty(meRes.Member, res)) { isProperty = true; } JsExpression node2; if (res.OperatorType.IsAny(ExpressionType.Negate, ExpressionType.PreDecrementAssign, ExpressionType.PreIncrementAssign, ExpressionType.Not, ExpressionType.OnesComplement)) { var simpler = res.OperatorType.ExtractCompoundAssignment(); if (isProperty && simpler != null) { var fakeCs = meRes.ShallowClone().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type); node2 = VisitExpression(fakeCs); } else { node2 = new JsPreUnaryExpression { Operator = Visit(res.OperatorType), Right = VisitExpression(res.Operands[0]) }; } } else if (res.OperatorType.IsAny(ExpressionType.PostIncrementAssign, ExpressionType.PostDecrementAssign, ExpressionType.PreIncrementAssign, ExpressionType.PreDecrementAssign)) { if (isProperty) { var simpler = res.OperatorType.ExtractCompoundAssignment(); var fakeCs = meRes.ShallowClone().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type); node2 = VisitExpression(fakeCs); } else { node2 = new JsPostUnaryExpression { Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]) }; } } else { throw new NotImplementedException(); } return(node2); }
bool IsNonStatic(IEntity me) { if (!me.IsStatic()) { return(true); } if (me is IMethod && Sk.ExtensionImplementedInInstance((IMethod)me)) { return(true); } return(false); }
void ProcessPrmBindings() { var list = Res.GetArgumentsForCall2(); PrmBindings = list.Select(t => new PrmBinding { Binding = t }).ToList(); if (Sk.OmitOptionalParameters(Method)) { PrmBindings.RemoveAll(t => t.Binding.ArgResult == null); } }
JsIndexerAccessExpression ProcessIndexer() { if (Res.Member.SymbolKind == SymbolKind.Indexer && Sk.UseNativeIndexer((IProperty)Res.Member)) { var node3 = new JsIndexerAccessExpression { Member = Node2.Member, Arguments = Node2.Arguments, }; return(node3); } return(null); }
protected bool ShouldExportConstructor(IMethod ctor) { var att = ctor.GetMetadata <JsMethodAttribute>(); if (att != null && !att.Export) { return(false); } if (ctor.IsGenerated(Compiler.Project) && Sk.OmitDefaultConstructor(ctor.GetDeclaringTypeDefinition())) { return(false); } return(true); }
/// <summary> /// Returns base type of a type, only if base type is Clr or Prototype /// </summary> /// <param name="ce"></param> /// <returns></returns> protected virtual IType GetBaseClassIfValid(ITypeDefinition ce, bool recursive) { var baseClass = ce.GetBaseType(); while (baseClass != null) { if (Sk.IsClrType(baseClass.GetDefinition()) || (Sk.IsNativeType(baseClass.GetDefinition()) && !Sk.IsGlobalType(baseClass.GetDefinition())) || !recursive) { return(baseClass); } baseClass = baseClass.GetBaseType(); } return(null); }
protected List <string> ExportMethodParameters(IMethod me) { var list = new List <string>(); if (!Sk.IgnoreGenericMethodArguments(me) && me.GetGenericArguments().Count() > 0) { list.AddRange(me.GetGenericArguments().Select(t => t.Name)); } //if (me.Parameters.Where(t => t.IsOut || t.IsRef).FirstOrDefault() != null) //{ // throw new CompilerException(me, "Out and ref parameters are not supported"); //} list.AddRange(me.Parameters.Select(t => t.Name)); return(list); }
void ProcessMember() { Member = Res.Member; Method = Member as IMethod; if (Method == null) { Property = Member as IProperty; if (Property != null) { Method = Property.Getter; Member = Method; } } MethodAtt = Method != null?Sk.GetJsMethodAttribute(Method) : null; }
public void Process() { List <ITypeDefinition> allTypesToExport = GetAllTypesToExport(); var byFile = allTypesToExport.GroupBy(ce => Compiler.PathMerger.ConvertRelativePath(Sk.GetExportPath(ce))).ToDictionary(); byFile.ForEach(t => SortByNativeInheritance(t.Value)); foreach (var f in byFile) { var customOrder = f.Value.Where(t => GetOrderInFile(t) != 0).ToList(); if (customOrder.Count > 0) { f.Value.RemoveAll(t => customOrder.Contains(t)); customOrder.Sort((x, y) => GetOrderInFile(x) - GetOrderInFile(y)); f.Value.InsertRange(0, customOrder.Where(t => GetOrderInFile(t) < 0)); f.Value.AddRange(customOrder.Where(t => GetOrderInFile(t) > 0)); } } //sort types by OrderInFile if needed: //byFile.Where(k => k.Value.Where(t => GetOrderInFile(t) != 0).FirstOrDefault() != null).ForEach(t => t.Value.Sort((x, y) => GetOrderInFile(x) - GetOrderInFile(y))); var byFile2 = new Dictionary <JsFile, List <ITypeDefinition> >(); foreach (var pair in byFile) { var file = new JsFile { Filename = pair.Key, Units = new List <JsUnit> { new JsUnit { Statements = new List <JsStatement>() } } }; byFile2.Add(file, pair.Value); } if (BeforeExportTypes != null) { BeforeExportTypes(byFile2); } //export by filenames and order byFile2.ForEachParallel(ExportTypesInFile); JsFiles = byFile2.Keys.ToList(); if (Sk.ExportTsHeaders(Compiler.Project.Compilation)) { ExportTsHeaders(allTypesToExport); } }
public override JsNode _Visit(IProperty pe) { var list = GetAccessorsToExport(pe); if (Sk.IsNativeProperty(pe)) { var statements = new List <JsStatement>(); statements.AddRange(list.Select(ExportMethod).Cast <JsStatement>()); var json = new JsJsonObjectExpression(); foreach (var accessor in list) { if (accessor == pe.Getter) { json.Add("get", ExportTypePrefix(pe.Getter.GetDeclaringTypeDefinition(), pe.IsStatic).Member("get_" + pe.Name)); } if (accessor == pe.Setter) { json.Add("set", ExportTypePrefix(pe.Setter.GetDeclaringTypeDefinition(), pe.IsStatic).Member("set_" + pe.Name)); } } if (Sk.IsNativePropertyEnumerable(pe)) { json.Add("enumerable", Js.True()); } var defineStatement = Js.Member("Object").Member("defineProperty").Invoke( ExportTypePrefix(pe.GetDeclaringTypeDefinition(), pe.IsStatic), Js.String(pe.Name), json).Statement(); statements.Add(defineStatement); return(new JsUnit() { Statements = statements }); } else { var list2 = list.Select(ExportMethod).Cast <JsStatement>().ToList(); return(new JsUnit { Statements = list2 }); } }
JsMode GetJsMode(ITypeDefinition ce) { var isGlobal = Sk.IsGlobalType(ce); if (isGlobal) { return(JsMode.Global); } var isNative = Sk.IsNativeType(ce); if (isNative) { return(JsMode.Prototype); } return(JsMode.Clr); }
public List <IMember> GetMembersToExport(ITypeDefinition ce) { var members = ce.Members.Where(t => ShouldExportMember(t)).ToList(); var fields = GeneratePropertyFields(ce, true).Concat(GeneratePropertyFields(ce, false)); members = members.Concat(fields).ToList(); var ctor = ce.Members.Where(t => t.SymbolKind == SymbolKind.Constructor && !t.IsStatic).FirstOrDefault(); if (ctor == null && !Sk.OmitDefaultConstructor(ce)) { ctor = GenerateDefaultConstructor(ce); if (ctor != null) { members.Add(ctor); } } if (ctor != null && members.Contains(ctor)) { var ctorIndex = 0; if (members.IndexOf(ctor) != ctorIndex) { members.Remove(ctor); members.Insert(ctorIndex, ctor); } } var inlineFields = Sk.InlineFields(ce); if (!inlineFields) { var vars = members.Where(t => t.SymbolKind == SymbolKind.Field).Cast <IField>(); if (vars.Where(t => t.IsStatic()).FirstOrDefault() != null) { var cctor = ce.GetConstructors(false, true).FirstOrDefault(); if (cctor == null) { cctor = CreateStaticCtor(ce); members.Insert(1, cctor); } } members.RemoveAll(t => t.SymbolKind == SymbolKind.Field); } return(members); }
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); }
void ProcessGenericMethodArgs() { GenericArgs = new List <GenericArg>(); if (Method != null && Method is SpecializedMethod && !Sk.IgnoreGenericMethodArguments(Method)) { if (Method.IsConstructor) { var ce = Method.DeclaringType as ParameterizedType; if (ce != null) { GenericArgs.AddRange(ce.TypeArguments.Select(t => new GenericArg { JsExpression = SkJs.EntityTypeRefToMember(t, true), Arg = t }).ToList()); } } else { var sme = (SpecializedMethod)Method; var genericMethodArgs = sme.TypeArguments.Select(t => new GenericArg { JsExpression = SkJs.EntityTypeRefToMember(t, true), Arg = t }).ToList(); var i = 0; foreach (var z in Method.TypeParameters) { if (i >= genericMethodArgs.Count) { continue; } genericMethodArgs[i].TypeParam = z; i++; } GenericArgs.AddRange(genericMethodArgs); } var jsArgs = GenericArgs.Select(t => t.JsExpression).ToList(); if (Node2.Arguments == null) { Node2.Arguments = new List <JsExpression>(jsArgs); } else { Node2.Arguments.InsertRange(0, jsArgs); } } }
public JsNode VisitThrowStatement(ThrowStatement node) { JsExpression node2; IType exceptionType; if (node.Expression == null || node.Expression.IsNull) //happens when performing "throw;" { var cc = node.GetParent <CatchClause>(); if (cc != null) { node2 = Js.Member(cc.VariableName); var type = cc.Type; if (type == null || type.IsNull) { exceptionType = Project.Compilation.FindType(KnownTypeCode.Exception); } else { exceptionType = cc.Type.Resolve().Type; } } else { throw new Exception("Rethrow not supported, catch clause not found"); } } else { node2 = VisitExpression(node.Expression); var res = node.Expression.Resolve(); exceptionType = res.Type; if (res is ConversionResolveResult) { exceptionType = ((ConversionResolveResult)res).Input.Type; } } if (!Sk.IsNativeError(exceptionType.GetDefinitionOrArrayType())) { node2 = Js.Member("$CreateException").Invoke(node2, Js.New(Js.Member("Error"))); } return(new JsThrowStatement { Expression = node2 }); }
public virtual JsNode ExportMethod(IMethod me) { var jma = Sk.GetJsMethodAttribute(me); if (jma != null && jma.GlobalCode) { var block = ExportMethodBody(me); return(new JsUnit { Statements = block.Statements }); } var func = new JsFunction(); func.Parameters = ExportMethodParameters(me); func.Name = SkJs.GetEntityJsName(me); func.Block = ExportMethodBody(me); func = ApplyYield(func); return(func); }
void SortByNativeInheritance(List <ITypeDefinition> list) { var list2 = list.Where(t => Sk.IsNativeType(t) && t.GetBaseTypeDefinition() != null && Sk.IsNativeType(t.GetBaseTypeDefinition())).ToList(); foreach (var ce in list2) { var ce3 = ce; while (true) { var baseCe = ce3.GetBaseTypeDefinition(); if (baseCe == null) { break; } MoveBefore(list, ce3, baseCe); ce3 = baseCe; } } }
public override JsNode _Visit(IProperty pe) { if (Sk.IsNativeField(pe)) { if (Sk.InlineFields(pe.GetDeclaringTypeDefinition())) { var fe = GenerateFakeField(pe); var value = AstNodeConverter.Visit(GetCreateInitializer(fe)); return(Js.JsonNameValue(pe.Name, (JsExpression)value)); } throw new Exception(); } else { var list2 = new JsNodeList { Nodes = new List <JsNode>() }; var node2 = ExportPropertyInfo(pe); if (node2 != null) { list2.Nodes.Add(node2); } var list = GetAccessorsToExport(pe); if (list.Count > 0) { foreach (var accessor in list) { var pair = (JsJsonNameValue)ExportMethod(accessor); list2.Nodes.Add(pair); } } //else if (pe.IsAutomaticProperty()) //{ // throw new NotImplementedException(); // //var def = CurrentType.GetDefinition(pe.IsStatic); // var getter = Js.Code(String.Format("function(){{return this._{0};}}", pe.Name)); ; // var setter = Js.Code(String.Format("function(value){{this._{0} = value;}}", pe.Name)); // list2.Nodes.Add(new JsJsonNameValue { Name = new JsJsonMember { Name = SkJs.GetEntityJsName(pe.Getter) }, Value = getter }); // list2.Nodes.Add(new JsJsonNameValue { Name = new JsJsonMember { Name = SkJs.GetEntityJsName(pe.Setter) }, Value = setter }); //} return(list2); } }