public static JRaw ConstructAttribute(IAttribute attr, ITypeDefinition currentType, IEmitter emitter) { var block = new AttributeCreateBlock(emitter, attr); var oldWriter = block.SaveWriter(); block.NewWriter(); block.Emit(); var str = emitter.Output.ToString(); block.RestoreWriter(oldWriter); return(new JRaw(str)); }
protected virtual void WritePositionalList(IList <ResolveResult> expressions, IAttribute attr) { bool needComma = false; int count = this.Emitter.Writers.Count; bool expanded = false; int paramsIndex = -1; if (attr.Constructor.Parameters.Any(p => p.IsParams)) { paramsIndex = attr.Constructor.Parameters.IndexOf(attr.Constructor.Parameters.FirstOrDefault(p => p.IsParams)); var or = new OverloadResolution(this.Emitter.Resolver.Compilation, expressions.ToArray()); or.AddCandidate(attr.Constructor); expanded = or.BestCandidateIsExpandedForm; } for (int i = 0; i < expressions.Count; i++) { var expr = expressions[i]; if (needComma) { this.WriteComma(); } needComma = true; if (expanded && paramsIndex == i) { this.WriteOpenBracket(); } AttributeCreateBlock.WriteResolveResult(expr, this); if (this.Emitter.Writers.Count != count) { this.PopWriter(); count = this.Emitter.Writers.Count; } } if (expanded) { this.WriteCloseBracket(); } }
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 List <string> WriteObjectInitializer(IList <KeyValuePair <IMember, ResolveResult> > expressions, TypeDefinition type, IAttribute attr) { bool needComma = false; List <string> names = new List <string>(); List <string> inlineInit = new List <string>(); if (expressions != null) { foreach (KeyValuePair <IMember, ResolveResult> item in expressions) { var member = item.Key; var name = this.Emitter.GetEntityName(member); var inlineCode = AttributeCreateBlock.GetInlineInit(item, this); if (inlineCode != null) { inlineInit.Add(inlineCode); } else { if (member is IProperty) { name = Helpers.GetPropertyRef(member, this.Emitter, true); } else if (member is IEvent) { name = Helpers.GetEventRef(member, this.Emitter, false); } if (needComma) { this.WriteComma(); } needComma = true; this.Write(name, ": "); AttributeCreateBlock.WriteResolveResult(item.Value, this); 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(inlineInit); } var itype = tinfo.Type as ITypeDefinition; var mode = 0; if (attr.Constructor != null) { if (itype != null) { var oattr = this.Emitter.Validator.GetAttribute(itype.Attributes, Translator.Bridge_ASSEMBLY + ".ObjectLiteralAttribute"); if (oattr.PositionalArguments.Count > 0) { var value = oattr.PositionalArguments.First().ConstantValue; if (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 (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); } } } } } return(inlineInit); }
public static string GetInlineInit(KeyValuePair <IMember, ResolveResult> item, AbstractEmitterBlock block) { string inlineCode = null; var member = item.Key; if (member is IProperty) { var setter = ((IProperty)member).Setter; if (setter != null) { inlineCode = block.Emitter.GetInline(setter); } } else { inlineCode = block.Emitter.GetInline(member); } if (inlineCode != null) { bool oldIsAssignment = block.Emitter.IsAssignment; bool oldUnary = block.Emitter.IsUnaryAccessor; var oldWriter = block.SaveWriter(); block.NewWriter(); block.Emitter.IsAssignment = true; block.Emitter.IsUnaryAccessor = false; bool hasThis = Helpers.HasThis(inlineCode); inlineCode = Helpers.ConvertTokens(block.Emitter, inlineCode, member); if (inlineCode.StartsWith("<self>")) { hasThis = true; inlineCode = inlineCode.Substring(6); } if (hasThis) { inlineCode = inlineCode.Replace("{this}", "this"); if (member is IProperty) { inlineCode = inlineCode.Replace("{0}", "[[0]]"); AttributeCreateBlock.WriteResolveResult(item.Value, block); var value = block.Emitter.Output.ToString(); inlineCode = inlineCode.Replace("{value}", value); inlineCode = inlineCode.Replace("[[0]]", "{0}"); } } else { if (member.SymbolKind == SymbolKind.Property) { var count = block.Emitter.Writers.Count; block.PushWriter("this." + inlineCode); AttributeCreateBlock.WriteResolveResult(item.Value, block); if (block.Emitter.Writers.Count > count) { inlineCode = block.PopWriter(true); } } else { block.Write("this." + inlineCode); } } block.Emitter.IsAssignment = oldIsAssignment; block.Emitter.IsUnaryAccessor = oldUnary; block.RestoreWriter(oldWriter); } if (inlineCode != null && !inlineCode.Trim().EndsWith(";")) { inlineCode += ";"; } return(inlineCode); }
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 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(); } }