protected virtual void EmitCtorForInstantiableClass() { var typeDef = this.Emitter.GetTypeDefinition(); string name = this.Emitter.Validator.GetCustomTypeName(typeDef, this.Emitter, true, false); if (name.IsEmpty()) { name = BridgeTypes.ToTypeScriptName(this.TypeInfo.Type, this.Emitter, false, true); } if (this.TypeInfo.Ctors.Count == 0) { this.Write("new "); this.WriteOpenCloseParentheses(); this.WriteColon(); this.Write(name); this.WriteSemiColon(); this.WriteNewLine(); } else if (this.TypeInfo.Ctors.Count == 1) { var ctor = this.TypeInfo.Ctors.First(); if (!ctor.HasModifier(Modifiers.Public)) { return; } XmlToJsDoc.EmitComment(this, ctor); this.Write("new "); this.EmitMethodParameters(ctor.Parameters, ctor); this.WriteColon(); this.Write(name); this.WriteSemiColon(); this.WriteNewLine(); } else { foreach (var ctor in this.TypeInfo.Ctors) { if (!ctor.HasModifier(Modifiers.Public)) { continue; } if (ctor.Parameters.Count == 0) { XmlToJsDoc.EmitComment(this, ctor); this.Write("new ()"); this.WriteColon(); this.Write(name); this.WriteSemiColon(); this.WriteNewLine(); } XmlToJsDoc.EmitComment(this, ctor); var ctorName = JS.Funcs.CONSTRUCTOR; if (this.TypeInfo.Ctors.Count > 1 && ctor.Parameters.Count > 0) { var overloads = OverloadsCollection.Create(this.Emitter, ctor); ctorName = overloads.GetOverloadName(); } this.Write(ctorName); this.WriteColon(); this.BeginBlock(); this.WriteNew(); this.EmitMethodParameters(ctor.Parameters, ctor); this.WriteColon(); this.Write(name); this.WriteNewLine(); this.EndBlock(); this.WriteSemiColon(); this.WriteNewLine(); } } }
public static JObject ConstructMemberInfo(IMember m, IEmitter emitter, bool includeDeclaringType, bool isGenericSpecialization, SyntaxTree tree) { if (m is IMethod && ((IMethod)m).IsConstructor) { return(MetadataUtils.ConstructConstructorInfo((IMethod)m, emitter, includeDeclaringType, isGenericSpecialization, tree)); } var properties = MetadataUtils.GetCommonMemberInfoProperties(m, emitter, includeDeclaringType, isGenericSpecialization, tree); if (m.IsStatic) { properties.Add("is", true); } if (m is IMethod) { var method = (IMethod)m; var inline = emitter.GetInline(method); if (string.IsNullOrEmpty(inline) && method.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute")) { properties.Add("exp", true); } properties.Add("t", (int)MemberTypes.Method); var parametersInfo = method.Parameters.Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("pi", new JArray(parametersInfo)); } if (!string.IsNullOrEmpty(inline)) { var isSelf = inline.StartsWith("<self>"); if (isSelf) { inline = inline.Substring(6); } if (!method.IsStatic && !isSelf && !inline.Contains("{this}")) { inline = "this." + inline; } var block = new InlineArgumentsBlock(emitter, new ArgumentsInfo(emitter, method), inline, method); var oldWriter = block.SaveWriter(); block.NewWriter(); block.EmitFunctionReference(true); var str = emitter.Output.ToString(); block.RestoreWriter(oldWriter); properties.Add("tpc", method.TypeParameters.Count); properties.Add("def", new JRaw(str)); } else { if (MetadataUtils.IsJsGeneric(method, emitter)) { properties.Add("tpc", method.TypeParameters.Count); properties.Add("tprm", new JArray(method.TypeParameters.Select(tp => tp.Name).ToArray())); } string sname; if (method.IsAccessor) { if (method.AccessorOwner is IProperty) { sname = Helpers.GetPropertyRef(method.AccessorOwner, emitter, ((IProperty)method.AccessorOwner).Setter == method); } else if (method.AccessorOwner is IEvent) { sname = Helpers.GetEventRef(method.AccessorOwner, emitter, ((IEvent)method.AccessorOwner).RemoveAccessor == method); } else { sname = OverloadsCollection.Create(emitter, method).GetOverloadName(); } } else { sname = OverloadsCollection.Create(emitter, method).GetOverloadName(); } if (sname.Contains("\"")) { properties.Add("sn", new JRaw(sname)); } else { properties.Add("sn", sname); } } properties.Add("rt", new JRaw(MetadataUtils.GetTypeName(method.ReturnType, emitter, isGenericSpecialization))); var attr = MetadataUtils.GetScriptableAttributes(method.ReturnTypeAttributes, emitter, tree).ToList(); if (attr.Count > 0) { JArray attrArr = new JArray(); foreach (var a in attr) { attrArr.Add(MetadataUtils.ConstructAttribute(a, null, emitter)); } properties.Add("rta", attrArr); } if (method.Parameters.Count > 0) { properties.Add("p", new JArray(method.Parameters.Select(p => new JRaw(MetadataUtils.GetTypeName(p.Type, emitter, isGenericSpecialization))))); } MetadataUtils.AddBox(m, emitter, properties); } else if (m is IField) { var field = (IField)m; properties.Add("t", (int)MemberTypes.Field); properties.Add("rt", new JRaw(MetadataUtils.GetTypeName(field.ReturnType, emitter, isGenericSpecialization))); properties.Add("sn", OverloadsCollection.Create(emitter, field).GetOverloadName()); if (field.IsReadOnly) { properties.Add("ro", field.IsReadOnly); } MetadataUtils.AddBox(m, emitter, properties); } else if (m is IProperty) { var typeDef = m.DeclaringTypeDefinition; var monoProp = typeDef != null?emitter.BridgeTypes.Get(typeDef).TypeDefinition.Properties.FirstOrDefault(p => p.Name == m.Name) : null; var prop = (IProperty)m; var canGet = prop.CanGet; var canSet = prop.CanSet; if (monoProp != null) { canGet = monoProp.GetMethod != null; canSet = monoProp.SetMethod != null; } properties.Add("t", (int)MemberTypes.Property); properties.Add("rt", new JRaw(MetadataUtils.GetTypeName(prop.ReturnType, emitter, isGenericSpecialization))); if (prop.Parameters.Count > 0) { properties.Add("p", new JArray(prop.Parameters.Select(p => new JRaw(MetadataUtils.GetTypeName(p.Type, emitter, isGenericSpecialization))))); } if (prop.IsIndexer) { properties.Add("i", true); } if (prop.IsIndexer) { if (prop.Getter != null) { var parametersInfo = prop.Getter.Parameters.Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("ipi", new JArray(parametersInfo)); } } else if (prop.Setter != null) { var parametersInfo = prop.Setter.Parameters.Take(prop.Setter.Parameters.Count - 1).Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("ipi", new JArray(parametersInfo)); } } } var inlineGetter = canGet && (emitter.GetInline(prop.Getter) != null || Helpers.IsScript(prop.Getter)); var inlineSetter = canSet && (emitter.GetInline(prop.Setter) != null || Helpers.IsScript(prop.Setter)); if (inlineGetter || inlineSetter || prop.IsIndexer) { if (canGet) { properties.Add("g", MetadataUtils.ConstructMemberInfo(prop.Getter, emitter, includeDeclaringType, isGenericSpecialization, tree)); } if (canSet) { properties.Add("s", MetadataUtils.ConstructMemberInfo(prop.Setter, emitter, includeDeclaringType, isGenericSpecialization, tree)); } } else { var fieldName = OverloadsCollection.Create(emitter, prop).GetOverloadName(); if (canGet) { properties.Add("g", MetadataUtils.ConstructFieldPropertyAccessor(prop.Getter, emitter, fieldName, true, includeDeclaringType, isGenericSpecialization, tree)); } if (canSet) { properties.Add("s", MetadataUtils.ConstructFieldPropertyAccessor(prop.Setter, emitter, fieldName, false, includeDeclaringType, isGenericSpecialization, tree)); } properties.Add("fn", fieldName); } } else if (m is IEvent) { var evt = (IEvent)m; properties.Add("t", (int)MemberTypes.Event); properties.Add("ad", MetadataUtils.ConstructMemberInfo(evt.AddAccessor, emitter, includeDeclaringType, isGenericSpecialization, tree)); properties.Add("r", MetadataUtils.ConstructMemberInfo(evt.RemoveAccessor, emitter, includeDeclaringType, isGenericSpecialization, tree)); } else { throw new ArgumentException("Invalid member " + m); } return(properties); }
protected virtual void EmitIndexerMethod(IndexerDeclaration indexerDeclaration, IProperty prop, Accessor accessor, IMethod propAccessor, bool setter) { var isIgnore = propAccessor != null && Emitter.Validator.IsExternalType(propAccessor); if (!accessor.IsNull && Emitter.GetInline(accessor) == null && !isIgnore) { EnsureComma(); ResetLocals(); var prevMap = BuildLocalsMap(); var prevNamesMap = BuildLocalsNamesMap(); if (setter) { AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } else { AddLocals(new ParameterDeclaration[0], accessor.Body); } XmlToJsDoc.EmitComment(this, IndexerDeclaration, !setter); string accName = null; if (prop != null) { accName = Emitter.GetEntityNameFromAttr(prop, setter); if (string.IsNullOrEmpty(accName)) { var member_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(indexerDeclaration); var overloads = OverloadsCollection.Create(Emitter, indexerDeclaration, setter); accName = overloads.GetOverloadName(false, Helpers.GetSetOrGet(setter), OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr)); } } Write(accName); WriteColon(); WriteFunction(); var nm = Helpers.GetFunctionName(Emitter.AssemblyInfo.NamedFunctions, prop, Emitter, setter); if (nm != null) { Write(nm); } EmitMethodParameters(indexerDeclaration.Parameters, null, indexerDeclaration, setter); if (setter) { Write(", value)"); } WriteSpace(); var script = Emitter.GetScript(accessor); if (script == null) { if (YieldBlock.HasYield(accessor.Body)) { new GeneratorBlock(Emitter, accessor).Emit(); } else { accessor.Body.AcceptVisitor(Emitter); } } else { BeginBlock(); WriteLines(script); EndBlock(); } ClearLocalsMap(prevMap); ClearLocalsNamesMap(prevNamesMap); Emitter.Comma = true; } }
protected virtual void WriteObjectInitializer(IEnumerable <Expression> expressions, bool preserveMemberCase, TypeDefinition type, InvocationResolveResult rr) { bool needComma = false; List <string> names = new List <string>(); if (rr != null && this.ObjectCreateExpression.Arguments.Count > 0) { var args = this.ObjectCreateExpression.Arguments.ToList(); var arrIsOpen = false; for (int i = 0; i < args.Count; i++) { Expression expression = args[i]; var p = rr.Member.Parameters[i < rr.Member.Parameters.Count ? i : (rr.Member.Parameters.Count - 1)]; var name = p.Name; if (needComma) { this.WriteComma(); } needComma = true; if (p.IsParams && !arrIsOpen) { arrIsOpen = true; this.Write("["); } this.Write(name, ": "); expression.AcceptVisitor(this.Emitter); names.Add(name); } if (arrIsOpen) { this.Write("]"); } } if (expressions != null) { foreach (Expression item in expressions) { NamedExpression namedExression = item as NamedExpression; NamedArgumentExpression namedArgumentExpression = item as NamedArgumentExpression; string name = namedExression != null ? namedExression.Name : namedArgumentExpression.Name; if (!preserveMemberCase) { name = Object.Net.Utilities.StringUtils.ToLowerCamelCase(name); } var itemrr = this.Emitter.Resolver.ResolveNode(item, this.Emitter) as MemberResolveResult; if (itemrr != null) { var oc = OverloadsCollection.Create(this.Emitter, itemrr.Member); oc.CancelChangeCase = this.Emitter.IsNativeMember(itemrr.Member.FullName) ? false : preserveMemberCase; name = oc.GetOverloadName(); } if (needComma) { this.WriteComma(); } needComma = true; Expression expression = namedExression != null ? namedExression.Expression : namedArgumentExpression.Expression; this.Write(name, ": "); expression.AcceptVisitor(this.Emitter); names.Add(name); } } if (this.Emitter.Validator.IsObjectLiteral(type)) { var key = BridgeTypes.GetTypeDefinitionKey(type); var tinfo = this.Emitter.Types.FirstOrDefault(t => t.Key == key); if (tinfo == null) { return; } var itype = tinfo.Type as ITypeDefinition; var mode = 0; if (rr != null) { if (rr.Member.Parameters.Count == 1 && rr.Member.Parameters.First().Type.FullName == "Bridge.DefaultValueMode") { var arg = rr.Arguments.FirstOrDefault(); if (arg != null && arg.ConstantValue != null) { mode = (int)arg.ConstantValue; } } else if (itype != null) { var attr = this.Emitter.Validator.GetAttribute(itype.Attributes, Translator.Bridge_ASSEMBLY + ".ObjectLiteralAttribute"); if (attr.PositionalArguments.Count > 0) { var value = attr.PositionalArguments.First().ConstantValue; if (value != null && value is int) { mode = (int)value; } } } } if (mode != 0) { var members = tinfo.InstanceConfig.Fields.Concat(tinfo.InstanceConfig.Properties); if (members.Any()) { foreach (var member in members) { if (mode == 1 && (member.VarInitializer == null || member.VarInitializer.Initializer.IsNull)) { continue; } var name = member.GetName(this.Emitter); if (!preserveMemberCase) { name = Object.Net.Utilities.StringUtils.ToLowerCamelCase(name); } if (names.Contains(name)) { continue; } if (needComma) { this.WriteComma(); } needComma = true; this.Write(name, ": "); var primitiveExpr = member.Initializer as PrimitiveExpression; if (primitiveExpr != null && primitiveExpr.Value is AstType) { this.Write(Inspector.GetStructDefaultValue((AstType)primitiveExpr.Value, this.Emitter)); } else { member.Initializer.AcceptVisitor(this.Emitter); } } } } } }
protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { foreach (var attrSection in methodDeclaration.Attributes) { foreach (var attr in attrSection.Attributes) { var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter); if (rr.Type.FullName == "Bridge.InitAttribute") { int initPosition = 0; if (attr.HasArgumentList) { if (attr.Arguments.Any()) { var argExpr = attr.Arguments.First(); var argrr = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter); if (argrr.ConstantValue is int) { initPosition = (int)argrr.ConstantValue; } } } if (initPosition == 1) // Before { return; } } } } this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(methodDeclaration.Parameters, methodDeclaration.Body); var typeDef = this.Emitter.GetTypeDefinition(); var overloads = OverloadsCollection.Create(this.Emitter, methodDeclaration); XmlToJsDoc.EmitComment(this, this.MethodDeclaration); if (overloads.HasOverloads) { string name = overloads.GetOverloadName(); this.Write(name); } else { this.Write(this.Emitter.GetEntityName(methodDeclaration)); } this.WriteColon(); if (methodDeclaration.TypeParameters.Count > 0) { this.WriteFunction(); this.EmitTypeParameters(methodDeclaration.TypeParameters, methodDeclaration); this.WriteSpace(); this.BeginBlock(); this.WriteReturn(true); this.Write("Bridge.fn.bind(this, "); } this.WriteFunction(); this.EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration); this.WriteSpace(); var script = this.Emitter.GetScript(methodDeclaration); if (script == null) { if (methodDeclaration.HasModifier(Modifiers.Async)) { new AsyncBlock(this.Emitter, methodDeclaration).Emit(); } else { methodDeclaration.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); foreach (var line in script) { this.Write(line); this.WriteNewLine(); } this.EndBlock(); } if (methodDeclaration.TypeParameters.Count > 0) { this.Write(");"); this.WriteNewLine(); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; }
protected virtual void EmitBaseConstructor(ConstructorDeclaration ctor, string ctorName) { var initializer = ctor.Initializer != null && !ctor.Initializer.IsNull ? ctor.Initializer : new ConstructorInitializer() { ConstructorInitializerType = ConstructorInitializerType.Base }; bool appendScope = false; if (initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { var baseType = this.Emitter.GetBaseTypeDefinition(); var baseName = "constructor"; if (ctor.Initializer != null && !ctor.Initializer.IsNull) { var member = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member; var overloads = OverloadsCollection.Create(this.Emitter, member); if (overloads.HasOverloads) { baseName = overloads.GetOverloadName(); } } string baseTypName; if (this.TypeInfo.GetBaseTypes(this.Emitter).Any()) { baseTypName = BridgeTypes.ToJsName(this.TypeInfo.GetBaseClass(this.Emitter), this.Emitter); } else { baseTypName = BridgeTypes.ToJsName(baseType, this.Emitter); } this.Write(baseTypName); this.WriteDot(); this.Write("__ctor__"); if (IsMultiCtor(baseType)) { int ctorIndex = GetCtorIndex(baseName); this.Write('[', ctorIndex, ']'); } appendScope = true; } else { var baseName = "constructor"; var member = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member; var overloads = OverloadsCollection.Create(this.Emitter, member); if (overloads.HasOverloads) { baseName = overloads.GetOverloadName(); } this.Write(ConvertConstructorName(baseName)); appendScope = true; } this.WriteOpenParentheses(); if (appendScope) { this.WriteThis(); if (initializer.Arguments.Count > 0) { this.WriteComma(); } } var args = new List <Expression>(initializer.Arguments); for (int i = 0; i < args.Count; i++) { args[i].AcceptVisitor(this.Emitter); if (i != (args.Count - 1)) { this.WriteComma(); } } this.WriteCloseParentheses(); this.WriteSemiColon(); if (isInitExists_ && initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { this.WriteNewLine(); this.Write("__init__(this)"); } }
protected virtual void EmitBaseConstructor(ConstructorDeclaration ctor, string ctorName, bool isObjectLiteral) { var initializer = ctor.Initializer != null && !ctor.Initializer.IsNull ? ctor.Initializer : new ConstructorInitializer() { ConstructorInitializerType = ConstructorInitializerType.Base }; bool appendScope = false; if (initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { var baseType = this.Emitter.GetBaseTypeDefinition(); var baseName = JS.Funcs.CONSTRUCTOR; if (ctor.Initializer != null && !ctor.Initializer.IsNull) { var member = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member; var overloads = OverloadsCollection.Create(this.Emitter, member); if (overloads.HasOverloads) { baseName = overloads.GetOverloadName(); } } string name = null; if (this.TypeInfo.GetBaseTypes(this.Emitter).Any()) { name = BridgeTypes.ToJsName(this.TypeInfo.GetBaseClass(this.Emitter), this.Emitter); } else { name = BridgeTypes.ToJsName(baseType, this.Emitter); } this.Write(name, "."); this.Write(baseName); if (!isObjectLiteral) { this.WriteCall(); appendScope = true; } } else { // this.WriteThis(); string name = BridgeTypes.ToJsName(this.TypeInfo.Type, this.Emitter); this.Write(name); this.WriteDot(); var baseName = JS.Funcs.CONSTRUCTOR; var member = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member; var overloads = OverloadsCollection.Create(this.Emitter, member); if (overloads.HasOverloads) { baseName = overloads.GetOverloadName(); } this.Write(baseName); if (!isObjectLiteral) { this.WriteCall(); appendScope = true; } } int openPos = this.Emitter.Output.Length; this.WriteOpenParentheses(); if (appendScope) { this.WriteThis(); if (initializer.Arguments.Count > 0) { this.WriteComma(); } } if (initializer.Arguments.Count > 0) { var argsInfo = new ArgumentsInfo(this.Emitter, ctor.Initializer); var argsExpressions = argsInfo.ArgumentsExpressions; var paramsArg = argsInfo.ParamsExpression; new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, ctor.Initializer, openPos).Emit(); } this.WriteCloseParentheses(); this.WriteSemiColon(); if (!isObjectLiteral) { this.WriteNewLine(); } }
private void HandleDecimal(ResolveResult resolveOperator, bool isLong = false) { var orr = resolveOperator as OperatorResolveResult; var op = this.UnaryOperatorExpression.Operator; var oldType = this.Emitter.UnaryOperatorType; var oldAccessor = this.Emitter.IsUnaryAccessor; var typeCode = isLong ? KnownTypeCode.Int64 : KnownTypeCode.Decimal; this.Emitter.UnaryOperatorType = op; var argResolverResult = this.Emitter.Resolver.ResolveNode(this.UnaryOperatorExpression.Expression, this.Emitter); bool nullable = NullableType.IsNullable(argResolverResult.Type); bool isAccessor = false; var memberArgResolverResult = argResolverResult as MemberResolveResult; if (memberArgResolverResult != null && memberArgResolverResult.Member is IProperty) { var isIgnore = this.Emitter.Validator.IsExternalType(memberArgResolverResult.Member.DeclaringTypeDefinition); var inlineAttr = this.Emitter.GetAttribute(memberArgResolverResult.Member.Attributes, Translator.Bridge_ASSEMBLY + ".TemplateAttribute"); var ignoreAccessor = this.Emitter.Validator.IsExternalType(((IProperty)memberArgResolverResult.Member).Getter); var isAccessorsIndexer = this.Emitter.Validator.IsAccessorsIndexer(memberArgResolverResult.Member); isAccessor = ((IProperty)memberArgResolverResult.Member).IsIndexer; if (inlineAttr == null && (isIgnore || ignoreAccessor) && !isAccessorsIndexer) { isAccessor = false; } } else if (argResolverResult is ArrayAccessResolveResult) { isAccessor = ((ArrayAccessResolveResult)argResolverResult).Indexes.Count > 1; } var isOneOp = op == UnaryOperatorType.Increment || op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostIncrement || op == UnaryOperatorType.PostDecrement; if (isAccessor && isOneOp) { this.Emitter.IsUnaryAccessor = true; if (nullable) { this.Write(JS.Funcs.BRIDGE_HASVALUE); this.WriteOpenParentheses(); this.Emitter.IsUnaryAccessor = false; this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(") ? "); this.Emitter.IsUnaryAccessor = true; this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" : null)"); } else { this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); } this.Emitter.UnaryOperatorType = oldType; this.Emitter.IsUnaryAccessor = oldAccessor; return; } var method = orr != null ? orr.UserDefinedOperatorMethod : null; if (orr != null && method == null) { var name = Helpers.GetUnaryOperatorMethodName(this.UnaryOperatorExpression.Operator); var type = NullableType.IsNullable(orr.Type) ? NullableType.GetUnderlyingType(orr.Type) : orr.Type; method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); } if (orr.IsLiftedOperator) { if (!isOneOp) { this.Write(JS.Types.SYSTEM_NULLABLE + "."); } string action = JS.Funcs.Math.LIFT1; string op_name = null; switch (this.UnaryOperatorExpression.Operator) { case UnaryOperatorType.Minus: op_name = JS.Funcs.Math.NEG; break; case UnaryOperatorType.Plus: op_name = "clone"; break; case UnaryOperatorType.BitNot: op_name = "not"; break; case UnaryOperatorType.Increment: case UnaryOperatorType.Decrement: this.Write(JS.Funcs.BRIDGE_HASVALUE); this.WriteOpenParentheses(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(") ? "); this.WriteOpenParentheses(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = " + JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1 + "(\"" + (op == UnaryOperatorType.Decrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "\", "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, true); this.Write(")"); this.WriteCloseParentheses(); this.Write(" : null"); break; case UnaryOperatorType.PostIncrement: case UnaryOperatorType.PostDecrement: this.Write(JS.Funcs.BRIDGE_HASVALUE); this.WriteOpenParentheses(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(") ? "); this.WriteOpenParentheses(); var valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.WriteComma(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = " + JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1 + "(\"" + (op == UnaryOperatorType.PostDecrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "\", "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, true); this.Write(")"); this.WriteComma(); this.Write(valueVar); this.WriteCloseParentheses(); this.RemoveTempVar(valueVar); this.Write(" : null"); break; } if (!isOneOp) { this.Write(action); this.WriteOpenParentheses(); this.WriteScript(op_name); this.WriteComma(); new ExpressionListBlock(this.Emitter, new Expression[] { this.UnaryOperatorExpression.Expression }, null, null, 0).Emit(); this.AddOveflowFlag(typeCode, op_name, true); this.WriteCloseParentheses(); } } else if (method == null) { string op_name = null; var isStatement = this.UnaryOperatorExpression.Parent is ExpressionStatement; if (isStatement) { if (op == UnaryOperatorType.PostIncrement) { op = UnaryOperatorType.Increment; } else if (op == UnaryOperatorType.PostDecrement) { op = UnaryOperatorType.Decrement; } } switch (op) { case UnaryOperatorType.Minus: op_name = JS.Funcs.Math.NEG; break; case UnaryOperatorType.Plus: op_name = "clone"; break; case UnaryOperatorType.BitNot: op_name = "not"; break; case UnaryOperatorType.Increment: case UnaryOperatorType.Decrement: if (!isStatement) { this.WriteOpenParentheses(); } this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write("." + (op == UnaryOperatorType.Decrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "("); this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, false); this.Write(")"); if (!isStatement) { this.WriteCloseParentheses(); } break; case UnaryOperatorType.PostIncrement: case UnaryOperatorType.PostDecrement: this.WriteOpenParentheses(); var valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.WriteComma(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write("." + (op == UnaryOperatorType.PostDecrement ? JS.Funcs.Math.DEC : JS.Funcs.Math.INC) + "("); this.AddOveflowFlag(typeCode, JS.Funcs.Math.DEC, false); this.Write("), "); this.Write(valueVar); this.WriteCloseParentheses(); this.RemoveTempVar(valueVar); break; } if (!isOneOp) { this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.WriteDot(); this.Write(op_name); this.WriteOpenParentheses(); this.AddOveflowFlag(typeCode, op_name, false); this.WriteCloseParentheses(); } } else { var inline = this.Emitter.GetInline(method); if (!string.IsNullOrWhiteSpace(inline)) { if (isOneOp) { var isStatement = this.UnaryOperatorExpression.Parent is ExpressionStatement; if (isStatement || this.UnaryOperatorExpression.Operator == UnaryOperatorType.Increment || this.UnaryOperatorExpression.Operator == UnaryOperatorType.Decrement) { if (!isStatement) { this.WriteOpenParentheses(); } this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = "); new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit (); if (!isStatement) { this.WriteCloseParentheses(); } } else { this.WriteOpenParentheses(); var valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.WriteComma(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = "); new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit(); this.WriteComma(); this.Write(valueVar); this.WriteCloseParentheses(); this.RemoveTempVar(valueVar); } } else { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit(); } } else if (!this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition)) { this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName()); this.WriteOpenParentheses(); new ExpressionListBlock(this.Emitter, new Expression[] { this.UnaryOperatorExpression.Expression }, null, null, 0).Emit(); this.WriteCloseParentheses(); } } this.Emitter.UnaryOperatorType = oldType; }
protected virtual void EmitIndexerMethod(IndexerDeclaration indexerDeclaration, IProperty prop, Accessor accessor, IMethod propAccessor, bool setter) { var isIgnore = propAccessor != null && this.Emitter.Validator.IsExternalType(propAccessor); if (!accessor.IsNull && this.Emitter.GetInline(accessor) == null && !isIgnore) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); if (setter) { this.AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } else { this.AddLocals(new ParameterDeclaration[0], accessor.Body); } XmlToJsDoc.EmitComment(this, this.IndexerDeclaration, !setter); string accName = null; if (prop != null) { accName = this.Emitter.GetEntityNameFromAttr(prop, setter); if (string.IsNullOrEmpty(accName)) { var overloads = OverloadsCollection.Create(this.Emitter, indexerDeclaration, setter); accName = overloads.GetOverloadName(false, Helpers.GetSetOrGet(setter), true); } } this.Write(accName); this.WriteColon(); this.WriteFunction(); this.EmitMethodParameters(indexerDeclaration.Parameters, null, indexerDeclaration, setter); if (setter) { this.Write(", value)"); } this.WriteSpace(); var script = this.Emitter.GetScript(accessor); if (script == null) { if (YieldBlock.HasYield(accessor.Body)) { new GeneratorBlock(this.Emitter, accessor).Emit(); } else { accessor.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); this.WriteLines(script); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; } }
protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr) { var method = orr != null ? orr.UserDefinedOperatorMethod : null; if (method != null) { var inline = this.Emitter.GetInline(method); if (!string.IsNullOrWhiteSpace(inline)) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit(); return(true); } else if (!this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition)) { bool addClose = false; string leftInterfaceTempVar = null; if (orr.OperatorType == ExpressionType.OrElse || orr.OperatorType == ExpressionType.AndAlso) { var orElse = orr.OperatorType == ExpressionType.OrElse; var left = orr.Operands[0]; var memberTargetrr = left as MemberResolveResult; bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult); if (!(left is ThisResolveResult || left is TypeResolveResult || left is LocalResolveResult || left is ConstantResolveResult || isField)) { this.WriteOpenParentheses(); leftInterfaceTempVar = this.GetTempVarName(); this.Write(leftInterfaceTempVar); this.Write(" = "); binaryOperatorExpression.Left.AcceptVisitor(this.Emitter); this.WriteComma(); addClose = true; } var m = FindOperatorTrueOrFalse(left.Type, orElse); this.Write(BridgeTypes.ToJsName(m.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, m).GetOverloadName()); this.WriteOpenParentheses(); if (leftInterfaceTempVar != null) { this.Write(leftInterfaceTempVar); } else { binaryOperatorExpression.Left.AcceptVisitor(this.Emitter); } this.WriteCloseParentheses(); this.Write(" ? "); if (leftInterfaceTempVar != null) { this.Write(leftInterfaceTempVar); } else { binaryOperatorExpression.Left.AcceptVisitor(this.Emitter); } this.Write(" : "); } if (orr.IsLiftedOperator) { this.Write(JS.Types.SYSTEM_NULLABLE + "."); string action = JS.Funcs.Math.LIFT; switch (this.BinaryOperatorExpression.Operator) { case BinaryOperatorType.GreaterThan: action = JS.Funcs.Math.LIFTCMP; break; case BinaryOperatorType.GreaterThanOrEqual: action = JS.Funcs.Math.LIFTCMP; break; case BinaryOperatorType.Equality: action = JS.Funcs.Math.LIFTEQ; break; case BinaryOperatorType.InEquality: action = JS.Funcs.Math.LIFTNE; break; case BinaryOperatorType.LessThan: action = JS.Funcs.Math.LIFTCMP; break; case BinaryOperatorType.LessThanOrEqual: action = JS.Funcs.Math.LIFTCMP; break; } this.Write(action + "("); } this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName()); if (orr.IsLiftedOperator) { this.WriteComma(); } else { this.WriteOpenParentheses(); } if (leftInterfaceTempVar != null) { this.Write(leftInterfaceTempVar); this.Write(", "); binaryOperatorExpression.Right.AcceptVisitor(this.Emitter); } else { new ExpressionListBlock(this.Emitter, new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }, null, null, 0).Emit(); } this.WriteCloseParentheses(); if (addClose) { this.WriteCloseParentheses(); } return(true); } } return(false); }
private void HandleType(ResolveResult resolveOperator, string variable, string op_name, KnownTypeCode typeCode) { if (this.AssignmentExpression.Operator == AssignmentOperatorType.Assign) { if (variable != null) { this.Write(variable); } else { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Right }, null, null, 0).Emit(); } return; } var orr = resolveOperator as OperatorResolveResult; var method = orr != null ? orr.UserDefinedOperatorMethod : null; var assigmentType = Helpers.TypeOfAssignment(this.AssignmentExpression.Operator); if (orr != null && method == null) { var name = Helpers.GetBinaryOperatorMethodName(assigmentType); var type = NullableType.IsNullable(orr.Type) ? NullableType.GetUnderlyingType(orr.Type) : orr.Type; method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); } if (method != null) { var inline = this.Emitter.GetInline(method); if (orr.IsLiftedOperator) { this.Write(JS.Types.SYSTEM_NULLABLE + "."); string action = JS.Funcs.Math.LIFT2; this.Write(action); this.WriteOpenParentheses(); this.WriteScript(op_name); this.WriteComma(); if (variable != null) { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null, null, 0).Emit(); } else { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null, null, 0).Emit(); } this.AddOveflowFlag(typeCode, op_name); this.WriteCloseParentheses(); } else if (!string.IsNullOrWhiteSpace(inline)) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.AssignmentExpression, orr, method), inline).Emit(); } else if (!this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition)) { this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName()); this.WriteOpenParentheses(); if (variable != null) { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null, null, 0).Emit(); this.Write(", " + variable); } else { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null, null, 0).Emit(); } this.WriteCloseParentheses(); } } else { if (orr.IsLiftedOperator) { this.Write(JS.Types.SYSTEM_NULLABLE + "."); string action = JS.Funcs.Math.LIFT2; this.Write(action); this.WriteOpenParentheses(); this.WriteScript(op_name); this.WriteComma(); if (variable != null) { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null, null, 0).Emit(); } else { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null, null, 0).Emit(); } this.AddOveflowFlag(typeCode, op_name); this.WriteCloseParentheses(); } else { this.AssignmentExpression.Left.AcceptVisitor(this.Emitter); this.WriteDot(); this.Write(op_name); this.WriteOpenParentheses(); this.AssignmentExpression.Right.AcceptVisitor(this.Emitter); this.AddOveflowFlag(typeCode, op_name); this.WriteCloseParentheses(); } } }
protected virtual void EmitBaseConstructor(ConstructorDeclaration ctor, string ctorName) { var initializer = ctor.Initializer != null && !ctor.Initializer.IsNull ? ctor.Initializer : new ConstructorInitializer() { ConstructorInitializerType = ConstructorInitializerType.Base }; bool appendScope = false; if (initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { var baseType = this.Emitter.GetBaseTypeDefinition(); var baseName = "constructor"; if (ctor.Initializer != null && !ctor.Initializer.IsNull) { var member = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member; var overloads = OverloadsCollection.Create(this.Emitter, member); if (overloads.HasOverloads) { baseName = overloads.GetOverloadName(); } } if (baseName == "constructor") { baseName = "$constructor"; } string name = null; if (this.TypeInfo.GetBaseTypes(this.Emitter).Any()) { name = BridgeTypes.ToJsName(this.TypeInfo.GetBaseClass(this.Emitter), this.Emitter); } else { name = BridgeTypes.ToJsName(baseType, this.Emitter); } this.Write(name, ".prototype."); this.Write(baseName); this.Write(".call"); appendScope = true; } else { // this.WriteThis(); string name = BridgeTypes.ToJsName(this.TypeInfo.Type, this.Emitter); this.Write(name, ".prototype"); this.WriteDot(); var baseName = "constructor"; var member = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(ctor.Initializer, this.Emitter)).Member; var overloads = OverloadsCollection.Create(this.Emitter, member); if (overloads.HasOverloads) { baseName = overloads.GetOverloadName(); } if (baseName == "constructor") { baseName = "$constructor"; } this.Write(baseName); this.Write(".call"); appendScope = true; } this.WriteOpenParentheses(); if (appendScope) { this.WriteThis(); if (initializer.Arguments.Count > 0) { this.WriteComma(); } } var args = new List <Expression>(initializer.Arguments); for (int i = 0; i < args.Count; i++) { args[i].AcceptVisitor(this.Emitter); if (i != (args.Count - 1)) { this.WriteComma(); } } this.WriteCloseParentheses(); this.WriteSemiColon(); this.WriteNewLine(); }
protected virtual void EmitCtorForInstantiableClass() { this.EmitInitMembers(); if (!this.TypeInfo.HasInstantiable || this.Emitter.Plugins.HasConstructorInjectors(this)) { return; } var baseType = this.Emitter.GetBaseTypeDefinition(); var typeDef = this.Emitter.GetTypeDefinition(); if (typeDef.IsValueType) { this.TypeInfo.Ctors.Add(new ConstructorDeclaration { Modifiers = Modifiers.Public, Body = new BlockStatement() }); } foreach (var ctor in this.TypeInfo.Ctors) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(ctor.Parameters, ctor.Body); var ctorName = "constructor"; if (this.TypeInfo.Ctors.Count > 1 && ctor.Parameters.Count > 0) { var overloads = OverloadsCollection.Create(this.Emitter, ctor); ctorName = overloads.GetOverloadName(); } XmlToJsDoc.EmitComment(this, ctor); this.Write(ctorName); this.WriteColon(); this.WriteFunction(); this.EmitMethodParameters(ctor.Parameters, ctor); this.WriteSpace(); this.BeginBlock(); var requireNewLine = false; if (baseType != null && (!this.Emitter.Validator.IsIgnoreType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) || (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This)) { if (requireNewLine) { this.WriteNewLine(); } this.EmitBaseConstructor(ctor, ctorName); requireNewLine = true; } var script = this.Emitter.GetScript(ctor); if (script == null) { if (ctor.Body.HasChildren) { var beginPosition = this.Emitter.Output.Length; if (requireNewLine) { this.WriteNewLine(); } this.ConvertParamsToReferences(ctor.Parameters); ctor.Body.AcceptChildren(this.Emitter); if (!this.Emitter.IsAsync) { this.EmitTempVars(beginPosition); } } } else { if (requireNewLine) { this.WriteNewLine(); } foreach (var line in script) { this.Write(line); this.WriteNewLine(); } } this.EndBlock(); this.Emitter.Comma = true; this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); } }
public static int CheckConversion(ConversionBlock block, Expression expression) { try { var rr = block.Emitter.Resolver.ResolveNode(expression, block.Emitter); var conversion = block.Emitter.Resolver.Resolver.GetConversion(expression); var expectedType = block.Emitter.Resolver.Resolver.GetExpectedType(expression); int level = 0; if (block.Emitter.IsAssignment) { return(level); } if (expression is ParenthesizedExpression && expression.Parent is CastExpression) { return(level); } if (rr is ConstantResolveResult && expression is CastExpression && !conversion.IsUserDefined) { return(level); } var convrr = rr as ConversionResolveResult; if (convrr != null && convrr.Input is ConstantResolveResult && !convrr.Conversion.IsUserDefined) { return(level); } if (convrr != null && !conversion.IsUserDefined) { conversion = convrr.Conversion; rr = convrr.Input; expectedType = convrr.Type; } if (!((expression.Parent is CastExpression) && !(expression is CastExpression))) { CheckNumericConversion(block, expression, rr, expectedType, conversion); } if (!(conversion.IsExplicit && conversion.IsNumericConversion)) { level = ConversionBlock.CheckDecimalConversion(block, expression, rr, expectedType, conversion) ? (level + 1) : level; } if (Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined) { return(level); } if (!(conversion.IsExplicit && conversion.IsNumericConversion)) { level = ConversionBlock.CheckLongConversion(block, expression, rr, expectedType, conversion) ? (level + 1) : level; } if (Helpers.Is64Type(expectedType, block.Emitter.Resolver) && !conversion.IsUserDefined) { return(level); } if (conversion == null) { return(level); } if (conversion.IsIdentityConversion) { return(level); } var isNumLifted = conversion.IsImplicit && conversion.IsLifted && conversion.IsNumericConversion && !(expression is BinaryOperatorExpression); if (isNumLifted && !conversion.IsUserDefined) { return(level); } bool isLifted = conversion.IsLifted && !isNumLifted && !(block is CastBlock) && !Helpers.IsDecimalType(expectedType, block.Emitter.Resolver) && !Helpers.Is64Type(expectedType, block.Emitter.Resolver) && !NullableType.IsNullable(expectedType); if (isLifted) { level++; block.Write("Bridge.Nullable.getValue("); } if (conversion.IsUserDefined) { var method = conversion.Method; string inline = block.Emitter.GetInline(method); if (conversion.IsExplicit && !string.IsNullOrWhiteSpace(inline)) { // Still returns true if Nullable.lift( was written. return(level); } if (!string.IsNullOrWhiteSpace(inline)) { if (expression is InvocationExpression) { new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (InvocationExpression)expression), inline).Emit(); } else if (expression is ObjectCreateExpression) { new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, (ObjectCreateExpression)expression), inline).Emit(); } else if (expression is UnaryOperatorExpression) { var unaryExpression = (UnaryOperatorExpression)expression; var resolveOperator = block.Emitter.Resolver.ResolveNode(unaryExpression, block.Emitter); OperatorResolveResult orr = resolveOperator as OperatorResolveResult; new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, unaryExpression, orr, method), inline).Emit(); } else if (expression is BinaryOperatorExpression) { var binaryExpression = (BinaryOperatorExpression)expression; var resolveOperator = block.Emitter.Resolver.ResolveNode(binaryExpression, block.Emitter); OperatorResolveResult orr = resolveOperator as OperatorResolveResult; new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, binaryExpression, orr, method), inline).Emit(); } else { new InlineArgumentsBlock(block.Emitter, new ArgumentsInfo(block.Emitter, expression), inline).Emit(); } block.DisableEmitConversionExpression = true; // Still returns true if Nullable.lift( was written. return(level); } else { if (method.DeclaringTypeDefinition != null && block.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { // Still returns true if Nullable.lift( was written. return(level); } block.Write(BridgeTypes.ToJsName(method.DeclaringType, block.Emitter)); block.WriteDot(); block.Write(OverloadsCollection.Create(block.Emitter, method).GetOverloadName()); } if (isLifted) { block.WriteComma(); } else { block.WriteOpenParentheses(); level++; } var arg = method.Parameters[0]; if (Helpers.IsDecimalType(arg.Type, block.Emitter.Resolver, arg.IsParams) && !Helpers.IsDecimalType(rr.Type, block.Emitter.Resolver) && !expression.IsNull) { block.Write("Bridge.Decimal"); if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write(".lift"); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(level); } block.WriteOpenParentheses(); level++; } if (Helpers.Is64Type(arg.Type, block.Emitter.Resolver, arg.IsParams) && !Helpers.Is64Type(rr.Type, block.Emitter.Resolver) && !expression.IsNull) { var isUint = Helpers.IsULongType(arg.Type, block.Emitter.Resolver, arg.IsParams); block.Write("Bridge." + (isUint ? "ULong" : "Long")); if (NullableType.IsNullable(arg.Type) && ConversionBlock.ShouldBeLifted(expression)) { block.Write(".lift"); } if (expression is CastExpression && ((CastExpression)expression).Expression is ParenthesizedExpression) { return(level); } block.WriteOpenParentheses(); level++; } return(level); } // Still returns true if Nullable.lift( was written. return(level); } catch { } return(0); }
private void HandleDecimal(ResolveResult resolveOperator) { var orr = resolveOperator as OperatorResolveResult; var op = this.UnaryOperatorExpression.Operator; var oldType = this.Emitter.UnaryOperatorType; var oldAccessor = this.Emitter.IsUnaryAccessor; this.Emitter.UnaryOperatorType = op; var argResolverResult = this.Emitter.Resolver.ResolveNode(this.UnaryOperatorExpression.Expression, this.Emitter); bool nullable = NullableType.IsNullable(argResolverResult.Type); bool isAccessor = false; var memberArgResolverResult = argResolverResult as MemberResolveResult; if (memberArgResolverResult != null && memberArgResolverResult.Member is IProperty) { isAccessor = true; } else if (argResolverResult is ArrayAccessResolveResult) { isAccessor = ((ArrayAccessResolveResult)argResolverResult).Indexes.Count > 1; } var isOneOp = op == UnaryOperatorType.Increment || op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostIncrement || op == UnaryOperatorType.PostDecrement; if (isAccessor && isOneOp) { this.Emitter.IsUnaryAccessor = true; if (nullable) { this.Write("({0}.hasValue(".F(LuaHelper.Root)); this.Emitter.IsUnaryAccessor = false; this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(") ? "); this.Emitter.IsUnaryAccessor = true; this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" : null)"); } else { this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); } this.Emitter.UnaryOperatorType = oldType; this.Emitter.IsUnaryAccessor = oldAccessor; return; } var method = orr != null ? orr.UserDefinedOperatorMethod : null; if (orr != null && method == null) { var name = Helpers.GetUnaryOperatorMethodName(this.UnaryOperatorExpression.Operator); var type = NullableType.IsNullable(orr.Type) ? NullableType.GetUnderlyingType(orr.Type) : orr.Type; method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); } if (method != null) { var inline = this.Emitter.GetInline(method); if (orr.IsLiftedOperator) { if (!isOneOp) { this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable."); } string action = "lift1"; string op_name = null; switch (this.UnaryOperatorExpression.Operator) { case UnaryOperatorType.Minus: op_name = "neg"; break; case UnaryOperatorType.Plus: op_name = "clone"; break; case UnaryOperatorType.Increment: case UnaryOperatorType.Decrement: this.Write("(Bridge.hasValue("); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(") ? "); this.WriteOpenParentheses(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = Bridge.Nullable.lift1('" + (op == UnaryOperatorType.Decrement ? "dec" : "inc") + "', "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(")"); this.WriteCloseParentheses(); this.Write(" : null)"); break; case UnaryOperatorType.PostIncrement: case UnaryOperatorType.PostDecrement: this.Write("(Bridge.hasValue("); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(") ? "); this.WriteOpenParentheses(); var valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.WriteComma(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = Bridge.Nullable.lift1('" + (op == UnaryOperatorType.PostDecrement ? "dec" : "inc") + "', "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(")"); this.WriteComma(); this.Write(valueVar); this.WriteCloseParentheses(); this.RemoveTempVar(valueVar); this.Write(" : null)"); break; } if (!isOneOp) { this.Write(action); this.WriteOpenParentheses(); this.WriteScript(op_name); this.WriteComma(); new ExpressionListBlock(this.Emitter, new Expression[] { this.UnaryOperatorExpression.Expression }, null).Emit(); this.WriteCloseParentheses(); } } else if (!string.IsNullOrWhiteSpace(inline)) { if (isOneOp) { var isStatement = this.UnaryOperatorExpression.Parent is ExpressionStatement; if (isStatement || this.UnaryOperatorExpression.Operator == UnaryOperatorType.Increment || this.UnaryOperatorExpression.Operator == UnaryOperatorType.Decrement) { this.WriteOpenParentheses(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = "); new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit (); this.WriteCloseParentheses(); } else { this.WriteOpenParentheses(); var valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.WriteComma(); this.UnaryOperatorExpression.Expression.AcceptVisitor(this.Emitter); this.Write(" = "); new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit(); this.WriteComma(); this.Write(valueVar); this.WriteCloseParentheses(); this.RemoveTempVar(valueVar); } } else { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.UnaryOperatorExpression, orr, method), inline).Emit(); } } else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName()); this.WriteOpenParentheses(); new ExpressionListBlock(this.Emitter, new Expression[] { this.UnaryOperatorExpression.Expression }, null).Emit(); this.WriteCloseParentheses(); } } this.Emitter.UnaryOperatorType = oldType; }
protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { foreach (var attrSection in methodDeclaration.Attributes) { foreach (var attr in attrSection.Attributes) { var rr = Emitter.Resolver.ResolveNode(attr.Type); if (rr.Type.FullName == "H5.ExternalAttribute") { return; } else if (rr.Type.FullName == "H5.InitAttribute") { InitPosition initPosition = InitPosition.After; if (attr.HasArgumentList) { if (attr.Arguments.Any()) { var argExpr = attr.Arguments.First(); var argrr = Emitter.Resolver.ResolveNode(argExpr); if (argrr.ConstantValue is int) { initPosition = (InitPosition)argrr.ConstantValue; } } } if (initPosition > 0) { return; } } } } EnsureComma(); ResetLocals(); var prevMap = BuildLocalsMap(); var prevNamesMap = BuildLocalsNamesMap(); AddLocals(methodDeclaration.Parameters, methodDeclaration.Body); var overloads = OverloadsCollection.Create(Emitter, methodDeclaration); XmlToJsDoc.EmitComment(this, MethodDeclaration); var isEntryPoint = Helpers.IsEntryPointMethod(Emitter, MethodDeclaration); var member_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(MethodDeclaration); string name = overloads.GetOverloadName(false, null, excludeTypeOnly: OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr)); if (isEntryPoint) { Write(JS.Funcs.ENTRY_POINT_NAME); } else { Write(name); } WriteColon(); WriteFunction(); if (isEntryPoint) { Write(name); WriteSpace(); } else { var nm = Helpers.GetFunctionName(Emitter.AssemblyInfo.NamedFunctions, member_rr.Member, Emitter); if (nm != null) { Write(nm); WriteSpace(); } } EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration.TypeParameters.Count > 0 && Helpers.IsIgnoreGeneric(methodDeclaration, Emitter) ? null : methodDeclaration.TypeParameters, methodDeclaration); WriteSpace(); var script = Emitter.GetScript(methodDeclaration); if (script == null) { if (YieldBlock.HasYield(methodDeclaration.Body)) { new GeneratorBlock(Emitter, methodDeclaration).Emit(); } else if (methodDeclaration.HasModifier(Modifiers.Async) || AsyncBlock.HasGoto(methodDeclaration.Body)) { new AsyncBlock(Emitter, methodDeclaration).Emit(); } else { methodDeclaration.Body.AcceptVisitor(Emitter); } } else { BeginBlock(); WriteLines(script); EndBlock(); } ClearLocalsMap(prevMap); ClearLocalsNamesMap(prevNamesMap); Emitter.Comma = true; }
protected void VisitInvocationExpression() { InvocationExpression invocationExpression = this.InvocationExpression; int pos = this.Emitter.Output.Length; if (this.Emitter.IsForbiddenInvocation(invocationExpression)) { throw new EmitterException(invocationExpression, "This method cannot be invoked directly"); } var oldValue = this.Emitter.ReplaceAwaiterByVar; var oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling; if (this.Emitter.IsAsync && !this.Emitter.AsyncExpressionHandling) { this.WriteAwaiters(invocationExpression); this.Emitter.ReplaceAwaiterByVar = true; this.Emitter.AsyncExpressionHandling = true; } Tuple <bool, bool, string> inlineInfo = this.Emitter.GetInlineCode(invocationExpression); var argsInfo = new ArgumentsInfo(this.Emitter, invocationExpression); var argsExpressions = argsInfo.ArgumentsExpressions; var paramsArg = argsInfo.ParamsExpression; var targetResolve = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter); var csharpInvocation = targetResolve as CSharpInvocationResolveResult; MemberReferenceExpression targetMember = invocationExpression.Target as MemberReferenceExpression; bool isObjectLiteral = csharpInvocation != null && csharpInvocation.Member.DeclaringTypeDefinition != null?this.Emitter.Validator.IsObjectLiteral(csharpInvocation.Member.DeclaringTypeDefinition) : false; var interceptor = this.Emitter.Plugins.OnInvocation(this, this.InvocationExpression, targetResolve as InvocationResolveResult); if (interceptor.Cancel) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } if (!string.IsNullOrEmpty(interceptor.Replacement)) { this.Write(interceptor.Replacement); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } if (inlineInfo != null) { bool isStaticMethod = inlineInfo.Item1; bool isInlineMethod = inlineInfo.Item2; string inlineScript = inlineInfo.Item3; if (isInlineMethod) { if (invocationExpression.Arguments.Count > 0) { var code = invocationExpression.Arguments.First(); var inlineExpression = code as PrimitiveExpression; if (inlineExpression == null) { throw new EmitterException(invocationExpression, "Only primitive expression can be inlined"); } string value = inlineExpression.Value.ToString().Trim(); if (value.Length > 0) { value = InlineArgumentsBlock.ReplaceInlineArgs(this, inlineExpression.Value.ToString(), invocationExpression.Arguments.Skip(1).ToArray()); this.Write(value); value = value.Trim(); if (value[value.Length - 1] == ';' || value.EndsWith("*/", StringComparison.InvariantCulture) || value.StartsWith("//")) { this.Emitter.EnableSemicolon = false; this.WriteNewLine(); } } else { // Empty string, emit nothing. this.Emitter.EnableSemicolon = false; } this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else { MemberReferenceExpression targetMemberRef = invocationExpression.Target as MemberReferenceExpression; bool isBase = targetMemberRef != null && targetMemberRef.Target is BaseReferenceExpression; if (!String.IsNullOrEmpty(inlineScript) && (isBase || invocationExpression.Target is IdentifierExpression)) { argsInfo.ThisArgument = "this"; bool noThis = !inlineScript.Contains("{this}"); if (inlineScript.StartsWith("<self>")) { noThis = false; inlineScript = inlineScript.Substring(6); } if (!noThis) { Emitter.ThisRefCounter++; } if (!isStaticMethod && noThis) { this.WriteThis(); this.WriteDot(); } new InlineArgumentsBlock(this.Emitter, argsInfo, inlineScript).Emit(); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } } if (targetMember != null || isObjectLiteral) { var member = targetMember != null?this.Emitter.Resolver.ResolveNode(targetMember.Target, this.Emitter) : null; if (targetResolve != null) { InvocationResolveResult invocationResult; bool isExtensionMethodInvocation = false; if (csharpInvocation != null) { if (member != null && member.Type.Kind == TypeKind.Delegate && (/*csharpInvocation.Member.Name == "Invoke" || */ csharpInvocation.Member.Name == "BeginInvoke" || csharpInvocation.Member.Name == "EndInvoke") && !csharpInvocation.IsExtensionMethodInvocation) { throw new EmitterException(invocationExpression, "Delegate's 'Invoke' methods are not supported. Please use direct delegate invoke."); } if (csharpInvocation.IsExtensionMethodInvocation) { invocationResult = csharpInvocation; isExtensionMethodInvocation = true; var resolvedMethod = invocationResult.Member as IMethod; if (resolvedMethod != null && resolvedMethod.IsExtensionMethod) { string inline = this.Emitter.GetInline(resolvedMethod); bool isNative = this.IsNativeMethod(resolvedMethod); if (string.IsNullOrWhiteSpace(inline) && isNative) { invocationResult = null; } } } else { invocationResult = null; } if (this.IsEmptyPartialInvoking(csharpInvocation.Member as IMethod) || IsConditionallyRemoved(invocationExpression, csharpInvocation.Member)) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else { invocationResult = targetResolve as InvocationResolveResult; if (invocationResult != null && (this.IsEmptyPartialInvoking(invocationResult.Member as IMethod) || IsConditionallyRemoved(invocationExpression, invocationResult.Member))) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } if (invocationResult == null) { invocationResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as InvocationResolveResult; } if (invocationResult != null) { var resolvedMethod = invocationResult.Member as IMethod; if (resolvedMethod != null && (resolvedMethod.IsExtensionMethod || isObjectLiteral)) { string inline = this.Emitter.GetInline(resolvedMethod); bool isNative = this.IsNativeMethod(resolvedMethod); if (isExtensionMethodInvocation || isObjectLiteral) { if (!string.IsNullOrWhiteSpace(inline)) { this.Write(""); StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit(); } else if (!isNative) { var overloads = OverloadsCollection.Create(this.Emitter, resolvedMethod); if (isObjectLiteral && !resolvedMethod.IsStatic && resolvedMethod.DeclaringType.Kind == TypeKind.Interface) { this.Write("Bridge.getType("); this.WriteThisExtension(invocationExpression.Target); this.Write(")."); } else { string name = BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter) + "."; this.Write(name); } if (isObjectLiteral && !resolvedMethod.IsStatic) { this.Write(JS.Fields.PROTOTYPE + "." + overloads.GetOverloadName() + "." + JS.Funcs.CALL); } else { this.Write(overloads.GetOverloadName()); } var isIgnoreClass = resolvedMethod.DeclaringTypeDefinition != null && this.Emitter.Validator.IsExternalType(resolvedMethod.DeclaringTypeDefinition); int openPos = this.Emitter.Output.Length; this.WriteOpenParentheses(); this.Emitter.Comma = false; if (isObjectLiteral && !resolvedMethod.IsStatic) { this.WriteThisExtension(invocationExpression.Target); this.Emitter.Comma = true; } if (!isIgnoreClass && !Helpers.IsIgnoreGeneric(resolvedMethod, this.Emitter) && argsInfo.HasTypeArguments) { this.EnsureComma(false); new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); this.Emitter.Comma = true; } if (!isObjectLiteral && resolvedMethod.IsStatic) { this.EnsureComma(false); this.WriteThisExtension(invocationExpression.Target); this.Emitter.Comma = true; } if (invocationExpression.Arguments.Count > 0) { this.EnsureComma(false); } new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit(); this.WriteCloseParentheses(); } if (!string.IsNullOrWhiteSpace(inline) || !isNative) { this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else if (isNative) { if (!string.IsNullOrWhiteSpace(inline)) { this.Write(""); StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit(); } else { argsExpressions.First().AcceptVisitor(this.Emitter); this.WriteDot(); string name = this.Emitter.GetEntityName(resolvedMethod); this.Write(name); int openPos = this.Emitter.Output.Length; this.WriteOpenParentheses(); new ExpressionListBlock(this.Emitter, argsExpressions.Skip(1), paramsArg, invocationExpression, openPos).Emit(); this.WriteCloseParentheses(); } this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } } } } var proto = false; if (targetMember != null && targetMember.Target is BaseReferenceExpression) { var rr = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter) as MemberResolveResult; if (rr != null) { proto = rr.IsVirtualCall; /*var method = rr.Member as IMethod; * if (method != null && method.IsVirtual) * { * proto = true; * } * else * { * var prop = rr.Member as IProperty; * * if (prop != null && prop.IsVirtual) * { * proto = true; * } * }*/ } } if (proto) { var baseType = this.Emitter.GetBaseMethodOwnerTypeDefinition(targetMember.MemberName, targetMember.TypeArguments.Count); bool isIgnore = this.Emitter.Validator.IsExternalType(baseType); if (isIgnore) { //throw (System.Exception)this.Emitter.CreateException(targetMember.Target, "Cannot call base method, because parent class code is ignored"); } bool needComma = false; var resolveResult = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter); string name = null; if (this.Emitter.TypeInfo.GetBaseTypes(this.Emitter).Any()) { name = BridgeTypes.ToJsName(this.Emitter.TypeInfo.GetBaseClass(this.Emitter), this.Emitter); } else { name = BridgeTypes.ToJsName(baseType, this.Emitter); } string baseMethod; bool isIgnoreGeneric = false; if (resolveResult is InvocationResolveResult) { InvocationResolveResult invocationResult = (InvocationResolveResult)resolveResult; baseMethod = OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName(); isIgnoreGeneric = Helpers.IsIgnoreGeneric(invocationResult.Member, this.Emitter); } else if (resolveResult is MemberResolveResult) { MemberResolveResult memberResult = (MemberResolveResult)resolveResult; baseMethod = OverloadsCollection.Create(this.Emitter, memberResult.Member).GetOverloadName(); isIgnoreGeneric = Helpers.IsIgnoreGeneric(memberResult.Member, this.Emitter); } else { baseMethod = targetMember.MemberName; baseMethod = this.Emitter.AssemblyInfo.PreserveMemberCase ? baseMethod : Object.Net.Utilities.StringUtils.ToLowerCamelCase(baseMethod); } this.Write(name, "." + JS.Fields.PROTOTYPE + ".", baseMethod); this.WriteCall(); this.WriteOpenParentheses(); this.WriteThis(); this.Emitter.Comma = true; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); } needComma = false; foreach (var arg in argsExpressions) { if (arg == null) { continue; } this.EnsureComma(false); if (needComma) { this.WriteComma(); } needComma = true; arg.AcceptVisitor(this.Emitter); } this.Emitter.Comma = false; this.WriteCloseParentheses(); } else { var dynamicResolveResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as DynamicInvocationResolveResult; if (dynamicResolveResult != null) { var group = dynamicResolveResult.Target as MethodGroupResolveResult; if (group != null && group.Methods.Count() > 1) { throw new EmitterException(invocationExpression, "Cannot compile this dynamic invocation because there are two or more method overloads with the same parameter count. To work around this limitation, assign the dynamic value to a non-dynamic variable before use or call a method with different parameter count"); } } var targetResolveResult = this.Emitter.Resolver.ResolveNode(invocationExpression.Target, this.Emitter); var invocationResolveResult = targetResolveResult as MemberResolveResult; IMethod method = null; if (invocationResolveResult != null) { method = invocationResolveResult.Member as IMethod; } if (this.IsEmptyPartialInvoking(method) || IsConditionallyRemoved(invocationExpression, method)) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } bool isIgnore = method != null && method.DeclaringTypeDefinition != null && this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition); bool needExpand = false; if (method != null) { string paramsName = null; var paramsParam = method.Parameters.FirstOrDefault(p => p.IsParams); if (paramsParam != null) { paramsName = paramsParam.Name; } if (paramsName != null) { if (csharpInvocation != null && !csharpInvocation.IsExpandedForm) { needExpand = true; } } } int count = this.Emitter.Writers.Count; invocationExpression.Target.AcceptVisitor(this.Emitter); if (this.Emitter.Writers.Count > count) { var writer = this.Emitter.Writers.Pop(); if (method != null && method.IsExtensionMethod) { StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; } else if (writer.ThisArg != null) { argsInfo.ThisArgument = writer.ThisArg; } new InlineArgumentsBlock(this.Emitter, argsInfo, writer.InlineCode) { IgnoreRange = writer.IgnoreRange }.Emit(); var result = this.Emitter.Output.ToString(); this.Emitter.Output = writer.Output; this.Emitter.IsNewLine = writer.IsNewLine; this.Write(result); if (writer.Callback != null) { writer.Callback.Invoke(); } } else { if (needExpand && isIgnore) { this.Write("." + JS.Funcs.APPLY); } int openPos = this.Emitter.Output.Length; this.WriteOpenParentheses(); bool isIgnoreGeneric = false; var invocationResult = targetResolve as InvocationResolveResult; if (invocationResult != null) { isIgnoreGeneric = Helpers.IsIgnoreGeneric(invocationResult.Member, this.Emitter); } if (needExpand && isIgnore) { StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); var thisArg = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; this.Write(thisArg); this.Emitter.Comma = true; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); } this.EnsureComma(false); if (argsExpressions.Length > 1) { this.WriteOpenBracket(); new ExpressionListBlock(this.Emitter, argsExpressions.Take(argsExpressions.Length - 1).ToArray(), paramsArg, invocationExpression, openPos).Emit(); this.WriteCloseBracket(); this.Write(".concat("); new ExpressionListBlock(this.Emitter, new Expression[] { argsExpressions[argsExpressions.Length - 1] }, paramsArg, invocationExpression, openPos).Emit(); this.Write(")"); } else { new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, -1).Emit(); } } else { this.Emitter.Comma = false; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); } if (invocationExpression.Arguments.Count > 0) { this.EnsureComma(false); } new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit(); } this.WriteCloseParentheses(); } } Helpers.CheckValueTypeClone(this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter), invocationExpression, this, pos); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; }
protected void VisitMemberReferenceExpression() { MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression; int pos = this.Emitter.Output.Length; ResolveResult resolveResult = null; ResolveResult expressionResolveResult = null; string targetVar = null; string valueVar = null; bool isStatement = false; bool isConstTarget = false; var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter); if (targetrr is ConstantResolveResult) { isConstTarget = true; } var memberTargetrr = targetrr as MemberResolveResult; if (memberTargetrr != null && memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField && this.Emitter.Validator.EnumEmitMode(memberTargetrr.Type) == 2) { isConstTarget = true; } if (memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression)) { resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter); expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter); if (expressionResolveResult is InvocationResolveResult) { resolveResult = expressionResolveResult; } } else { resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter); } bool oldIsAssignment = this.Emitter.IsAssignment; bool oldUnary = this.Emitter.IsUnaryAccessor; if (resolveResult == null) { this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } memberReferenceExpression.Target.AcceptVisitor(this.Emitter); if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; this.WriteDot(); string name = memberReferenceExpression.MemberName; this.Write(name.ToLowerCamelCase()); return; } if (resolveResult is DynamicInvocationResolveResult) { resolveResult = ((DynamicInvocationResolveResult)resolveResult).Target; } if (resolveResult is MethodGroupResolveResult) { var oldResult = (MethodGroupResolveResult)resolveResult; resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter); if (resolveResult is DynamicInvocationResolveResult) { var method = oldResult.Methods.Last(); resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method); } } MemberResolveResult member = resolveResult as MemberResolveResult; var globalTarget = member != null?this.Emitter.IsGlobalTarget(member.Member) : null; if (globalTarget != null && globalTarget.Item1) { var target = globalTarget.Item2; if (!string.IsNullOrWhiteSpace(target)) { bool assign = false; var memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent; var targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression; var assignment = memberExpression as AssignmentExpression; if (assignment != null && assignment.Right == targetExpression) { assign = true; } else { var varInit = memberExpression as VariableInitializer; if (varInit != null && varInit.Initializer == targetExpression) { assign = true; } else if (memberExpression is InvocationExpression) { var targetInvocation = (InvocationExpression)memberExpression; if (targetInvocation.Arguments.Any(a => a == targetExpression)) { assign = true; } } } if (assign) { if (resolveResult is InvocationResolveResult) { this.PushWriter(target); } else { this.Write(target); } return; } } if (resolveResult is InvocationResolveResult) { this.PushWriter(""); } return; } Tuple <bool, bool, string> inlineInfo = member != null?this.Emitter.GetInlineCode(memberReferenceExpression) : null; //string inline = member != null ? this.Emitter.GetInline(member.Member) : null; string inline = inlineInfo != null ? inlineInfo.Item3 : null; bool hasInline = !string.IsNullOrEmpty(inline); bool hasThis = hasInline && inline.Contains("{this}"); if (hasThis) { this.Write(""); var oldBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } memberReferenceExpression.Target.AcceptVisitor(this.Emitter); if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; inline = inline.Replace("{this}", this.Emitter.Output.ToString()); this.Emitter.Output = oldBuilder; if (resolveResult is InvocationResolveResult) { this.PushWriter(inline); } else { if (member != null && member.Member is IMethod) { throw new EmitterException(memberReferenceExpression, "The templated method (" + member.Member.FullName + ") cannot be used like reference"); } else { this.Write(inline); } } return; } if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member)) { this.WriteScript(member.ConstantValue); } else if (hasInline && member.Member.IsStatic) { if (resolveResult is InvocationResolveResult) { this.PushWriter(inline); } else { if (member != null && member.Member is IMethod) { var r = new Regex(@"([$\w\.]+)\(\s*\S.*\)"); var match = r.Match(inline); if (match.Success) { this.Write(match.Groups[1].Value); } else { throw new EmitterException(memberReferenceExpression, "The templated method (" + member.Member.FullName + ") cannot be used like reference"); } } else { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit(); } } } else { if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum) { var typeDef = member.Member.DeclaringType as DefaultResolvedTypeDefinition; if (typeDef != null) { var enumMode = this.Emitter.Validator.EnumEmitMode(typeDef); if ((this.Emitter.Validator.IsIgnoreType(typeDef) && enumMode == -1) || enumMode == 2) { this.WriteScript(member.ConstantValue); return; } if (enumMode >= 3) { string enumStringName = member.Member.Name; var attr = Helpers.GetInheritedAttribute(member.Member, Translator.Bridge_ASSEMBLY + ".NameAttribute"); if (attr != null) { enumStringName = this.Emitter.GetEntityName(member.Member); } else { switch (enumMode) { case 3: enumStringName = Object.Net.Utilities.StringUtils.ToLowerCamelCase(member.Member.Name); break; case 4: break; case 5: enumStringName = enumStringName.ToLowerInvariant(); break; case 6: enumStringName = enumStringName.ToUpperInvariant(); break; } } this.WriteScript(enumStringName); return; } } } bool isInvokeInCurClass = false; if (resolveResult is TypeResolveResult) { TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult; this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter)); /* * var isNative = this.Emitter.Validator.IsIgnoreType(typeResolveResult.Type.GetDefinition()); * if(isNative) { * this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter)); * } * else { * this.Write("Bridge.get(" + BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter) + ")"); * }*/ return; } else if (member != null && member.Member is IMethod && !(member is InvocationResolveResult) && !( memberReferenceExpression.Parent is InvocationExpression && memberReferenceExpression.NextSibling != null && memberReferenceExpression.NextSibling.Role is TokenRole && ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "(" ) ) { var resolvedMethod = (IMethod)member.Member; bool isStatic = resolvedMethod != null && resolvedMethod.IsStatic; var isExtensionMethod = resolvedMethod.IsExtensionMethod; this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (!isStatic) { this.Write(Bridge.Translator.Emitter.ROOT + "." + (isExtensionMethod ? Bridge.Translator.Emitter.DELEGATE_BIND_SCOPE : Bridge.Translator.Emitter.DELEGATE_BIND) + "("); memberReferenceExpression.Target.AcceptVisitor(this.Emitter); this.Write(", "); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; if (isExtensionMethod) { this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter)); } else { this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } memberReferenceExpression.Target.AcceptVisitor(this.Emitter); if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; } this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName()); if (!isStatic) { this.Write(")"); } return; } else { bool isProperty = false; if (member != null && member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition)) { isProperty = true; bool writeTargetVar = false; if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign) { writeTargetVar = true; } else if (this.Emitter.IsUnaryAccessor) { writeTargetVar = true; isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement; if (NullableType.IsNullable(member.Type)) { isStatement = false; } if (!isStatement) { this.WriteOpenParentheses(); } } if (writeTargetVar) { bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult); if (!(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField)) { targetVar = this.GetTempVarName(); this.WriteVar(); this.Write(targetVar); this.Write(" = "); } } } if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null) { valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); } this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } isInvokeInCurClass = resolveResult is InvocationResolveResult && member.Member.DeclaringType == TransformCtx.CurClass; if (!isInvokeInCurClass) { memberReferenceExpression.Target.AcceptVisitor(this.Emitter); } if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; if (targetVar != null) { if (this.Emitter.IsUnaryAccessor && !isStatement) { this.WriteComma(false); valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.Write(targetVar); } else { this.WriteSemiColon(); this.WriteNewLine(); this.Write(targetVar); } } } var targetResolveResult = targetrr as MemberResolveResult; if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null) { if (member != null && member.Member != null) { if (!isInvokeInCurClass) { if (!member.Member.IsStatic && ((member.Member.SymbolKind == SymbolKind.Method && !this.Emitter.Validator.IsDelegateOrLambda(expressionResolveResult)) || (member.Member.SymbolKind == SymbolKind.Property && !Helpers.IsFieldProperty(member.Member, this.Emitter)))) { this.WriteObjectColon(); } else { this.WriteDot(); } } } else { this.WriteDot(); } } if (member == null) { if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic) { this.Write(memberReferenceExpression.MemberName); } else { this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase()); } } else if (!string.IsNullOrEmpty(inline)) { if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment)) { this.PushWriter(inline); } else { this.Write(inline); } } else if (member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition)) { var proto = false; if (this.MemberReferenceExpression.Target is BaseReferenceExpression && member != null) { var prop = member.Member as IProperty; if (prop != null && (prop.IsVirtual || prop.IsOverride)) { proto = true; } } if (Helpers.IsFieldProperty(member.Member, this.Emitter)) { this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter)); } else if (!this.Emitter.IsAssignment) { if (this.Emitter.IsUnaryAccessor) { bool isNullable = NullableType.IsNullable(member.Member.ReturnType); bool isDecimal = Helpers.IsDecimalType(member.Member.ReturnType, this.Emitter.Resolver); if (isStatement) { this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true)); if (proto) { this.Write(".call"); this.WriteOpenParentheses(); this.WriteThis(); this.WriteComma(); } else { this.WriteOpenParentheses(); } if (isDecimal) { if (isNullable) { this.Write("Bridge.Nullable.lift1"); this.WriteOpenParentheses(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.WriteScript("inc"); } else { this.WriteScript("dec"); } this.WriteComma(); if (targetVar != null) { this.Write(targetVar); } else { memberReferenceExpression.Target.AcceptVisitor(this.Emitter); } this.WriteDot(); this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false)); if (proto) { this.Write(".call"); this.WriteOpenParentheses(); this.WriteThis(); this.WriteCloseParentheses(); } else { this.WriteOpenParentheses(); this.WriteCloseParentheses(); } this.WriteCloseParentheses(); } else { if (targetVar != null) { this.Write(targetVar); } else { memberReferenceExpression.Target.AcceptVisitor(this.Emitter); } this.WriteDot(); this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false)); if (proto) { this.Write(".call"); this.WriteOpenParentheses(); this.WriteThis(); this.WriteCloseParentheses(); } else { this.WriteOpenParentheses(); this.WriteCloseParentheses(); } this.WriteDot(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write("inc"); } else { this.Write("dec"); } this.WriteOpenParentheses(); this.WriteCloseParentheses(); this.WriteCloseParentheses(); } } else { if (targetVar != null) { this.Write(targetVar); } else { if (isConstTarget) { this.Write("("); } memberReferenceExpression.Target.AcceptVisitor(this.Emitter); if (isConstTarget) { this.Write(")"); } } this.WriteObjectColon(); this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false)); if (proto) { this.Write(".call"); this.WriteOpenParentheses(); this.WriteThis(); this.WriteCloseParentheses(); } else { this.WriteOpenParentheses(); this.WriteCloseParentheses(); } if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write(" + "); } else { this.Write(" - "); } this.Write("1"); this.WriteCloseParentheses(); } } else { this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false)); if (proto) { this.Write(".call"); this.WriteOpenParentheses(); this.WriteThis(); this.WriteCloseParentheses(); } else { this.WriteOpenParentheses(); this.WriteCloseParentheses(); } this.WriteComma(); if (targetVar != null) { this.Write(targetVar); } else { if (isConstTarget) { this.Write("("); } memberReferenceExpression.Target.AcceptVisitor(this.Emitter); if (isConstTarget) { this.Write(")"); } } this.WriteDot(); this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true)); if (proto) { this.Write(".call"); this.WriteOpenParentheses(); this.WriteThis(); this.WriteComma(); } else { this.WriteOpenParentheses(); } if (isDecimal) { if (isNullable) { this.Write("Bridge.Nullable.lift1"); this.WriteOpenParentheses(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.WriteScript("inc"); } else { this.WriteScript("dec"); } this.WriteComma(); this.Write(valueVar); this.WriteCloseParentheses(); } else { this.Write(valueVar); this.WriteDot(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write("inc"); } else { this.Write("dec"); } this.WriteOpenParentheses(); this.WriteCloseParentheses(); } } else { this.Write(valueVar); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write("+"); } else { this.Write("-"); } this.Write("1"); } this.WriteCloseParentheses(); this.WriteComma(); bool isPreOp = this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.Decrement; if (isPreOp) { if (targetVar != null) { this.Write(targetVar); } else { memberReferenceExpression.Target.AcceptVisitor(this.Emitter); } this.WriteDot(); this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false)); this.WriteOpenParentheses(); this.WriteCloseParentheses(); } else { this.Write(valueVar); } this.WriteCloseParentheses(); if (valueVar != null) { this.RemoveTempVar(valueVar); } } if (targetVar != null) { this.RemoveTempVar(targetVar); } } else { this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter)); if (proto) { this.Write(".call"); this.WriteOpenParentheses(); this.WriteThis(); this.WriteCloseParentheses(); } else { this.WriteOpenParentheses(); this.WriteCloseParentheses(); } } } else if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign) { if (targetVar != null) { this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true), proto ? ".call(this, " : "(", targetVar, ".", Helpers.GetPropertyRef(member.Member, this.Emitter, false), proto ? ".call(this)" : "()", "{0})"), () => { this.RemoveTempVar(targetVar); }); } else { var oldWriter = this.SaveWriter(); this.NewWriter(); this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; memberReferenceExpression.Target.AcceptVisitor(this.Emitter); this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; var trg = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + "({0})"); /* * this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true), * proto ? ".call(this, " : "(", * trg, * ".", * Helpers.GetPropertyRef(member.Member, this.Emitter, false), * proto ? ".call(this)" : "()", * "{0})"));*/ } } else { if (proto) { this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + ".call(this, {0})"); } else { this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + "({0})"); } } } else if (member.Member.SymbolKind == SymbolKind.Field) { bool isConst = this.Emitter.IsMemberConst(member.Member); if (isConst && this.Emitter.IsInlineConst(member.Member)) { this.WriteScript(member.ConstantValue); } else { this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName()); } } else if (resolveResult is InvocationResolveResult) { InvocationResolveResult invocationResult = (InvocationResolveResult)resolveResult; CSharpInvocationResolveResult cInvocationResult = (CSharpInvocationResolveResult)resolveResult; var expresssionMember = expressionResolveResult as MemberResolveResult; if (expresssionMember != null && cInvocationResult != null && cInvocationResult.IsDelegateInvocation && invocationResult.Member != expresssionMember.Member) { this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName()); } else { string name = OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName(); if (isInvokeInCurClass && Emitter.LocalsNamesMap.ContainsKey(name)) { string newName = this.GetUniqueName(name); this.IntroduceTempVar(newName + " = " + name); name = newName; } this.Write(name); } } else if (member.Member is DefaultResolvedEvent) { if (this.Emitter.IsAssignment && (this.Emitter.AssignmentType == AssignmentOperatorType.Add || this.Emitter.AssignmentType == AssignmentOperatorType.Subtract)) { this.Write(this.Emitter.AssignmentType == AssignmentOperatorType.Add ? "add" : "remove"); this.Write( OverloadsCollection.Create(this.Emitter, member.Member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName()); this.WriteOpenParentheses(); } else { this.Write(this.Emitter.GetEntityName(member.Member, true)); } } else { this.Write(this.Emitter.GetEntityName(member.Member)); } Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this, pos); } }
protected virtual void EmitCtorForInstantiableClass() { var baseType = this.Emitter.GetBaseTypeDefinition(); var typeDef = this.Emitter.GetTypeDefinition(); var isObjectLiteral = this.Emitter.Validator.IsObjectLiteral(typeDef); var isPlainMode = this.Emitter.Validator.GetObjectCreateMode(typeDef) == 0; var ctorWrappers = isObjectLiteral ? new string[0] : this.EmitInitMembers().ToArray(); if (!this.TypeInfo.HasRealInstantiable(this.Emitter) && ctorWrappers.Length == 0) { return; } if (isObjectLiteral && isPlainMode) { return; } bool forceDefCtor = isObjectLiteral && this.Emitter.Validator.GetObjectCreateMode(typeDef) == 1 && this.TypeInfo.Ctors.Count == 0; if (typeDef.IsValueType || forceDefCtor || (this.TypeInfo.Ctors.Count == 0 && ctorWrappers.Length > 0)) { this.TypeInfo.Ctors.Add(new ConstructorDeclaration { Modifiers = Modifiers.Public, Body = new BlockStatement() }); } foreach (var ctor in this.TypeInfo.Ctors) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(ctor.Parameters, ctor.Body); var ctorName = JS.Funcs.CONSTRUCTOR; if (this.TypeInfo.Ctors.Count > 1 && ctor.Parameters.Count > 0) { var overloads = OverloadsCollection.Create(this.Emitter, ctor); ctorName = overloads.GetOverloadName(); } XmlToJsDoc.EmitComment(this, ctor); this.Write(ctorName); this.WriteColon(); this.WriteFunction(); int pos = this.Emitter.Output.Length; this.EmitMethodParameters(ctor.Parameters, null, ctor); var ctorParams = this.Emitter.Output.ToString().Substring(pos); this.WriteSpace(); this.BeginBlock(); var len = this.Emitter.Output.Length; var requireNewLine = false; var noThisInvocation = ctor.Initializer == null || ctor.Initializer.IsNull || ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base; IWriterInfo oldWriter = null; if (ctorWrappers.Length > 0 && noThisInvocation) { oldWriter = this.SaveWriter(); this.NewWriter(); } this.ConvertParamsToReferences(ctor.Parameters); if (len != this.Emitter.Output.Length) { requireNewLine = true; } if (isObjectLiteral) { if (requireNewLine) { this.WriteNewLine(); } this.Write("var " + JS.Vars.D_THIS + " = "); var isBaseObjectLiteral = baseType != null && this.Emitter.Validator.IsObjectLiteral(baseType); if (isBaseObjectLiteral && baseType != null && (!this.Emitter.Validator.IsExternalType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) || (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This)) { this.EmitBaseConstructor(ctor, ctorName, true); } else if (isBaseObjectLiteral && baseType != null && ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { this.EmitExternalBaseCtor(ctor, ref requireNewLine); } else { this.Write("{};"); } this.WriteNewLine(); string name = this.Emitter.Validator.GetCustomTypeName(typeDef, this.Emitter); if (name.IsEmpty()) { name = BridgeTypes.DefinitionToJsName(this.TypeInfo.Type, this.Emitter); } this.Write(JS.Vars.D_THIS + "." + JS.Funcs.GET_TYPE + " = function() { return " + name + "; };"); this.WriteNewLine(); this.Write("(function()"); this.BeginBlock(); requireNewLine = false; } if (noThisInvocation) { if (requireNewLine) { this.WriteNewLine(); } if (isObjectLiteral) { var fieldBlock = new FieldBlock(this.Emitter, this.TypeInfo, false, false, true); fieldBlock.Emit(); var properties = this.TypeInfo.InstanceProperties; var names = new List <string>(properties.Keys); foreach (var name in names) { var props = properties[name]; foreach (var prop in props) { var p = prop as PropertyDeclaration; if (p != null) { if (p.Getter.Body.IsNull && p.Setter.Body.IsNull) { continue; } this.Write(JS.Types.Object.DEFINEPROPERTY); this.WriteOpenParentheses(); this.Write("this, "); this.WriteScript(OverloadsCollection.Create(this.Emitter, p).GetOverloadName()); this.WriteComma(); this.Emitter.Comma = false; this.BeginBlock(); var block = new VisitorPropertyBlock(this.Emitter, p); block.EmitPropertyMethod(p, p.Getter, false, true); block.EmitPropertyMethod(p, p.Setter, true, true); this.EnsureComma(true); this.Write(JS.Fields.ENUMERABLE + ": true"); this.WriteNewLine(); this.EndBlock(); this.WriteCloseParentheses(); this.Write(";"); this.WriteNewLine(); } } } } else { this.Write("this." + JS.Funcs.INITIALIZE + "();"); requireNewLine = true; } } if (!isObjectLiteral) { if (baseType != null && (!this.Emitter.Validator.IsExternalType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) || (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This)) { if (requireNewLine) { this.WriteNewLine(); requireNewLine = false; } this.EmitBaseConstructor(ctor, ctorName, false); } else if (baseType != null && ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { this.EmitExternalBaseCtor(ctor, ref requireNewLine); } } var script = this.Emitter.GetScript(ctor); if (script == null) { if (ctor.Body.HasChildren) { var beginPosition = this.Emitter.Output.Length; if (requireNewLine) { this.WriteNewLine(); } ctor.Body.AcceptChildren(this.Emitter); if (!this.Emitter.IsAsync) { this.EmitTempVars(beginPosition, true); } } else if (requireNewLine) { this.WriteNewLine(); } } else { if (requireNewLine) { this.WriteNewLine(); } this.WriteLines(script); } if (oldWriter != null) { this.WrapBody(oldWriter, ctorWrappers, ctorParams); } if (isObjectLiteral) { if (requireNewLine) { this.WriteNewLine(); } this.EndBlock(); this.Write(")." + JS.Funcs.CALL + "(" + JS.Vars.D_THIS + ");"); this.WriteNewLine(); this.Write("return " + JS.Vars.D_THIS + ";"); this.WriteNewLine(); } this.EndBlock(); this.Emitter.Comma = true; this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); } }
protected void VisitObjectCreateExpression() { ObjectCreateExpression objectCreateExpression = this.ObjectCreateExpression; var resolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression.Type, this.Emitter) as TypeResolveResult; if (resolveResult != null && resolveResult.Type.Kind == TypeKind.Enum) { this.Write("(0)"); return; } bool isTypeParam = resolveResult != null && resolveResult.Type.Kind == TypeKind.TypeParameter; var invocationResolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter) as InvocationResolveResult; var hasInitializer = !objectCreateExpression.Initializer.IsNull && objectCreateExpression.Initializer.Elements.Count > 0; if (isTypeParam && invocationResolveResult != null && invocationResolveResult.Member.Parameters.Count == 0 && !hasInitializer) { this.Write(JS.Funcs.BRIDGE_CREATEINSTANCE); this.WriteOpenParentheses(); this.Write(resolveResult.Type.Name); this.WriteCloseParentheses(); return; } var type = isTypeParam ? null : this.Emitter.GetTypeDefinition(objectCreateExpression.Type); var isObjectLiteral = type != null && this.Emitter.Validator.IsObjectLiteral(type); if (type != null && type.BaseType != null && type.BaseType.FullName == "System.MulticastDelegate") { bool wrap = false; var parent = objectCreateExpression.Parent as InvocationExpression; if (parent != null && parent.Target == objectCreateExpression) { wrap = true; } if (wrap) { this.WriteOpenParentheses(); } objectCreateExpression.Arguments.First().AcceptVisitor(this.Emitter); if (wrap) { this.WriteCloseParentheses(); } return; } var argsInfo = new ArgumentsInfo(this.Emitter, objectCreateExpression); var argsExpressions = argsInfo.ArgumentsExpressions; var paramsArg = argsInfo.ParamsExpression; string inlineCode = null; if (invocationResolveResult != null) { if (invocationResolveResult.Member.DeclaringType.Kind == TypeKind.Struct && objectCreateExpression.Arguments.Count == 0) { var ctors = invocationResolveResult.Member.DeclaringType.GetConstructors(c => c.Parameters.Count == 1); var defCtor = ctors.FirstOrDefault(c => c.Parameters.First().Type.FullName == "System.Runtime.CompilerServices.DummyTypeUsedToAddAttributeToDefaultValueTypeConstructor"); if (defCtor != null) { inlineCode = this.Emitter.GetInline(defCtor); } } if (inlineCode == null) { inlineCode = this.Emitter.GetInline(invocationResolveResult.Member); } } var customCtor = isTypeParam ? "" : (this.Emitter.Validator.GetCustomConstructor(type) ?? ""); AstNodeCollection <Expression> elements = null; if (hasInitializer) { elements = objectCreateExpression.Initializer.Elements; } var isPlainObjectCtor = Regex.Match(customCtor, @"\s*\{\s*\}\s*").Success; var isPlainMode = type != null && this.Emitter.Validator.GetObjectCreateMode(type) == 0; if (inlineCode == null && isPlainObjectCtor && isPlainMode) { this.WriteOpenBrace(); this.WriteSpace(); var pos = this.Emitter.Output.Length; this.WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, false); if (pos < this.Emitter.Output.Length) { this.WriteSpace(); } this.WriteCloseBrace(); } else { string tempVar = null; if (hasInitializer) { tempVar = this.GetTempVarName(); this.WriteOpenParentheses(); this.Write(tempVar); this.Write(" = "); } if (inlineCode != null) { new InlineArgumentsBlock(this.Emitter, argsInfo, inlineCode).Emit(); } else { var ctorMember = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter)).Member; var expandParams = ctorMember.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute"); bool applyCtor = false; if (expandParams) { var ctor_rr = this.Emitter.Resolver.ResolveNode(paramsArg, this.Emitter); if (ctor_rr.Type.Kind == TypeKind.Array && !(paramsArg is ArrayCreateExpression) && objectCreateExpression.Arguments.Last() == paramsArg) { this.Write(JS.Types.Bridge.Reflection.APPLYCONSTRUCTOR + "("); applyCtor = true; } } if (String.IsNullOrEmpty(customCtor) || (isObjectLiteral && isPlainObjectCtor)) { if (!applyCtor && !isObjectLiteral) { this.WriteNew(); } var typerr = this.Emitter.Resolver.ResolveNode(objectCreateExpression.Type, this.Emitter).Type; var td = typerr.GetDefinition(); var isGeneric = typerr.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(typerr, this.Emitter) || td != null && Validator.IsVirtualTypeStatic(td); if (isGeneric && !applyCtor) { this.WriteOpenParentheses(); } objectCreateExpression.Type.AcceptVisitor(this.Emitter); if (isGeneric && !applyCtor) { this.WriteCloseParentheses(); } } else { this.Write(customCtor); } if (!isTypeParam && type.Methods.Count(m => m.IsConstructor && !m.IsStatic) > (type.IsValueType || isObjectLiteral ? 0 : 1)) { var member = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter)).Member; if (!this.Emitter.Validator.IsExternalType(type) || member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.NameAttribute")) { this.WriteDot(); var name = OverloadsCollection.Create(this.Emitter, member).GetOverloadName(); this.Write(name); } } if (applyCtor) { this.Write(", "); } else { this.WriteOpenParentheses(); } new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, objectCreateExpression, -1).Emit(); this.WriteCloseParentheses(); } if (hasInitializer) { if (isObjectLiteral && isPlainMode) { this.WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, true); } else { foreach (Expression item in elements) { this.WriteInitializerExpression(item, tempVar); } } this.WriteComma(); this.Write(tempVar); this.WriteCloseParentheses(); this.RemoveTempVar(tempVar); } } //Helpers.CheckValueTypeClone(invocationResolveResult, this.ObjectCreateExpression, this, pos); }
protected void VisitObjectCreateExpression() { ObjectCreateExpression objectCreateExpression = this.ObjectCreateExpression; var resolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression.Type, this.Emitter) as TypeResolveResult; if (resolveResult != null && resolveResult.Type.Kind == TypeKind.Enum) { this.Write("(0)"); return; } bool isTypeParam = resolveResult != null && resolveResult.Type.Kind == TypeKind.TypeParameter; var invocationResolveResult = this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter) as InvocationResolveResult; if (isTypeParam && invocationResolveResult != null && invocationResolveResult.Member.Parameters.Count == 0) { this.Write(JS.Funcs.BRIDGE_CREATEINSTANCE); this.WriteOpenParentheses(); this.Write(resolveResult.Type.Name); this.WriteCloseParentheses(); return; } var type = isTypeParam ? null : this.Emitter.GetTypeDefinition(objectCreateExpression.Type); if (type != null && type.BaseType != null && type.BaseType.FullName == "System.MulticastDelegate") { bool wrap = false; var parent = objectCreateExpression.Parent as InvocationExpression; if (parent != null && parent.Target == objectCreateExpression) { wrap = true; } if (wrap) { this.WriteOpenParentheses(); } objectCreateExpression.Arguments.First().AcceptVisitor(this.Emitter); if (wrap) { this.WriteCloseParentheses(); } return; } var argsInfo = new ArgumentsInfo(this.Emitter, objectCreateExpression); var argsExpressions = argsInfo.ArgumentsExpressions; var paramsArg = argsInfo.ParamsExpression; string inlineCode = null; if (invocationResolveResult != null) { if (invocationResolveResult.Member.DeclaringType.Kind == TypeKind.Struct && objectCreateExpression.Arguments.Count == 0) { var ctors = invocationResolveResult.Member.DeclaringType.GetConstructors(c => c.Parameters.Count == 1); var defCtor = ctors.FirstOrDefault(c => c.Parameters.First().Type.FullName == "System.Runtime.CompilerServices.DummyTypeUsedToAddAttributeToDefaultValueTypeConstructor"); if (defCtor != null) { inlineCode = this.Emitter.GetInline(defCtor); } } if (inlineCode == null) { inlineCode = this.Emitter.GetInline(invocationResolveResult.Member); } } var customCtor = isTypeParam ? "" : (this.Emitter.Validator.GetCustomConstructor(type) ?? ""); var hasInitializer = !objectCreateExpression.Initializer.IsNull && objectCreateExpression.Initializer.Elements.Count > 0; bool isCollectionInitializer = false; AstNodeCollection <Expression> elements = null; if (hasInitializer) { elements = objectCreateExpression.Initializer.Elements; isCollectionInitializer = elements.Count > 0 && elements.First() is ArrayInitializerExpression; } if (inlineCode == null && Regex.Match(customCtor, @"\s*\{\s*\}\s*").Success) { this.WriteOpenBrace(); this.WriteSpace(); this.WriteObjectInitializer(objectCreateExpression.Initializer.Elements, this.Emitter.AssemblyInfo.PreserveMemberCase, type, invocationResolveResult); this.WriteSpace(); this.WriteCloseBrace(); } else { if (hasInitializer) { this.Write(JS.Funcs.BRIDGE_MERGE); this.WriteOpenParentheses(); } if (inlineCode != null) { new InlineArgumentsBlock(this.Emitter, argsInfo, inlineCode).Emit(); } else { var ctorMember = ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter)).Member; var expandParams = ctorMember.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute"); bool applyCtor = false; if (expandParams) { var ctor_rr = this.Emitter.Resolver.ResolveNode(paramsArg, this.Emitter); if (ctor_rr.Type.Kind == TypeKind.Array && !(paramsArg is ArrayCreateExpression) && objectCreateExpression.Arguments.Last() == paramsArg) { this.Write("Bridge.Reflection.applyConstructor("); applyCtor = true; } } if (String.IsNullOrEmpty(customCtor)) { if (!applyCtor) { this.WriteNew(); } var typerr = this.Emitter.Resolver.ResolveNode(objectCreateExpression.Type, this.Emitter).Type; var isGeneric = typerr.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(typerr, this.Emitter); if (isGeneric && !applyCtor) { this.WriteOpenParentheses(); } objectCreateExpression.Type.AcceptVisitor(this.Emitter); if (isGeneric && !applyCtor) { this.WriteCloseParentheses(); } } else { this.Write(customCtor); } if (!isTypeParam && !this.Emitter.Validator.IsIgnoreType(type) && type.Methods.Count(m => m.IsConstructor && !m.IsStatic) > (type.IsValueType ? 0 : 1)) { this.WriteDot(); var name = OverloadsCollection.Create(this.Emitter, ((InvocationResolveResult)this.Emitter.Resolver.ResolveNode(objectCreateExpression, this.Emitter)).Member).GetOverloadName(); if (name == JS.Funcs.CONSTRUCTOR) { name = JS.Funcs.DCONSTRUCTOR; } this.Write(name); } if (applyCtor) { this.Write(", "); } else { this.WriteOpenParentheses(); } new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, objectCreateExpression, -1).Emit(); this.WriteCloseParentheses(); } if (hasInitializer) { this.WriteComma(); bool needComma = false; if (isCollectionInitializer) { this.Write("["); this.WriteNewLine(); this.Indent(); } else { this.BeginBlock(); } List <string> inlineInit = new List <string>(); foreach (Expression item in elements) { if (needComma) { this.WriteComma(true); } needComma = true; inlineCode = ObjectCreateBlock.GetInlineInit(item, this); if (inlineCode != null) { inlineInit.Add(inlineCode); } else if (item is NamedExpression) { var namedExpression = (NamedExpression)item; new NameBlock(this.Emitter, namedExpression.Name, namedExpression, namedExpression.Expression, true).Emit(); } else if (item is NamedArgumentExpression) { var namedArgumentExpression = (NamedArgumentExpression)item; new NameBlock(this.Emitter, namedArgumentExpression.Name, namedArgumentExpression, namedArgumentExpression.Expression, true).Emit(); } else if (item is ArrayInitializerExpression) { var arrayInitializer = (ArrayInitializerExpression)item; this.Write("["); foreach (var el in arrayInitializer.Elements) { this.EnsureComma(false); el.AcceptVisitor(this.Emitter); this.Emitter.Comma = true; } this.Write("]"); this.Emitter.Comma = false; } else if (item is IdentifierExpression) { var identifierExpression = (IdentifierExpression)item; new IdentifierBlock(this.Emitter, identifierExpression).Emit(); } } this.WriteNewLine(); if (isCollectionInitializer) { this.Outdent(); this.Write("]"); } else { this.EndBlock(); } if (inlineInit.Count > 0) { this.Write(", function () "); this.BeginBlock(); foreach (var init in inlineInit) { this.Write(init); this.WriteNewLine(); } this.EndBlock(); } this.WriteSpace(); this.WriteCloseParentheses(); } } //Helpers.CheckValueTypeClone(invocationResolveResult, this.ObjectCreateExpression, this, pos); }
protected virtual void WriteObjectInitializer(IEnumerable <Expression> expressions, TypeDefinition type, InvocationResolveResult rr, bool withCtor) { bool needComma = false; List <string> names = new List <string>(); var isObjectLiteral = this.Emitter.Validator.IsObjectLiteral(type); if (!withCtor && rr != null && this.ObjectCreateExpression.Arguments.Count > 0) { var args = this.ObjectCreateExpression.Arguments.ToList(); var arrIsOpen = false; for (int i = 0; i < args.Count; i++) { Expression expression = args[i]; var p = rr.Member.Parameters[i < rr.Member.Parameters.Count ? i : (rr.Member.Parameters.Count - 1)]; var name = p.Name; if (p.Type.FullName == "Bridge.ObjectInitializationMode" || p.Type.FullName == "Bridge.ObjectCreateMode") { continue; } if (needComma) { this.WriteComma(); } needComma = true; if (p.IsParams && !arrIsOpen) { arrIsOpen = true; this.Write("["); } this.Write(name, ": "); expression.AcceptVisitor(this.Emitter); names.Add(name); } if (arrIsOpen) { this.Write("]"); } } if (expressions != null) { foreach (Expression item in expressions) { NamedExpression namedExression = item as NamedExpression; NamedArgumentExpression namedArgumentExpression = item as NamedArgumentExpression; string name = namedExression != null ? namedExression.Name : namedArgumentExpression.Name; var itemrr = this.Emitter.Resolver.ResolveNode(item, this.Emitter) as MemberResolveResult; if (itemrr != null) { var oc = OverloadsCollection.Create(this.Emitter, itemrr.Member); bool forceObjectLiteral = itemrr.Member is IProperty && !itemrr.Member.Attributes.Any(attr => attr.AttributeType.FullName == "Bridge.NameAttribute") && !this.Emitter.Validator.IsObjectLiteral(itemrr.Member.DeclaringTypeDefinition); name = oc.GetOverloadName(isObjectLiteral: forceObjectLiteral); } if (needComma) { this.WriteComma(); } needComma = true; Expression expression = namedExression != null ? namedExression.Expression : namedArgumentExpression.Expression; this.WriteIdentifier(name, true, true); this.Write(": "); expression.AcceptVisitor(this.Emitter); names.Add(name); } } if (isObjectLiteral) { var key = BridgeTypes.GetTypeDefinitionKey(type); var tinfo = this.Emitter.Types.FirstOrDefault(t => t.Key == key); var mode = 0; if (rr != null) { if (rr.Member.Parameters.Count > 0) { var prm = rr.Member.Parameters.FirstOrDefault(p => p.Type.FullName == "Bridge.ObjectInitializationMode"); if (prm != null) { var prmIndex = rr.Member.Parameters.IndexOf(prm); var arg = rr.Arguments.FirstOrDefault(a => { if (a is NamedArgumentResolveResult) { return(((NamedArgumentResolveResult)a).ParameterName == prm.Name); } return(prmIndex == rr.Arguments.IndexOf(a)); }); if (arg != null && arg.ConstantValue != null && arg.ConstantValue is int) { mode = (int)arg.ConstantValue; } } } else if (type != null) { mode = this.Emitter.Validator.GetObjectInitializationMode(type); } } if (tinfo == null) { if (mode == 2) { var properties = rr.Member.DeclaringTypeDefinition.GetProperties(null, GetMemberOptions.IgnoreInheritedMembers); foreach (var prop in properties) { var name = OverloadsCollection.Create(this.Emitter, prop).GetOverloadName(); if (names.Contains(name)) { continue; } if (needComma) { this.WriteComma(); } needComma = true; this.WriteIdentifier(name, true, true); this.Write(": "); var argType = prop.ReturnType; var defValue = Inspector.GetDefaultFieldValue(argType, null); if (defValue == argType) { this.Write(Inspector.GetStructDefaultValue(argType, this.Emitter)); } else { this.Write(defValue); } } } return; } if (mode != 0) { var members = tinfo.InstanceConfig.Fields.Concat(tinfo.InstanceConfig.Properties); if (members.Any()) { foreach (var member in members) { if (mode == 1 && (member.VarInitializer == null || member.VarInitializer.Initializer.IsNull) && !member.IsPropertyInitializer) { continue; } var name = member.GetName(this.Emitter); if (names.Contains(name)) { continue; } if (needComma) { this.WriteComma(); } needComma = true; this.WriteIdentifier(name, true, true); this.Write(": "); var primitiveExpr = member.Initializer as PrimitiveExpression; if (mode == 2 && (member.Initializer == null || member.Initializer.IsNull) && !(member.VarInitializer == null || member.VarInitializer.Initializer.IsNull)) { var argType = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter).Type; var defValue = Inspector.GetDefaultFieldValue(argType, null); if (defValue == argType) { this.Write(Inspector.GetStructDefaultValue(argType, this.Emitter)); } else { this.Write(defValue); } } else { if (primitiveExpr != null && primitiveExpr.Value is AstType) { this.Write(Inspector.GetStructDefaultValue((AstType)primitiveExpr.Value, this.Emitter)); } else if (member.Initializer != null) { member.Initializer.AcceptVisitor(this.Emitter); } else { this.Write("null"); } } } } } } }
protected virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, bool setter) { var memberResult = this.Emitter.Resolver.ResolveNode(propertyDeclaration, this.Emitter) as MemberResolveResult; if (memberResult != null && (memberResult.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.FieldPropertyAttribute" || a.AttributeType.FullName == "Bridge.IgnoreAttribute" || a.AttributeType.FullName == "Bridge.ExternalAttribute") || (propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull))) { return; } if (!accessor.IsNull && this.Emitter.GetInline(accessor) == null) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); if (setter) { this.AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } XmlToJsDoc.EmitComment(this, this.PropertyDeclaration); var overloads = OverloadsCollection.Create(this.Emitter, propertyDeclaration, setter); string name = overloads.GetOverloadName(); this.Write((setter ? "set" : "get") + name); this.WriteColon(); this.WriteFunction(); this.WriteOpenParentheses(); this.Write(setter ? "value" : ""); this.WriteCloseParentheses(); this.WriteSpace(); var script = this.Emitter.GetScript(accessor); if (script == null) { accessor.Body.AcceptVisitor(this.Emitter); } else { this.BeginBlock(); foreach (var line in script) { this.Write(line); this.WriteNewLine(); } this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; } }
protected bool ResolveOperator(AssignmentExpression assignmentExpression, OperatorResolveResult orr, int initCount) { var method = orr != null ? orr.UserDefinedOperatorMethod : null; if (method != null) { var inline = this.Emitter.GetInline(method); if (!string.IsNullOrWhiteSpace(inline)) { if (this.Emitter.Writers.Count == initCount) { this.Write("= "); } new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, assignmentExpression, orr, method), inline).Emit(); if (this.Emitter.Writers.Count > initCount) { this.PopWriter(); } return(true); } else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { if (this.Emitter.Writers.Count == initCount) { this.Write("= "); } if (orr.IsLiftedOperator) { this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.lift("); } this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName()); if (orr.IsLiftedOperator) { this.WriteComma(); } else { this.WriteOpenParentheses(); } new ExpressionListBlock(this.Emitter, new Expression[] { assignmentExpression.Left, assignmentExpression.Right }, null).Emit(); this.WriteCloseParentheses(); if (this.Emitter.Writers.Count > initCount) { this.PopWriter(); } return(true); } } return(false); }
protected void VisitIdentifierExpression() { IdentifierExpression identifierExpression = this.IdentifierExpression; int pos = this.Emitter.Output.Length; ResolveResult resolveResult = null; resolveResult = this.Emitter.Resolver.ResolveNode(identifierExpression, this.Emitter); var id = identifierExpression.Identifier; var isResolved = resolveResult != null && !(resolveResult is ErrorResolveResult); var memberResult = resolveResult as MemberResolveResult; if (this.Emitter.Locals != null && this.Emitter.Locals.ContainsKey(id)) { if (this.Emitter.LocalsMap != null && this.Emitter.LocalsMap.ContainsKey(id) && !(identifierExpression.Parent is DirectionExpression)) { this.Write(this.Emitter.LocalsMap[id]); } else if (this.Emitter.LocalsNamesMap != null && this.Emitter.LocalsNamesMap.ContainsKey(id)) { this.Write(this.Emitter.LocalsNamesMap[id]); } else { this.Write(id); } Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos); return; } if (resolveResult is TypeResolveResult) { this.Write(BridgeTypes.ToJsName(resolveResult.Type, this.Emitter)); /*if (this.Emitter.Validator.IsIgnoreType(resolveResult.Type.GetDefinition()) || resolveResult.Type.Kind == TypeKind.Enum) * { * this.Write(BridgeTypes.ToJsName(resolveResult.Type, this.Emitter)); * } * else * { * this.Write("Bridge.get(" + BridgeTypes.ToJsName(resolveResult.Type, this.Emitter) + ")"); * }*/ return; } string inlineCode = memberResult != null?this.Emitter.GetInline(memberResult.Member) : null; bool hasInline = !string.IsNullOrEmpty(inlineCode); bool hasThis = hasInline && inlineCode.Contains("{this}"); if (hasThis) { this.Write(""); var oldBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); if (memberResult.Member.IsStatic) { this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter)); /*if (!this.Emitter.Validator.IsIgnoreType(memberResult.Member.DeclaringTypeDefinition) && memberResult.Member.DeclaringTypeDefinition.Kind != TypeKind.Enum) * { * this.Write("(Bridge.get(" + BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter) + "))"); * } * else * { * this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter)); * }*/ } else { this.WriteThis(); } inlineCode = inlineCode.Replace("{this}", this.Emitter.Output.ToString()); this.Emitter.Output = oldBuilder; if (resolveResult is InvocationResolveResult) { this.PushWriter(inlineCode); } else { this.Write(inlineCode); } return; } if (hasInline && memberResult.Member.IsStatic) { if (resolveResult is InvocationResolveResult) { this.PushWriter(inlineCode); } else { this.Write(inlineCode); } return; } string appendAdditionalCode = null; if (memberResult != null && memberResult.Member is IMethod && !(memberResult is InvocationResolveResult) && !( identifierExpression.Parent is InvocationExpression && identifierExpression.NextSibling != null && identifierExpression.NextSibling.Role is TokenRole && ((TokenRole)identifierExpression.NextSibling.Role).Token == "(" ) ) { var resolvedMethod = (IMethod)memberResult.Member; bool isStatic = resolvedMethod != null && resolvedMethod.IsStatic; if (!isStatic) { var isExtensionMethod = resolvedMethod.IsExtensionMethod; this.Write(Bridge.Translator.Emitter.ROOT + "." + (isExtensionMethod ? Bridge.Translator.Emitter.DELEGATE_BIND_SCOPE : Bridge.Translator.Emitter.DELEGATE_BIND) + "("); this.WriteThis(); this.Write(", "); appendAdditionalCode = ")"; } } if (memberResult != null && memberResult.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(memberResult.Member) && this.Emitter.IsInlineConst(memberResult.Member)) { this.WriteScript(memberResult.ConstantValue); return; } if (memberResult != null && memberResult.Member.SymbolKind == SymbolKind.Property && memberResult.TargetResult.Type.Kind != TypeKind.Anonymous) { bool isStatement = false; string valueVar = null; if (this.Emitter.IsUnaryAccessor) { isStatement = identifierExpression.Parent is UnaryOperatorExpression && identifierExpression.Parent.Parent is ExpressionStatement; if (NullableType.IsNullable(memberResult.Type)) { isStatement = false; } if (!isStatement) { this.WriteOpenParentheses(); valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); } } this.WriteTarget(memberResult); if (!string.IsNullOrWhiteSpace(inlineCode)) { //this.Write(inlineCode); if (resolveResult is InvocationResolveResult || (memberResult.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment)) { this.PushWriter(inlineCode); } else { this.Write(inlineCode); } } else if (Helpers.IsFieldProperty(memberResult.Member, this.Emitter)) { this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter)); } else if (!this.Emitter.IsAssignment) { if (this.Emitter.IsUnaryAccessor) { bool isDecimal = Helpers.IsDecimalType(memberResult.Member.ReturnType, this.Emitter.Resolver); bool isLong = Helpers.Is64Type(memberResult.Member.ReturnType, this.Emitter.Resolver); bool isNullable = NullableType.IsNullable(memberResult.Member.ReturnType); if (isStatement) { this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, true)); this.WriteOpenParentheses(); if (isDecimal || isLong) { if (isNullable) { this.Write("Bridge.Nullable.lift1"); this.WriteOpenParentheses(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.WriteScript("inc"); } else { this.WriteScript("dec"); } this.WriteComma(); this.WriteTarget(memberResult); this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, false)); this.WriteOpenParentheses(); this.WriteCloseParentheses(); this.WriteCloseParentheses(); } else { this.WriteTarget(memberResult); this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, false)); this.WriteOpenParentheses(); this.WriteCloseParentheses(); this.WriteDot(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write("inc"); } else { this.Write("dec"); } this.WriteOpenParentheses(); this.WriteCloseParentheses(); } } else { this.WriteTarget(memberResult); this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, false)); this.WriteOpenParentheses(); this.WriteCloseParentheses(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write("+"); } else { this.Write("-"); } this.Write("1"); } this.WriteCloseParentheses(); } else { this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, false)); this.WriteOpenParentheses(); this.WriteCloseParentheses(); this.WriteComma(); this.WriteTarget(memberResult); this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, true)); this.WriteOpenParentheses(); if (isDecimal || isLong) { if (isNullable) { this.Write("Bridge.Nullable.lift1"); this.WriteOpenParentheses(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.WriteScript("inc"); } else { this.WriteScript("dec"); } this.WriteComma(); this.Write(valueVar); this.WriteCloseParentheses(); } else { this.Write(valueVar); this.WriteDot(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write("inc"); } else { this.Write("dec"); } this.WriteOpenParentheses(); this.WriteCloseParentheses(); } } else { this.Write(valueVar); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { this.Write("+"); } else { this.Write("-"); } this.Write("1"); } this.WriteCloseParentheses(); this.WriteComma(); if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.Decrement) { this.WriteTarget(memberResult); this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, false)); this.WriteOpenParentheses(); this.WriteCloseParentheses(); } else { this.Write(valueVar); } this.WriteCloseParentheses(); if (valueVar != null) { this.RemoveTempVar(valueVar); } } } else { this.Write(Helpers.GetPropertyRef(memberResult.Member, this.Emitter)); this.WriteOpenParentheses(); this.WriteCloseParentheses(); } } else if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign) { string trg; if (memberResult.Member.IsStatic) { trg = BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter); } else { trg = "this"; } this.PushWriter(string.Concat(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, true), "(", trg, ".", Helpers.GetPropertyRef(memberResult.Member, this.Emitter, false), "()", "{0})")); } else { this.PushWriter(Helpers.GetPropertyRef(memberResult.Member, this.Emitter, true) + "({0})"); } } else if (memberResult != null && memberResult.Member is DefaultResolvedEvent) { if (this.Emitter.IsAssignment && (this.Emitter.AssignmentType == AssignmentOperatorType.Add || this.Emitter.AssignmentType == AssignmentOperatorType.Subtract)) { this.WriteTarget(memberResult); if (!string.IsNullOrWhiteSpace(inlineCode)) { this.Write(inlineCode); } else { this.Write(this.Emitter.AssignmentType == AssignmentOperatorType.Add ? "add" : "remove"); this.Write( OverloadsCollection.Create(this.Emitter, memberResult.Member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName()); } this.WriteOpenParentheses(); } else { this.WriteTarget(memberResult); this.Write(this.Emitter.GetEntityName(memberResult.Member, true)); } } else { if (!string.IsNullOrWhiteSpace(inlineCode)) { this.Write(inlineCode); } else if (isResolved) { if (resolveResult is TypeResolveResult) { var typeResolveResult = (TypeResolveResult)resolveResult; var isNative = this.Emitter.Validator.IsIgnoreType(typeResolveResult.Type.GetDefinition()); this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter)); /*if (!isNative) * { * this.Write("Bridge.get(" + BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter)); * } * else * { * this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter)); * }*/ if (typeResolveResult.Type.TypeParameterCount > 0) { this.WriteOpenParentheses(); new TypeExpressionListBlock(this.Emitter, this.IdentifierExpression.TypeArguments).Emit(); this.WriteCloseParentheses(); } if (!isNative) { this.Write(")"); } } else if (resolveResult is LocalResolveResult) { var localResolveResult = (LocalResolveResult)resolveResult; this.Write(localResolveResult.Variable.Name); } else if (memberResult != null) { this.WriteTarget(memberResult); this.Write(OverloadsCollection.Create(this.Emitter, memberResult.Member).GetOverloadName()); } else { this.Write(resolveResult.ToString()); } } else { throw new EmitterException(identifierExpression, "Cannot resolve identifier: " + id); } } if (appendAdditionalCode != null) { this.Write(appendAdditionalCode); } Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos); }
private void HandleDecimal(ResolveResult resolveOperator, string variable) { if (this.AssignmentExpression.Operator == AssignmentOperatorType.Assign) { if (variable != null) { this.Write(variable); } else { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Right }, null).Emit(); } return; } var orr = resolveOperator as OperatorResolveResult; var method = orr != null ? orr.UserDefinedOperatorMethod : null; var assigmentType = Helpers.TypeOfAssignment(this.AssignmentExpression.Operator); if (orr != null && method == null) { var name = Helpers.GetBinaryOperatorMethodName(assigmentType); var type = NullableType.IsNullable(orr.Type) ? NullableType.GetUnderlyingType(orr.Type) : orr.Type; method = type.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault(); } if (method != null) { var inline = this.Emitter.GetInline(method); if (orr.IsLiftedOperator) { this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable."); string action = "lift2"; string op_name = null; switch (assigmentType) { case BinaryOperatorType.GreaterThan: op_name = "gt"; break; case BinaryOperatorType.GreaterThanOrEqual: op_name = "gte"; break; case BinaryOperatorType.Equality: op_name = "equals"; break; case BinaryOperatorType.InEquality: op_name = "ne"; break; case BinaryOperatorType.LessThan: op_name = "lt"; break; case BinaryOperatorType.LessThanOrEqual: op_name = "lte"; break; case BinaryOperatorType.Add: op_name = "add"; break; case BinaryOperatorType.Subtract: op_name = "sub"; break; case BinaryOperatorType.Multiply: op_name = "mul"; break; case BinaryOperatorType.Divide: op_name = "div"; break; case BinaryOperatorType.Modulus: op_name = "mod"; break; default: throw new ArgumentOutOfRangeException(); } this.Write(action); this.WriteOpenParentheses(); this.WriteScript(op_name); this.WriteComma(); if (variable != null) { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null).Emit(); } else { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null).Emit(); } this.WriteCloseParentheses(); } else if (!string.IsNullOrWhiteSpace(inline)) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, this.AssignmentExpression, orr, method), inline).Emit(); } else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName()); this.WriteOpenParentheses(); if (variable != null) { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left }, null).Emit(); this.Write(", " + variable); } else { new ExpressionListBlock(this.Emitter, new Expression[] { this.AssignmentExpression.Left, this.AssignmentExpression.Right }, null).Emit(); } this.WriteCloseParentheses(); } } }
private static JObject ConstructConstructorInfo(IMethod constructor, IEmitter emitter, bool includeDeclaringType, bool isGenericSpecialization, SyntaxTree tree) { var properties = MetadataUtils.GetCommonMemberInfoProperties(constructor, emitter, includeDeclaringType, isGenericSpecialization, tree); if (Helpers.IsNonScriptable(constructor)) { return(null); } properties.Add("t", (int)MemberTypes.Constructor); if (constructor.Parameters.Count > 0) { properties.Add("p", new JArray(constructor.Parameters.Select(p => new JRaw(MetadataUtils.GetTypeName(p.Type, emitter, isGenericSpecialization))))); } var parametersInfo = constructor.Parameters.Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("pi", new JArray(parametersInfo)); } var inline = emitter.GetInline(constructor); var typeDef = constructor.DeclaringTypeDefinition; IAttribute customCtor = null; if (typeDef != null) { customCtor = emitter.Validator.GetAttribute(typeDef.Attributes, Translator.Bridge_ASSEMBLY + ".ConstructorAttribute"); } if (string.IsNullOrEmpty(inline) && customCtor == null) { string sname; if (constructor.IsStatic || constructor.DeclaringType.Kind == TypeKind.Anonymous) { sname = JS.Funcs.CONSTRUCTOR; } else { sname = OverloadsCollection.Create(emitter, constructor).GetOverloadName(); } properties.Add("sn", sname); } if (constructor.IsStatic) { properties.Add("sm", true); } if (string.IsNullOrEmpty(inline) && constructor.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute")) { properties.Add("exp", true); } if (!string.IsNullOrEmpty(inline)) { var block = new InlineArgumentsBlock(emitter, new ArgumentsInfo(emitter, constructor), inline, constructor); var oldWriter = block.SaveWriter(); block.NewWriter(); block.EmitFunctionReference(true); var str = emitter.Output.ToString(); block.RestoreWriter(oldWriter); properties.Add("def", new JRaw(str)); } else if (customCtor != null) { inline = customCtor.PositionalArguments[0].ConstantValue.ToString(); if (Regex.Match(inline, @"\s*\{\s*\}\s*").Success) { var names = constructor.Parameters.Select(p => p.Name); StringBuilder sb = new StringBuilder("function (" + string.Join(", ", names.ToArray()) + ") { return {"); bool needComma = false; foreach (var name in names) { if (needComma) { sb.Append(", "); } needComma = true; sb.Append(name + ": " + name); } sb.Append("};}"); properties.Add("def", new JRaw(sb.ToString())); } else { var block = new InlineArgumentsBlock(emitter, new ArgumentsInfo(emitter, constructor), inline, constructor); var oldWriter = block.SaveWriter(); block.NewWriter(); block.EmitFunctionReference(true); var str = emitter.Output.ToString(); block.RestoreWriter(oldWriter); properties.Add("def", new JRaw(str)); } } return(properties); }
protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { foreach (var attrSection in methodDeclaration.Attributes) { foreach (var attr in attrSection.Attributes) { var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter); if (rr.Type.FullName == "Bridge.ExternalAttribute") { return; } else if (rr.Type.FullName == "Bridge.InitAttribute") { int initPosition = 0; if (attr.HasArgumentList) { if (attr.Arguments.Any()) { var argExpr = attr.Arguments.First(); var argrr = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter); if (argrr.ConstantValue is int) { initPosition = (int)argrr.ConstantValue; } } } if (initPosition > 0) { return; } } } } this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(methodDeclaration.Parameters, methodDeclaration.Body); var overloads = OverloadsCollection.Create(this.Emitter, methodDeclaration); XmlToJsDoc.EmitComment(this, this.MethodDeclaration); string name = overloads.GetOverloadName(false, null, true); if (Helpers.IsEntryPointMethod(this.Emitter, methodDeclaration)) { name = JS.Fields.MAIN; } this.Write(name); this.WriteColon(); this.WriteFunction(); this.EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration.TypeParameters.Count > 0 && Helpers.IsIgnoreGeneric(methodDeclaration, this.Emitter) ? null : methodDeclaration.TypeParameters, methodDeclaration); this.WriteSpace(); var script = this.Emitter.GetScript(methodDeclaration); if (script == null) { if (methodDeclaration.HasModifier(Modifiers.Async)) { new AsyncBlock(this.Emitter, methodDeclaration).Emit(); } else { methodDeclaration.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); this.WriteLines(script); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; }