private Expression GetDefaultFieldInitializer(AstType type) { return(new PrimitiveExpression(Inspector.GetDefaultFieldValue(type, this.Resolver), "?")); }
protected virtual void EmitInlineExpressionList(ArgumentsInfo argsInfo, string inline, bool asRef = false, bool isNull = false, bool?definition = null) { IEnumerable <NamedParamExpression> expressions = argsInfo.NamedExpressions; IEnumerable <TypeParamExpression> typeParams = argsInfo.TypeArguments; bool addClose = false; this.Write(""); if (asRef) { var withoutTypeParams = this.Method.TypeArguments.Count > 0 && this.Method.TypeArguments.All(t => t.Kind != TypeKind.TypeParameter); if (definition.HasValue) { withoutTypeParams = !definition.Value; } if (withoutTypeParams && (!this.Method.IsStatic || this.Method.IsExtensionMethod && this.TargetResolveResult is ThisResolveResult) && (this.TargetResolveResult is ThisResolveResult || this.TargetResolveResult == null) && (inline.Contains("{this}") || this.Method.IsStatic || this.Method.IsExtensionMethod && inline.Contains("{" + this.Method.Parameters.First().Name + "}"))) { this.Write(JS.Funcs.BRIDGE_BIND); this.Write("(this, "); addClose = true; } this.Write("function ("); this.EmitMethodParameters(this.Method, this.Method.Parameters, withoutTypeParams ? null : this.Method.TypeParameters, isNull); this.Write(") { return "); } bool needExpand = false; bool expandParams = false; string paramsName = null; IType paramsType = null; int paramsIndex = 0; if (argsInfo.ResolveResult != null) { var paramsParam = argsInfo.ResolveResult.Member.Parameters.FirstOrDefault(p => p.IsParams); if (paramsParam != null) { paramsIndex = argsInfo.ResolveResult.Member.Parameters.IndexOf(paramsParam); paramsName = paramsParam.Name; paramsType = paramsParam.Type; } expandParams = argsInfo.ResolveResult.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute"); } else if (argsInfo.Method != null) { var paramsParam = argsInfo.Method.Parameters.FirstOrDefault(p => p.IsParams); if (paramsParam != null) { paramsIndex = argsInfo.Method.Parameters.IndexOf(paramsParam); paramsName = paramsParam.Name; paramsType = paramsParam.Type; } expandParams = argsInfo.Method.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute"); } if (paramsName != null) { var matches = _formatArg.Matches(inline); bool ignoreArray = false; foreach (Match m in matches) { if (m.Groups[2].Value == paramsName) { bool isRaw = m.Groups[1].Success && m.Groups[1].Value == "*"; ignoreArray = isRaw || argsInfo.ParamsExpression == null; string modifier = m.Groups[1].Success ? m.Groups[4].Value : null; if (modifier == "array") { ignoreArray = false; } break; } } if (expandParams) { ignoreArray = true; } if (argsInfo.ResolveResult is CSharpInvocationResolveResult) { needExpand = !((CSharpInvocationResolveResult)argsInfo.ResolveResult).IsExpandedForm; } if (needExpand && ignoreArray && !asRef) { IList <Expression> exprs = this.GetExpressionsByKey(expressions, paramsName); if (exprs.Count == 1 && exprs[0] != null && exprs[0].Parent != null) { var exprrr = this.Emitter.Resolver.ResolveNode(exprs[0], this.Emitter); if (exprrr.Type.Kind == TypeKind.Array) { var match = _inlineMethod.Match(inline); if (match.Success) { string target = null; var methodName = match.Groups[1].Value; if (methodName.Contains(".")) { target = methodName.LeftOfRightmostOf('.'); } string args = match.Groups[2].Value; StringBuilder sb = new StringBuilder(); sb.Append(methodName); sb.Append("."); sb.Append(JS.Funcs.APPLY); sb.Append("("); sb.Append(target ?? "null"); if (args.Contains(",")) { sb.Append(", ["); sb.Append(args.LeftOfRightmostOf(',').Trim()); sb.Append("].concat("); sb.Append(args.RightOfRightmostOf(',').Trim()); sb.Append(")"); } else { sb.Append(","); sb.Append(args); } sb.Append(")"); inline = inline.Remove(match.Index, match.Length); inline = inline.Insert(match.Index, sb.ToString()); } } } } } var r = InlineArgumentsBlock._formatArg.Matches(inline); List <Match> keyMatches = new List <Match>(); foreach (Match keyMatch in r) { keyMatches.Add(keyMatch); } var tempVars = new Dictionary <string, string>(); var tempMap = new Dictionary <string, string>(); inline = _formatArg.Replace(inline, delegate(Match m) { if (this.IgnoreRange != null && m.Index >= this.IgnoreRange[0] && m.Index <= this.IgnoreRange[1]) { return(m.Value); } int count = this.Emitter.Writers.Count; string key = m.Groups[2].Value; bool isRaw = m.Groups[1].Success && m.Groups[1].Value == "*"; bool ignoreArray = isRaw || argsInfo.ParamsExpression == null; string modifier = m.Groups[1].Success ? m.Groups[4].Value : null; bool isSimple = false; var tempKey = key + ":" + modifier ?? ""; if (tempMap.ContainsKey(tempKey)) { return(tempMap[tempKey]); } if (!string.IsNullOrWhiteSpace(modifier) && !this.allowedModifiers.Contains(modifier)) { return(m.Value); } if (modifier == "array") { ignoreArray = false; } StringBuilder oldSb = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); if (modifier == "module") { IList <Expression> exprs = this.GetExpressionsByKey(expressions, key); if (exprs.Count > 0) { var amd = new List <string>(); var cjs = new List <string>(); foreach (var expr in exprs) { var rr = this.Emitter.Resolver.ResolveNode(expr, this.Emitter) as TypeOfResolveResult; if (rr == null) { throw new EmitterException(expr, "Module.Load supports typeof expression only"); } var bridgeType = this.Emitter.BridgeTypes.Get(rr.ReferencedType, true); Module module = null; if (bridgeType.TypeInfo == null) { BridgeTypes.EnsureModule(bridgeType); module = bridgeType.Module; } else { module = bridgeType.TypeInfo.Module; } AddModuleByType(amd, cjs, module); } this.Write("{"); if (amd.Count > 0) { this.Write("amd: "); this.Write(this.Emitter.ToJavaScript(amd.ToArray())); if (cjs.Count > 0) { this.Write(", "); } } if (cjs.Count > 0) { this.Write("cjs: "); this.Write(this.Emitter.ToJavaScript(cjs.ToArray())); } if (!string.IsNullOrWhiteSpace(this.Emitter.AssemblyInfo.Loader.FunctionName)) { this.Write(", "); this.Write(this.Emitter.ToJavaScript(this.Emitter.AssemblyInfo.Loader.FunctionName)); } this.Write("}, function () { "); var idx = 0; var list = amd.Concat(cjs); foreach (var moduleName in list) { this.Write(moduleName); this.Write(" = arguments["); this.Write(idx++); this.Write("];"); } this.Write(" }"); } } else if (asRef) { if (Regex.IsMatch(key, "^\\d+$")) { var index = int.Parse(key); key = this.Method.Parameters[index].Name; } if (modifier == "type") { this.Write(JS.Funcs.BRIDGE_GET_TYPE + "("); } if (key == "this") { if (isNull) { isSimple = true; this.Write(JS.Vars.T); } else if (this.Method.IsExtensionMethod && this.TargetResolveResult is TypeResolveResult) { isSimple = true; this.WriteParamName(this.Method.Parameters.First().Name); } else if (argsInfo.Expression is MemberReferenceExpression) { var trg = ((MemberReferenceExpression)argsInfo.Expression).Target; if (trg is BaseReferenceExpression) { isSimple = true; this.Write("this"); } else { isSimple = this.IsSimpleExpression(trg); trg.AcceptVisitor(this.Emitter); } } else { this.Write("this"); } } else if (this.Method.IsExtensionMethod && key == this.Method.Parameters.First().Name) { if (this.TargetResolveResult is TypeResolveResult) { isSimple = true; this.WriteParamName(key); } else if (argsInfo.Expression is MemberReferenceExpression) { var trg = ((MemberReferenceExpression)argsInfo.Expression).Target; if (trg is BaseReferenceExpression) { isSimple = true; this.Write("this"); } else { isSimple = this.IsSimpleExpression(trg); trg.AcceptVisitor(this.Emitter); } } else { isSimple = true; this.WriteParamName(key); } } else if (paramsName == key && !ignoreArray) { isSimple = true; this.Write(JS.Types.ARRAY + "." + JS.Fields.PROTOTYPE + "." + JS.Funcs.SLICE); this.WriteCall("(" + JS.Vars.ARGUMENTS + ", " + paramsIndex + ")"); } else { isSimple = true; this.WriteParamName(key); } if (modifier == "type") { this.Write(")"); } } else if (key == "this" || key == argsInfo.ThisName || (key == "0" && argsInfo.IsExtensionMethod)) { if (modifier == "type") { AstNode node = null; if (argsInfo.ThisArgument is AstNode) { node = (AstNode)argsInfo.ThisArgument; } else { node = argsInfo.Expression; } if (node != null) { var rr = this.Emitter.Resolver.ResolveNode(node, this.Emitter); var type = rr.Type; var mrr = rr as MemberResolveResult; if (mrr != null && mrr.Member.ReturnType.Kind != TypeKind.Enum && mrr.TargetResult != null) { type = mrr.TargetResult.Type; } bool needName = this.NeedName(type); if (needName) { isSimple = true; this.Write(BridgeTypes.ToJsName(type, this.Emitter)); } else { string thisValue = argsInfo.GetThisValue(); if (thisValue != null) { if (type.Kind == TypeKind.TypeParameter && !Helpers.IsIgnoreGeneric(((ITypeParameter)type).Owner, this.Emitter)) { thisValue = thisValue + ", " + type.Name; } this.Write(JS.Funcs.BRIDGE_GET_TYPE + "(" + thisValue + ")"); } } } } else { string thisValue = argsInfo.GetThisValue(); if (thisValue != null) { isSimple = true; this.Write(thisValue); } } } else { IList <Expression> exprs = this.GetExpressionsByKey(expressions, key); if (exprs.Count > 0) { if (modifier == "type") { IType type = null; if (paramsName == key && paramsType != null) { type = paramsType; } else { var rr = this.Emitter.Resolver.ResolveNode(exprs[0], this.Emitter); type = rr.Type; } bool needName = this.NeedName(type); this.WriteGetType(needName, type, exprs[0], modifier); isSimple = true; } else if (modifier == "tmp") { var tmpVarName = this.GetTempVarName(); var nameExpr = exprs[0] as PrimitiveExpression; if (nameExpr == null) { throw new EmitterException(exprs[0], "Primitive expression is required"); } Emitter.NamedTempVariables[nameExpr.LiteralValue] = tmpVarName; Write(tmpVarName); isSimple = true; } else if (modifier == "version") { var versionTypeExp = exprs != null && exprs.Any() ? exprs[0] : null; var versionType = 0; if (versionTypeExp != null) { var versionTypePrimitiveExp = versionTypeExp as PrimitiveExpression; if (versionTypePrimitiveExp != null && versionTypePrimitiveExp.Value is int) { versionType = (int)versionTypePrimitiveExp.Value; } else { var rr = this.Emitter.Resolver.ResolveNode(versionTypeExp, this.Emitter); if (rr != null && rr.ConstantValue != null && rr.ConstantValue is int) { versionType = (int)rr.ConstantValue; } } } string version; if (versionType == 0) { version = this.Emitter.Translator.GetVersionContext().Assembly.Version; } else { version = this.Emitter.Translator.GetVersionContext().Compiler.Version; } Write("\"", version, "\""); isSimple = true; } else if (modifier == "gettmp") { var nameExpr = exprs[0] as PrimitiveExpression; if (nameExpr == null) { throw new EmitterException(exprs[0], "Primitive expression is required"); } if (!Emitter.NamedTempVariables.ContainsKey(nameExpr.LiteralValue)) { throw new EmitterException(exprs[0], "Primitive expression is required"); } var tmpVarName = Emitter.NamedTempVariables[nameExpr.LiteralValue]; Write(tmpVarName); isSimple = true; } else if (modifier == "body") { var lambdaExpr = exprs[0] as LambdaExpression; if (lambdaExpr == null) { throw new EmitterException(exprs[0], "Lambda expression is required"); } var writer = this.SaveWriter(); this.NewWriter(); lambdaExpr.Body.AcceptVisitor(this.Emitter); var s = this.Emitter.Output.ToString(); this.RestoreWriter(writer); this.Write(this.WriteIndentToString(s)); } else if (exprs.Count > 1 || paramsName == key) { if (needExpand) { ignoreArray = true; } if (!ignoreArray) { this.Write("["); } if (exprs.Count == 1 && exprs[0] == null) { isSimple = true; this.Write("null"); } else { new ExpressionListBlock(this.Emitter, exprs, null, null, 0).Emit(); } if (!ignoreArray) { this.Write("]"); } } else { string s; if (exprs[0] != null) { var writer = this.SaveWriter(); this.NewWriter(); var directExpr = exprs[0] as DirectionExpression; if (directExpr != null) { var rr = this.Emitter.Resolver.ResolveNode(exprs[0], this.Emitter) as ByReferenceResolveResult; if (rr != null && !(rr.ElementResult is LocalResolveResult)) { this.Write(JS.Funcs.BRIDGE_REF + "("); this.Emitter.IsRefArg = true; exprs[0].AcceptVisitor(this.Emitter); this.Emitter.IsRefArg = false; if (this.Emitter.Writers.Count != count) { this.PopWriter(); count = this.Emitter.Writers.Count; } this.Write(")"); } else { exprs[0].AcceptVisitor(this.Emitter); } } else if (modifier == "plain") { var an = exprs[0] as AnonymousTypeCreateExpression; if (an == null) { this.Write(JS.Funcs.BRIDGE_TOPLAIN); this.WriteOpenParentheses(); exprs[0].AcceptVisitor(this.Emitter); this.Write(")"); } else { new AnonymousTypeCreateBlock(this.Emitter, an, true).Emit(); } } else { isSimple = this.IsSimpleExpression(exprs[0]); exprs[0].AcceptVisitor(this.Emitter); } s = this.Emitter.Output.ToString(); this.RestoreWriter(writer); if (modifier == "raw") { s = s.Trim('"'); } } else { isSimple = true; s = "null"; } this.Write(this.WriteIndentToString(s)); } } else if (this.ArgumentsInfo.Attribute != null) { var results = this.GetResolveResultByKey(key); if (results.Count > 1 || paramsName == key) { if (needExpand) { ignoreArray = true; } if (!ignoreArray) { this.Write("["); } if (exprs.Count == 1 && results[0].IsCompileTimeConstant && results[0].ConstantValue == null) { isSimple = true; this.Write("null"); } else { bool needComma = false; foreach (ResolveResult item in results) { if (needComma) { this.WriteComma(); } needComma = true; isSimple = this.IsSimpleResolveResult(item); AttributeCreateBlock.WriteResolveResult(item, this); } } if (!ignoreArray) { this.Write("]"); } } else { string s; if (results[0] != null) { var writer = this.SaveWriter(); this.NewWriter(); isSimple = this.IsSimpleResolveResult(results[0]); AttributeCreateBlock.WriteResolveResult(results[0], this); s = this.Emitter.Output.ToString(); this.RestoreWriter(writer); if (modifier == "raw") { s = s.Trim('"'); } } else { s = "null"; } this.Write(this.WriteIndentToString(s)); } } else if (this.ArgumentsInfo.StringArguments != null) { var results = this.GetStringArgumentByKey(key); if (results.Count > 1 || paramsName == key) { if (needExpand) { ignoreArray = true; } if (!ignoreArray) { this.Write("["); } bool needComma = false; foreach (string item in results) { if (needComma) { this.WriteComma(); } needComma = true; this.Write(item); } if (!ignoreArray) { this.Write("]"); } } else { string s; if (results[0] != null) { s = results[0]; if (modifier == "raw") { s = s.Trim('"'); } } else { s = "null"; } this.Write(s); } } else if (typeParams != null) { var type = this.GetAstTypeByKey(typeParams, key); if (type != null) { if (modifier == "default" || modifier == "defaultFn") { var def = Inspector.GetDefaultFieldValue(type, this.Emitter.Resolver); this.GetDefaultValue(def, modifier); } else { type.AcceptVisitor(this.Emitter); } } else { var iType = this.GetTypeByKey(typeParams, key); if (iType != null) { if (modifier == "default" || modifier == "defaultFn") { var def = Inspector.GetDefaultFieldValue(iType.IType, iType.AstType); this.GetDefaultValue(def, modifier); } else { new CastBlock(this.Emitter, iType.IType).Emit(); } } } } } if (this.Emitter.Writers.Count != count) { this.PopWriter(); } string replacement = this.Emitter.Output.ToString(); this.Emitter.Output = oldSb; if (!isSimple && keyMatches.Count(keyMatch => { string key1 = keyMatch.Groups[2].Value; string modifier1 = keyMatch.Groups[1].Success ? keyMatch.Groups[4].Value : null; return(key == key1 && modifier1 == modifier); }) > 1) { var t = this.GetTempVarName(); tempVars.Add(t, replacement); tempMap[tempKey] = t; return(t); } return(replacement); }); if (tempVars.Count > 0) { StringBuilder sb = new StringBuilder(); sb.Append("("); foreach (var tempVar in tempVars) { sb.Append(tempVar.Key); sb.Append("="); sb.Append(tempVar.Value); sb.Append(", "); } sb.Append(inline); sb.Append(")"); inline = sb.ToString(); } this.Write(inline); if (asRef) { this.Write("; }"); if (addClose) { this.Write(")"); } } }
protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat) { bool hasProperties = this.HasProperties(objectName, members); int pos = 0; IWriterInfo writer = null; bool beginBlock = false; if (hasProperties && objectName != null && !this.IsObjectLiteral) { beginBlock = true; pos = this.Emitter.Output.Length; writer = this.SaveWriter(); this.EnsureComma(); this.Write(objectName); this.WriteColon(); this.BeginBlock(); } bool isProperty = JS.Fields.PROPERTIES == objectName; bool isField = JS.Fields.FIELDS == objectName; int count = 0; foreach (var member in members) { object constValue = null; bool isPrimitive = false; var primitiveExpr = member.Initializer as PrimitiveExpression; bool write = false; bool writeScript = false; if (primitiveExpr != null) { //isPrimitive = true; constValue = primitiveExpr.Value; ResolveResult rr = null; if (member.VarInitializer != null) { rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter); } else { rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter); } if (rr != null && rr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue); writeScript = true; } } if (constValue is RawValue) { constValue = constValue.ToString(); write = true; writeScript = false; } var isNull = member.Initializer.IsNull || member.Initializer is NullReferenceExpression || member.Initializer.Parent == null; if (!isNull && !isPrimitive) { var constrr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter); if (constrr != null && constrr.IsCompileTimeConstant) { //isPrimitive = true; constValue = constrr.ConstantValue; var expectedType = this.Emitter.Resolver.Resolver.GetExpectedType(member.Initializer); if (!expectedType.Equals(constrr.Type) && expectedType.Kind != TypeKind.Dynamic) { try { constValue = Convert.ChangeType(constValue, ReflectionHelper.GetTypeCode(expectedType)); } catch (Exception) { this.Emitter.Log.Warn($"FieldBlock: Convert.ChangeType is failed. Value type: {constrr.Type.FullName}, Target type: {expectedType.FullName}"); } } if (constrr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, constrr.Type, constrr.ConstantValue); } writeScript = true; } } var isNullable = false; if (isPrimitive && constValue is AstType) { var itype = this.Emitter.Resolver.ResolveNode((AstType)constValue, this.Emitter); if (NullableType.IsNullable(itype.Type)) { isNullable = true; } } string tpl = null; IMember templateMember = null; MemberResolveResult init_rr = null; if (isField && member.VarInitializer != null) { init_rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter) as MemberResolveResult; tpl = init_rr != null?this.Emitter.GetInline(init_rr.Member) : null; if (tpl != null) { templateMember = init_rr.Member; } } bool isAutoProperty = false; if (isProperty) { var member_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult; var property = (IProperty)member_rr.Member; isAutoProperty = Helpers.IsAutoProperty(property); } bool written = false; if (!isNull && (!isPrimitive || constValue is AstType || tpl != null) && !(isProperty && !IsObjectLiteral && !isAutoProperty)) { string value = null; bool needContinue = false; string defValue = ""; if (!isPrimitive) { var oldWriter = this.SaveWriter(); this.NewWriter(); member.Initializer.AcceptVisitor(this.Emitter); value = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); ResolveResult rr = null; AstType astType = null; if (member.VarInitializer != null) { rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter); } else { astType = member.Entity.ReturnType; rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter); } constValue = Inspector.GetDefaultFieldValue(rr.Type, astType); if (rr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue); } isNullable = NullableType.IsNullable(rr.Type); needContinue = constValue is IType; writeScript = true; /*if (needContinue && !(member.Initializer is ObjectCreateExpression)) * { * defValue = " || " + Inspector.GetStructDefaultValue((IType)constValue, this.Emitter); * }*/ } else if (constValue is AstType) { value = isNullable ? "null" : Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter); constValue = value; write = true; needContinue = !isProperty && !isNullable; } var name = member.GetName(this.Emitter); bool isValidIdentifier = Helpers.IsValidIdentifier(name); if (isProperty && isPrimitive) { constValue = "null"; if (this.IsObjectLiteral) { written = true; if (isValidIdentifier) { this.Write(string.Format("this.{0} = {1};", name, value)); } else { this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } this.WriteNewLine(); } else { this.Injectors.Add(string.Format(name.StartsWith("\"") || !isValidIdentifier ? "this[{0}] = {1};" : "this.{0} = {1};", isValidIdentifier ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } } else { if (this.IsObjectLiteral) { written = true; if (isValidIdentifier) { this.Write(string.Format("this.{0} = {1};", name, value + defValue)); } else { this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue)); } this.WriteNewLine(); } else if (tpl != null) { if (!tpl.Contains("{0}")) { tpl = tpl + " = {0};"; } string v = null; if (!isNull && (!isPrimitive || constValue is AstType)) { v = value + defValue; } else { if (write) { v = constValue != null?constValue.ToString() : ""; } else if (writeScript) { v = AbstractEmitterBlock.ToJavaScript(constValue, this.Emitter); } else { var oldWriter = this.SaveWriter(); this.NewWriter(); member.Initializer.AcceptVisitor(this.Emitter); v = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); } } tpl = Helpers.ConvertTokens(this.Emitter, tpl, templateMember); tpl = tpl.Replace("{this}", "this").Replace("{0}", v); if (!tpl.EndsWith(";")) { tpl += ";"; } this.Injectors.Add(tpl); } else { var rr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter) as CSharpInvocationResolveResult; bool isDefaultInstance = rr != null && rr.Member.SymbolKind == SymbolKind.Constructor && rr.Arguments.Count == 0 && rr.InitializerStatements.Count == 0 && rr.Type.Kind == TypeKind.Struct; if (!isDefaultInstance) { if (isField && !isValidIdentifier) { this.Injectors.Add(string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue)); } else { this.Injectors.Add(string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value + defValue)); } } } } } count++; if (written) { continue; } bool withoutTypeParams = true; MemberResolveResult m_rr = null; if (member.Entity != null) { m_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult; if (m_rr != null) { withoutTypeParams = OverloadsCollection.ExcludeTypeParameterForDefinition(m_rr); } } var mname = member.GetName(this.Emitter, withoutTypeParams); if (this.TypeInfo.IsEnum && m_rr != null) { mname = this.Emitter.GetEntityName(m_rr.Member); } bool isValid = Helpers.IsValidIdentifier(mname); if (!isValid) { if (this.IsObjectLiteral) { mname = "[" + AbstractEmitterBlock.ToJavaScript(mname, this.Emitter) + "]"; } else { mname = AbstractEmitterBlock.ToJavaScript(mname, this.Emitter); } } if (this.IsObjectLiteral) { this.WriteThis(); if (isValid) { this.WriteDot(); } this.Write(mname); this.Write(" = "); } else { this.EnsureComma(); XmlToJsDoc.EmitComment(this, member.Entity, null, member.Entity is FieldDeclaration ? member.VarInitializer : null); this.Write(mname); this.WriteColon(); } bool close = false; if (isProperty && !IsObjectLiteral && !isAutoProperty) { var oldTempVars = this.Emitter.TempVariables; this.BeginBlock(); new VisitorPropertyBlock(this.Emitter, (PropertyDeclaration)member.Entity).Emit(); this.WriteNewLine(); this.EndBlock(); this.Emitter.Comma = true; this.Emitter.TempVariables = oldTempVars; continue; } if (constValue is AstType || constValue is IType) { this.Write("null"); if (!isNullable) { var name = member.GetName(this.Emitter); bool isValidIdentifier = Helpers.IsValidIdentifier(name); var value = constValue is AstType?Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter) : Inspector.GetStructDefaultValue((IType)constValue, this.Emitter); if (!isValidIdentifier) { this.Injectors.Insert(BeginCounter++, string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } else { this.Injectors.Insert(BeginCounter++, string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value)); } } } else if (write) { this.Write(constValue); } else if (writeScript) { this.WriteScript(constValue); } else { member.Initializer.AcceptVisitor(this.Emitter); } if (close) { this.Write(" }"); } if (this.IsObjectLiteral) { this.WriteSemiColon(true); } this.Emitter.Comma = true; } if (count > 0 && objectName != null && !IsObjectLiteral) { this.WriteNewLine(); this.EndBlock(); } else if (beginBlock) { this.Emitter.IsNewLine = writer.IsNewLine; this.Emitter.ResetLevel(writer.Level); this.Emitter.Comma = writer.Comma; this.Emitter.Output.Length = pos; } return(count > 0); }
protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat) { bool hasProperties = this.HasProperties(objectName, members); if (hasProperties && objectName != null && !this.IsObjectLiteral) { this.EnsureComma(); this.Write(objectName); this.WriteColon(); this.BeginBlock(); } bool isProperty = JS.Fields.PROPERTIES == objectName; bool isField = objectName == null; int count = 0; foreach (var member in members) { object constValue = null; bool isPrimitive = false; var primitiveExpr = member.Initializer as PrimitiveExpression; bool write = false; bool writeScript = false; if (primitiveExpr != null) { isPrimitive = true; constValue = primitiveExpr.Value; ResolveResult rr = null; if (member.VarInitializer != null) { rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter); } else { rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter); } if (rr != null && rr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue); writeScript = true; } } if (constValue is RawValue) { constValue = constValue.ToString(); write = true; writeScript = false; } var isNull = member.Initializer.IsNull || member.Initializer is NullReferenceExpression; if (!isNull && !isPrimitive) { var constrr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter); if (constrr != null && constrr.IsCompileTimeConstant) { isPrimitive = true; constValue = constrr.ConstantValue; if (constrr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, constrr.Type, constrr.ConstantValue); } writeScript = true; } } var isNullable = false; if (isPrimitive && constValue is AstType) { var itype = this.Emitter.Resolver.ResolveNode((AstType)constValue, this.Emitter); if (NullableType.IsNullable(itype.Type)) { isNullable = true; } } string tpl = null; MemberResolveResult init_rr = null; if (isField && member.VarInitializer != null) { init_rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter) as MemberResolveResult; tpl = init_rr != null?this.Emitter.GetInline(init_rr.Member) : null; } bool written = false; if (!isNull && (!isPrimitive || constValue is AstType || tpl != null)) { string value = null; bool needContinue = false; string defValue = ""; if (!isPrimitive) { var oldWriter = this.SaveWriter(); this.NewWriter(); member.Initializer.AcceptVisitor(this.Emitter); value = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); ResolveResult rr = null; AstType astType = null; if (member.VarInitializer != null) { rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter); } else { astType = member.Entity.ReturnType; rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter); } constValue = Inspector.GetDefaultFieldValue(rr.Type, astType); if (rr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue); } isNullable = NullableType.IsNullable(rr.Type); needContinue = constValue is IType; writeScript = true; if (needContinue && !(member.Initializer is ObjectCreateExpression)) { defValue = " || " + Inspector.GetStructDefaultValue((IType)constValue, this.Emitter); } } else if (constValue is AstType) { value = isNullable ? "null" : Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter); constValue = value; write = true; needContinue = !isProperty && !isNullable; } var name = member.GetName(this.Emitter); bool isValidIdentifier = Helpers.IsValidIdentifier(name); if (isProperty && isPrimitive) { constValue = "null"; if (this.IsObjectLiteral) { written = true; if (isValidIdentifier) { this.Write(string.Format("this.{0} = {1};", name, value)); } else { this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } this.WriteNewLine(); } else { this.Injectors.Add(string.Format(name.StartsWith("\"") || !isValidIdentifier ? "this[{0}] = {1};" : "this.{0} = {1};", isValidIdentifier ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } } else { if (this.IsObjectLiteral) { written = true; if (isValidIdentifier) { this.Write(string.Format("this.{0} = {1};", name, value + defValue)); } else { this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue)); } this.WriteNewLine(); } else if (tpl != null) { if (!tpl.Contains("{0}")) { tpl = tpl + " = {0};"; } string v = null; if (!isNull && (!isPrimitive || constValue is AstType)) { v = value + defValue; } else { if (write) { v = constValue != null?constValue.ToString() : ""; } else if (writeScript) { v = AbstractEmitterBlock.ToJavaScript(constValue, this.Emitter); } else { var oldWriter = this.SaveWriter(); this.NewWriter(); member.Initializer.AcceptVisitor(this.Emitter); v = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); } } tpl = tpl.Replace("{this}", "this").Replace("{0}", v); if (!tpl.EndsWith(";")) { tpl += ";"; } this.Injectors.Add(tpl); } else { if (isField && !isValidIdentifier) { this.Injectors.Add(string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue)); } else { this.Injectors.Add(string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value + defValue)); } } } if (needContinue || tpl != null) { continue; } } count++; if (written) { continue; } var mname = member.GetName(this.Emitter, true); bool isValid = Helpers.IsValidIdentifier(mname); if (!isValid) { if (this.IsObjectLiteral) { mname = "[" + AbstractEmitterBlock.ToJavaScript(mname, this.Emitter) + "]"; } else { mname = AbstractEmitterBlock.ToJavaScript(mname, this.Emitter); } } if (this.IsObjectLiteral) { this.WriteThis(); if (isValid) { this.WriteDot(); } this.Write(mname); this.Write(" = "); } else { this.EnsureComma(); XmlToJsDoc.EmitComment(this, member.Entity); this.Write(mname); this.WriteColon(); } if (constValue is AstType) { if (isNullable) { this.Write("null"); } else { this.Write(Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter)); } } else if (constValue is IType) { if (isNullable) { this.Write("null"); } else { this.Write(Inspector.GetStructDefaultValue((IType)constValue, this.Emitter)); } } else if (write) { this.Write(constValue); } else if (writeScript) { this.WriteScript(constValue); } else { member.Initializer.AcceptVisitor(this.Emitter); } if (this.IsObjectLiteral) { this.WriteSemiColon(true); } this.Emitter.Comma = true; } if (count > 0 && objectName != null) { this.WriteNewLine(); this.EndBlock(); } return(count > 0); }
protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format) { bool hasProperties = this.HasProperties(objectName, members); if (hasProperties && objectName != null) { this.EnsureComma(); this.Write(objectName); this.WriteColon(); this.BeginBlock(); } bool isProperty = FieldBlock.PropertiesName == objectName; foreach (var member in members) { object constValue = null; bool isPrimitive = false; var primitiveExpr = member.Initializer as PrimitiveExpression; bool write = false; bool writeScript = false; if (primitiveExpr != null) { isPrimitive = true; constValue = primitiveExpr.Value; writeScript = true; } if (constValue is RawValue) { constValue = constValue.ToString(); write = true; writeScript = false; } var isNull = member.Initializer.IsNull || member.Initializer is NullReferenceExpression; if (!isNull && !isPrimitive) { var constrr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter); if (constrr != null && constrr.IsCompileTimeConstant) { isPrimitive = true; constValue = constrr.ConstantValue; writeScript = true; } } var isNullable = false; if (isPrimitive && constValue is AstType) { var itype = this.Emitter.Resolver.ResolveNode((AstType)constValue, this.Emitter); if (NullableType.IsNullable(itype.Type)) { isNullable = true; } } if (!isNull && (!isPrimitive || (constValue is AstType))) { string value = null; bool needContinue = false; string defValue = ""; if (!isPrimitive) { var oldWriter = this.SaveWriter(); this.NewWriter(); member.Initializer.AcceptVisitor(this.Emitter); value = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); ResolveResult rr = null; AstType astType = null; if (member.VarInitializer != null) { rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter); } else { astType = member.Entity.ReturnType; rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter); } constValue = Inspector.GetDefaultFieldValue(rr.Type, astType); isNullable = NullableType.IsNullable(rr.Type); needContinue = constValue is IType; writeScript = true; if (needContinue && !(member.Initializer is ObjectCreateExpression)) { defValue = " || " + Inspector.GetStructDefaultValue((IType)constValue, this.Emitter); } } else { value = isNullable ? "null" : Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter); constValue = value; write = true; needContinue = !isProperty && !isNullable; } if (isProperty && isPrimitive) { constValue = "null"; this.Injectors.Add(string.Format("this.{0} = {1};", member.GetName(this.Emitter), value)); } else { this.Injectors.Add(string.Format(format, member.GetName(this.Emitter), value + defValue)); } if (needContinue) { continue; } } this.EnsureComma(); XmlToJsDoc.EmitComment(this, member.Entity); this.Write(member.GetName(this.Emitter)); this.WriteColon(); if (constValue is AstType) { if (isNullable) { this.Write("null"); } else { this.Write(Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter)); } } else if (constValue is IType) { if (isNullable) { this.Write("null"); } else { this.Write(Inspector.GetStructDefaultValue((IType)constValue, this.Emitter)); } } else if (write) { this.Write(constValue); } else if (writeScript) { this.WriteScript(constValue); } else { member.Initializer.AcceptVisitor(this.Emitter); } this.Emitter.Comma = true; } if (hasProperties && objectName != null) { this.WriteNewLine(); this.EndBlock(); } return(hasProperties); }
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); name = oc.GetOverloadName(); if (!this.Emitter.AssemblyInfo.PreserveMemberCase && itemrr.Member is IProperty && !itemrr.Member.Attributes.Any(attr => attr.AttributeType.FullName == "Bridge.NameAttribute") && !this.Emitter.Validator.IsObjectLiteral(itemrr.Member.DeclaringTypeDefinition)) { name = Object.Net.Utilities.StringUtils.ToLowerCamelCase(name); } } 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 (isObjectLiteral) { 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 > 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 (itype != null) { mode = this.Emitter.Validator.GetObjectInitializationMode(type); } } 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.Write(name, ": "); 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 void VisitArrayCreateExpression() { ArrayCreateExpression arrayCreateExpression = this.ArrayCreateExpression; var rr = this.Emitter.Resolver.ResolveNode(arrayCreateExpression, this.Emitter) as ArrayCreateResolveResult; var at = (ArrayType)rr.Type; var rank = arrayCreateExpression.Arguments.Count; if (arrayCreateExpression.Initializer.IsNull && rank == 1) { this.Write("Bridge.Array.init("); arrayCreateExpression.Arguments.First().AcceptVisitor(this.Emitter); this.WriteComma(); var def = Inspector.GetDefaultFieldValue(at.ElementType); if (def == at.ElementType) { this.WriteFunction(); this.WriteOpenCloseParentheses(); this.BeginBlock(); this.WriteReturn(true); this.Write(Inspector.GetStructDefaultValue(at.ElementType, this.Emitter)); this.WriteSemiColon(); this.WriteNewLine(); this.EndBlock(); } else { this.WriteScript(def); } this.Write(")"); return; } if (at.Dimensions > 1) { this.Write("Bridge.Array.create("); var defaultInitializer = new PrimitiveExpression(Inspector.GetDefaultFieldValue(at.ElementType), "?"); if (defaultInitializer.Value is IType) { this.Write(Inspector.GetStructDefaultValue((IType)defaultInitializer.Value, this.Emitter)); } else { defaultInitializer.AcceptVisitor(this.Emitter); } this.WriteComma(); } if (rr.InitializerElements != null && rr.InitializerElements.Count > 0) { this.WriteOpenBracket(); var elements = arrayCreateExpression.Initializer.Elements; new ExpressionListBlock(this.Emitter, elements, null).Emit(); this.WriteCloseBracket(); } else if (at.Dimensions > 1) { this.Write("null"); } else { this.Write("[]"); } if (at.Dimensions > 1) { this.Emitter.Comma = true; for (int i = 0; i < rr.SizeArguments.Count; i++) { var a = rr.SizeArguments[i]; this.EnsureComma(false); if (a.IsCompileTimeConstant) { this.Write(a.ConstantValue); } else if (arrayCreateExpression.Arguments.Count > i) { var arg = arrayCreateExpression.Arguments.ElementAt(i); if (arg != null) { arg.AcceptVisitor(this.Emitter); } } this.Emitter.Comma = true; } this.Write(")"); this.Emitter.Comma = false; } }
protected void VisitArrayCreateExpression() { ArrayCreateExpression arrayCreateExpression = this.ArrayCreateExpression; var rr = this.ArrayCreateResolveResult ?? (this.Emitter.Resolver.ResolveNode(arrayCreateExpression, this.Emitter) as ArrayCreateResolveResult); var at = (ArrayType)rr.Type; var rank = arrayCreateExpression.Arguments.Count; if (arrayCreateExpression.Initializer.IsNull && rank == 1) { string typedArrayName = null; if (this.Emitter.AssemblyInfo.UseTypedArrays && (typedArrayName = Helpers.GetTypedArrayName(at.ElementType)) != null) { this.Write("new ", typedArrayName, "("); if (this.ArrayCreateResolveResult != null) { AttributeCreateBlock.WriteResolveResult(this.ArrayCreateResolveResult.SizeArguments.First(), this); } else { arrayCreateExpression.Arguments.First().AcceptVisitor(this.Emitter); } this.Write(")"); } else { this.Write(JS.Types.SYSTEM_ARRAY + ".init("); if (this.ArrayCreateResolveResult != null) { AttributeCreateBlock.WriteResolveResult(this.ArrayCreateResolveResult.SizeArguments.First(), this); } else { arrayCreateExpression.Arguments.First().AcceptVisitor(this.Emitter); } this.WriteComma(); var def = Inspector.GetDefaultFieldValue(at.ElementType, arrayCreateExpression.Type); if (def == at.ElementType || def is RawValue) { this.WriteFunction(); this.WriteOpenCloseParentheses(); this.BeginBlock(); this.WriteReturn(true); if (def is RawValue) { this.Write(def.ToString()); } else { this.Write(Inspector.GetStructDefaultValue(at.ElementType, this.Emitter)); } this.WriteSemiColon(); this.WriteNewLine(); this.EndBlock(); } else { this.WriteScript(def); } this.Write(")"); } return; } if (at.Dimensions > 1) { this.Write(JS.Types.SYSTEM_ARRAY + ".create("); var defaultInitializer = new PrimitiveExpression(Inspector.GetDefaultFieldValue(at.ElementType, arrayCreateExpression.Type), "?"); if (defaultInitializer.Value is IType) { this.Write(Inspector.GetStructDefaultValue((IType)defaultInitializer.Value, this.Emitter)); } else if (defaultInitializer.Value is RawValue) { this.Write(defaultInitializer.Value.ToString()); } else { defaultInitializer.AcceptVisitor(this.Emitter); } this.WriteComma(); } if (rr.InitializerElements != null && rr.InitializerElements.Count > 0) { this.WriteOpenBracket(); if (this.ArrayCreateResolveResult != null) { bool needComma = false; foreach (ResolveResult item in this.ArrayCreateResolveResult.InitializerElements) { if (needComma) { this.WriteComma(); } needComma = true; AttributeCreateBlock.WriteResolveResult(item, this); } } else { var elements = arrayCreateExpression.Initializer.Elements; new ExpressionListBlock(this.Emitter, elements, null, null, 0).Emit(); } this.WriteCloseBracket(); } else if (at.Dimensions > 1) { this.Write("null"); } else { this.Write("[]"); } if (at.Dimensions > 1) { this.Emitter.Comma = true; for (int i = 0; i < rr.SizeArguments.Count; i++) { var a = rr.SizeArguments[i]; this.EnsureComma(false); if (a.IsCompileTimeConstant) { this.Write(a.ConstantValue); } else if (this.ArrayCreateResolveResult != null) { AttributeCreateBlock.WriteResolveResult(this.ArrayCreateResolveResult.SizeArguments[i], this); } else if (arrayCreateExpression.Arguments.Count > i) { var arg = arrayCreateExpression.Arguments.ElementAt(i); if (arg != null) { arg.AcceptVisitor(this.Emitter); } } this.Emitter.Comma = true; } this.Write(")"); this.Emitter.Comma = false; } }
protected virtual void EmitInlineExpressionList(ArgumentsInfo argsInfo, string inline, bool asRef = false, bool isNull = false) { IEnumerable <NamedParamExpression> expressions = argsInfo.NamedExpressions; IEnumerable <TypeParamExpression> typeParams = argsInfo.TypeArguments; this.Write(""); if (asRef) { this.Write("function ("); this.EmitMethodParameters(this.Method, this.Method.Parameters, this.Method.TypeParameters, isNull); this.Write(") { return "); } bool needExpand = false; string paramsName = null; IType paramsType = null; int paramsIndex = 0; if (argsInfo.ResolveResult != null) { var paramsParam = argsInfo.ResolveResult.Member.Parameters.FirstOrDefault(p => p.IsParams); if (paramsParam != null) { paramsIndex = argsInfo.ResolveResult.Member.Parameters.IndexOf(paramsParam); paramsName = paramsParam.Name; paramsType = paramsParam.Type; } } if (paramsName != null) { var matches = _formatArg.Matches(inline); bool ignoreArray = false; foreach (Match m in matches) { if (m.Groups[2].Value == paramsName) { bool isRaw = m.Groups[1].Success && m.Groups[1].Value == "*"; ignoreArray = isRaw || argsInfo.ParamsExpression == null; string modifier = m.Groups[1].Success ? m.Groups[4].Value : null; if (modifier == "array") { ignoreArray = false; } break; } } if (argsInfo.ResolveResult is CSharpInvocationResolveResult) { needExpand = !((CSharpInvocationResolveResult)argsInfo.ResolveResult).IsExpandedForm; } if (needExpand && ignoreArray && !asRef) { IList <Expression> exprs = this.GetExpressionsByKey(expressions, paramsName); if (exprs.Count == 1 && exprs[0] != null && exprs[0].Parent != null) { var exprrr = this.Emitter.Resolver.ResolveNode(exprs[0], this.Emitter); if (exprrr.Type.Kind == TypeKind.Array) { var match = _inlineMethod.Match(inline); if (match.Success) { string target = null; var methodName = match.Groups[1].Value; if (methodName.Contains(".")) { target = methodName.LeftOfRightmostOf('.'); } string args = match.Groups[2].Value; StringBuilder sb = new StringBuilder(); sb.Append(methodName); sb.Append(".apply("); sb.Append(target ?? "null"); if (args.Contains(",")) { sb.Append(", ["); sb.Append(args.LeftOfRightmostOf(',').Trim()); sb.Append("].concat("); sb.Append(args.RightOfRightmostOf(',').Trim()); sb.Append(")"); } else { sb.Append(","); sb.Append(args); } sb.Append(")"); inline = inline.Remove(match.Index, match.Length); inline = inline.Insert(match.Index, sb.ToString()); } } } } } inline = _formatArg.Replace(inline, delegate(Match m) { int count = this.Emitter.Writers.Count; string key = m.Groups[2].Value; bool isRaw = m.Groups[1].Success && m.Groups[1].Value == "*"; bool ignoreArray = isRaw || argsInfo.ParamsExpression == null; string modifier = m.Groups[1].Success ? m.Groups[4].Value : null; if (modifier == "array") { ignoreArray = false; } StringBuilder oldSb = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); if (asRef) { if (Regex.IsMatch(key, "^\\d+$")) { var index = int.Parse(key); key = this.Method.Parameters[index].Name; } if (key == "this") { if (isNull) { this.Write("$t"); } else if (this.Method.IsExtensionMethod && this.TargetResolveResult is TypeResolveResult) { this.WriteParamName(this.Method.Parameters.First().Name); } else { ((MemberReferenceExpression)argsInfo.Expression).Target.AcceptVisitor(this.Emitter); } } else if (this.Method.IsExtensionMethod && key == this.Method.Parameters.First().Name) { if (this.TargetResolveResult is TypeResolveResult) { this.WriteParamName(key); } else { ((MemberReferenceExpression)argsInfo.Expression).Target.AcceptVisitor(this.Emitter); } } else if (paramsName == key && !ignoreArray) { this.Write("Array.prototype.slice.call(arguments, " + paramsIndex + ")"); } else { this.WriteParamName(key); } } else if (key == "this" || key == argsInfo.ThisName || (key == "0" && argsInfo.IsExtensionMethod)) { if (modifier == "type") { AstNode node = null; if (argsInfo.ThisArgument is AstNode) { node = (AstNode)argsInfo.ThisArgument; } else { node = argsInfo.Expression; } if (node != null) { var rr = this.Emitter.Resolver.ResolveNode(node, this.Emitter); var type = rr.Type; if (rr is MemberResolveResult) { type = ((MemberResolveResult)rr).TargetResult.Type; } bool needName = this.NeedName(type); if (needName) { this.Write(BridgeTypes.ToJsName(type, this.Emitter)); } else { string thisValue = argsInfo.GetThisValue(); if (thisValue != null) { this.Write("Bridge.getType(" + thisValue + ")"); } } } } else { string thisValue = argsInfo.GetThisValue(); if (thisValue != null) { this.Write(thisValue); } } } else { IList <Expression> exprs = this.GetExpressionsByKey(expressions, key); if (exprs.Count > 0) { if (modifier == "type") { IType type = null; if (paramsName == key && paramsType != null) { type = paramsType; } else { var rr = this.Emitter.Resolver.ResolveNode(exprs[0], this.Emitter); type = rr.Type; } bool needName = this.NeedName(type); this.WriteGetType(needName, type, exprs[0], modifier); } else if (exprs.Count > 1 || paramsName == key) { if (needExpand) { ignoreArray = true; } if (!ignoreArray) { this.Write("["); } if (exprs.Count == 1 && exprs[0] == null) { this.Write("null"); } else { new ExpressionListBlock(this.Emitter, exprs, null).Emit(); } if (!ignoreArray) { this.Write("]"); } } else { string s; if (exprs[0] != null) { var writer = this.SaveWriter(); this.NewWriter(); var directExpr = exprs[0] as DirectionExpression; if (directExpr != null) { var rr = this.Emitter.Resolver.ResolveNode(exprs[0], this.Emitter) as ByReferenceResolveResult; if (rr != null && !(rr.ElementResult is LocalResolveResult)) { this.Write("Bridge.ref("); this.Emitter.IsRefArg = true; exprs[0].AcceptVisitor(this.Emitter); this.Emitter.IsRefArg = false; if (this.Emitter.Writers.Count != count) { this.PopWriter(); count = this.Emitter.Writers.Count; } this.Write(")"); } else { exprs[0].AcceptVisitor(this.Emitter); } } else { exprs[0].AcceptVisitor(this.Emitter); } s = this.Emitter.Output.ToString(); this.RestoreWriter(writer); if (modifier == "raw") { s = s.Trim('"'); } } else { s = "null"; } this.Write(this.WriteIndentToString(s)); } } else if (typeParams != null) { var type = this.GetAstTypeByKey(typeParams, key); if (type != null) { if (modifier == "default" || modifier == "defaultFn") { var def = Inspector.GetDefaultFieldValue(type, this.Emitter.Resolver); this.GetDefaultValue(def, modifier); } else { type.AcceptVisitor(this.Emitter); } } else { var iType = this.GetITypeByKey(typeParams, key); if (iType != null) { if (modifier == "default" || modifier == "defaultFn") { var def = Inspector.GetDefaultFieldValue(iType); this.GetDefaultValue(def, modifier); } else { new CastBlock(this.Emitter, iType).Emit(); } } } } } if (this.Emitter.Writers.Count != count) { this.PopWriter(); } string replacement = this.Emitter.Output.ToString(); this.Emitter.Output = oldSb; return(replacement); }); this.Write(inline); if (asRef) { this.Write("; }"); } }
protected override void DoEmit() { var elements = this.ArrayInitializerExpression.Elements; var first = elements.Count > 0 ? elements.First() : null; var isObjectInitializer = first is NamedExpression || first is NamedArgumentExpression; var rr = this.Emitter.Resolver.ResolveNode(this.ArrayInitializerExpression, this.Emitter) as ArrayCreateResolveResult; var at = rr != null ? (ArrayType)rr.Type : null; var create = at != null && at.Dimensions > 1; if (rr != null) { } if (!isObjectInitializer || this.ArrayInitializerExpression.IsSingleElement) { if (at != null) { this.Write(create ? JS.Types.System.Array.CREATE : JS.Types.System.Array.INIT); this.WriteOpenParentheses(); } if (create) { var defaultInitializer = new PrimitiveExpression(Inspector.GetDefaultFieldValue(at.ElementType, AstType.Null), "?"); if (defaultInitializer.Value is IType) { this.Write(Inspector.GetStructDefaultValue((IType)defaultInitializer.Value, this.Emitter)); } else if (defaultInitializer.Value is RawValue) { this.Write(defaultInitializer.Value.ToString()); } else { defaultInitializer.AcceptVisitor(this.Emitter); } this.WriteComma(); } this.Write("["); } else { this.BeginBlock(); } new ExpressionListBlock(this.Emitter, elements, null, null, 0).Emit(); if (!isObjectInitializer || this.ArrayInitializerExpression.IsSingleElement) { this.Write("]"); if (at != null) { this.Write(", "); this.Write(BridgeTypes.ToJsName(at.ElementType, this.Emitter)); if (create) { this.Emitter.Comma = true; for (int i = 0; i < rr.SizeArguments.Count; i++) { var a = rr.SizeArguments[i]; this.EnsureComma(false); if (a.IsCompileTimeConstant) { this.Write(a.ConstantValue); } else { AttributeCreateBlock.WriteResolveResult(rr.SizeArguments[i], this); } this.Emitter.Comma = true; } } this.Write(")"); } } else { this.WriteNewLine(); this.EndBlock(); } }
protected void VisitArrayCreateExpression() { ArrayCreateExpression arrayCreateExpression = this.ArrayCreateExpression; var rr = this.Emitter.Resolver.ResolveNode(arrayCreateExpression, this.Emitter) as ArrayCreateResolveResult; var at = (ArrayType)rr.Type; var rank = arrayCreateExpression.Arguments.Count; if (arrayCreateExpression.Initializer.IsNull && rank == 1) { this.Write("new Array("); arrayCreateExpression.Arguments.First().AcceptVisitor(this.Emitter); this.Write(")"); return; } if (at.Dimensions > 1) { this.Write("Bridge.Array.create("); var defaultInitializer = new PrimitiveExpression(Inspector.GetDefaultFieldValue(arrayCreateExpression.Type, this.Emitter.Resolver), "?"); if (defaultInitializer == null) { this.Write("Bridge.getDefaultValue(" + Helpers.TranslateTypeReference(arrayCreateExpression.Type, this.Emitter) + ")"); } else { var primitiveExpr = defaultInitializer as PrimitiveExpression; if (primitiveExpr != null && primitiveExpr.Value is AstType) { this.Write("new " + Helpers.TranslateTypeReference((AstType)primitiveExpr.Value, this.Emitter) + "()"); } else { defaultInitializer.AcceptVisitor(this.Emitter); } } this.WriteComma(); } if (rr.InitializerElements != null && rr.InitializerElements.Count > 0) { this.WriteOpenBracket(); var elements = arrayCreateExpression.Initializer.Elements; new ExpressionListBlock(this.Emitter, elements, null).Emit(); this.WriteCloseBracket(); } else if (at.Dimensions > 1) { this.Write("null"); } if (at.Dimensions > 1) { this.Emitter.Comma = true; for (int i = 0; i < rr.SizeArguments.Count; i++) { var a = rr.SizeArguments[i]; this.EnsureComma(false); if (a.IsCompileTimeConstant) { this.Write(a.ConstantValue); } else if (arrayCreateExpression.Arguments.Count > i) { var arg = arrayCreateExpression.Arguments.ElementAt(i); if (arg != null) { arg.AcceptVisitor(this.Emitter); } } this.Emitter.Comma = true; } this.Write(")"); this.Emitter.Comma = false; } }