Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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();
            }
        }
Ejemplo n.º 3
0
        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(")");
                }
            }
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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;
            }
        }
Ejemplo n.º 7
0
        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();
            }
        }