private GotoImplementationResponse GetMemberResponse(CSharpTypeResolveContext rctx, MemberResolveResult resolveResult)
 {
     var locations = new List<Location>();
     //TODO: we don't need to scan all types in all projects
     foreach (IUnresolvedTypeDefinition type in GetAllTypes())
     {
         ITypeDefinition resolvedDef = type.Resolve(rctx).GetDefinition();
         if (resolvedDef != null)
         {
             IMember member =
                 InheritanceHelper.GetDerivedMember(resolveResult.Member, resolvedDef);
             if (member != null)
             {
                 var region = member.MemberDefinition.Region;
                 var location = new Location
                     {
                         FileName = region.FileName,
                         Line = region.BeginLine,
                         Column = region.BeginColumn
                     };
                 locations.Add(location);
             }
         }
     }
     return new GotoImplementationResponse { Locations = locations };
 }
Exemplo n.º 2
0
 private QuickFixResponse GetMemberResponse(ITypeResolveContext rctx, MemberResolveResult resolveResult)
 {
     var quickFixes = new List<QuickFix>();
     //TODO: we don't need to scan all types in all projects
     foreach (ITypeDefinition type in GetAllTypes(rctx))
     {
         if (type != null)
         {
             IMember member =
                 InheritanceHelper.GetDerivedMember(resolveResult.Member, type);
             if (member != null)
             {
                 var quickFix = QuickFix.ForFirstLineInRegion
                                    ( member.MemberDefinition.Region
                                    , _solution.GetFile(type.Region.FileName));
                 quickFixes.Add(quickFix);
             }
         }
     }
     return new QuickFixResponse(quickFixes);
 }
Exemplo n.º 3
0
        protected virtual IEnumerable <string> GetDefineMethods(string prefix, Func <MethodDeclaration, IMethod, string> fn)
        {
            var methods  = this.TypeInfo.InstanceMethods;
            var attrName = "Bridge.InitAttribute";
            int value    = 0;

            switch (prefix)
            {
            case "After":
                value = 0;
                break;

            case "Before":
                value = 1;
                break;

            case "Top":
                value = 2;
                break;

            case "Bottom":
                value = 3;
                break;
            }

            foreach (var methodGroup in methods)
            {
                foreach (var method in methodGroup.Value)
                {
                    foreach (var attrSection in method.Attributes)
                    {
                        foreach (var attr in attrSection.Attributes)
                        {
                            var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter);
                            if (rr.Type.FullName == attrName)
                            {
                                throw new EmitterException(attr, "Instance method cannot be Init method");
                            }
                        }
                    }
                }
            }

            methods = this.TypeInfo.StaticMethods;
            List <string> list = new List <string>();

            foreach (var methodGroup in methods)
            {
                foreach (var method in methodGroup.Value)
                {
                    MemberResolveResult rrMember = null;
                    IMethod             rrMethod = null;
                    foreach (var attrSection in method.Attributes)
                    {
                        foreach (var attr in attrSection.Attributes)
                        {
                            var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter);
                            if (rr.Type.FullName == attrName)
                            {
                                int?initPosition = null;
                                if (attr.HasArgumentList)
                                {
                                    if (attr.Arguments.Count > 0)
                                    {
                                        var argExpr = attr.Arguments.First();
                                        var argrr   = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter);
                                        if (argrr.ConstantValue is int)
                                        {
                                            initPosition = (int)argrr.ConstantValue;
                                        }
                                    }
                                    else
                                    {
                                        initPosition = 0; //Default InitPosition.After
                                    }
                                }
                                else
                                {
                                    initPosition = 0; //Default InitPosition.After
                                }

                                if (initPosition == value)
                                {
                                    if (rrMember == null)
                                    {
                                        rrMember = this.Emitter.Resolver.ResolveNode(method, this.Emitter) as MemberResolveResult;
                                        rrMethod = rrMember != null ? rrMember.Member as IMethod : null;
                                    }

                                    if (rrMethod != null)
                                    {
                                        if (rrMethod.TypeParameters.Count > 0)
                                        {
                                            throw new EmitterException(method, "Init method cannot be generic");
                                        }

                                        if (rrMethod.Parameters.Count > 0)
                                        {
                                            throw new EmitterException(method, "Init method should not have parameters");
                                        }

                                        if (rrMethod.ReturnType.Kind != TypeKind.Void)
                                        {
                                            throw new EmitterException(method, "Init method should not return anything");
                                        }

                                        list.Add(fn(method, rrMethod));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(list);
        }
Exemplo n.º 4
0
 public static bool ExcludeTypeParameterForDefinition(MemberResolveResult rr)
 {
     return(rr != null && OverloadsCollection.ExcludeTypeParameterForDefinition(rr.Member));
 }
Exemplo n.º 5
0
        protected void VisitInvocationExpression()
        {
            InvocationExpression invocationExpression = this.InvocationExpression;
            int pos = this.Emitter.Output.Length;

            if (this.Emitter.IsForbiddenInvocation(invocationExpression))
            {
                throw new EmitterException(invocationExpression, "This method cannot be invoked directly");
            }

            var oldValue = this.Emitter.ReplaceAwaiterByVar;
            var oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling;

            if (this.Emitter.IsAsync && !this.Emitter.AsyncExpressionHandling)
            {
                this.WriteAwaiters(invocationExpression);
                this.Emitter.ReplaceAwaiterByVar     = true;
                this.Emitter.AsyncExpressionHandling = true;
            }

            Tuple <bool, bool, string> inlineInfo = this.Emitter.GetInlineCode(invocationExpression);
            var argsInfo = new ArgumentsInfo(this.Emitter, invocationExpression);

            var argsExpressions = argsInfo.ArgumentsExpressions;
            var paramsArg       = argsInfo.ParamsExpression;

            var targetResolve    = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter);
            var csharpInvocation = targetResolve as CSharpInvocationResolveResult;
            MemberReferenceExpression targetMember = invocationExpression.Target as MemberReferenceExpression;
            bool isObjectLiteral = csharpInvocation != null && csharpInvocation.Member.DeclaringTypeDefinition != null?this.Emitter.Validator.IsObjectLiteral(csharpInvocation.Member.DeclaringTypeDefinition) : false;

            var interceptor = this.Emitter.Plugins.OnInvocation(this, this.InvocationExpression, targetResolve as InvocationResolveResult);

            if (interceptor.Cancel)
            {
                this.Emitter.SkipSemiColon           = true;
                this.Emitter.ReplaceAwaiterByVar     = oldValue;
                this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
                return;
            }

            if (!string.IsNullOrEmpty(interceptor.Replacement))
            {
                this.Write(interceptor.Replacement);
                this.Emitter.ReplaceAwaiterByVar     = oldValue;
                this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
                return;
            }

            if (inlineInfo != null)
            {
                bool   isStaticMethod = inlineInfo.Item1;
                bool   isInlineMethod = inlineInfo.Item2;
                string inlineScript   = inlineInfo.Item3;

                if (isInlineMethod)
                {
                    if (invocationExpression.Arguments.Count > 0)
                    {
                        var code             = invocationExpression.Arguments.First();
                        var inlineExpression = code as PrimitiveExpression;

                        if (inlineExpression == null)
                        {
                            throw new EmitterException(invocationExpression, "Only primitive expression can be inlined");
                        }

                        string value = inlineExpression.Value.ToString().Trim();

                        if (value.Length > 0)
                        {
                            value = InlineArgumentsBlock.ReplaceInlineArgs(this, inlineExpression.Value.ToString(), invocationExpression.Arguments.Skip(1).ToArray());
                            this.Write(value);

                            value = value.Trim();
                            if (value[value.Length - 1] == ';' || value.EndsWith("*/", StringComparison.InvariantCulture) || value.StartsWith("//"))
                            {
                                this.Emitter.SkipSemiColon = true;
                                this.WriteNewLine();
                            }
                        }
                        else
                        {
                            // Empty string, emit nothing.
                            this.Emitter.SkipSemiColon = true;
                        }

                        this.Emitter.ReplaceAwaiterByVar     = oldValue;
                        this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                        return;
                    }
                }
                else
                {
                    MemberReferenceExpression targetMemberRef = invocationExpression.Target as MemberReferenceExpression;
                    bool isBase = targetMemberRef != null && targetMemberRef.Target is BaseReferenceExpression;

                    if (!String.IsNullOrEmpty(inlineScript) && (isBase || invocationExpression.Target is IdentifierExpression))
                    {
                        argsInfo.ThisArgument = "this";
                        bool noThis = !Helpers.HasThis(inlineScript);

                        if (inlineScript.StartsWith("<self>"))
                        {
                            noThis       = false;
                            inlineScript = inlineScript.Substring(6);
                        }

                        if (!noThis)
                        {
                            Emitter.ThisRefCounter++;
                        }

                        if (!isStaticMethod && noThis)
                        {
                            this.WriteThis();
                            this.WriteDot();
                        }

                        new InlineArgumentsBlock(this.Emitter, argsInfo, inlineScript).Emit();
                        this.Emitter.ReplaceAwaiterByVar     = oldValue;
                        this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                        return;
                    }
                }
            }

            if (targetMember != null || isObjectLiteral)
            {
                var member = targetMember != null?this.Emitter.Resolver.ResolveNode(targetMember.Target, this.Emitter) : null;

                if (targetResolve != null)
                {
                    InvocationResolveResult invocationResult;
                    bool isExtensionMethodInvocation = false;
                    if (csharpInvocation != null)
                    {
                        if (member != null && member.Type.Kind == TypeKind.Delegate && (/*csharpInvocation.Member.Name == "Invoke" || */ csharpInvocation.Member.Name == "BeginInvoke" || csharpInvocation.Member.Name == "EndInvoke") && !csharpInvocation.IsExtensionMethodInvocation)
                        {
                            throw new EmitterException(invocationExpression, "Delegate's 'Invoke' methods are not supported. Please use direct delegate invoke.");
                        }

                        if (csharpInvocation.IsExtensionMethodInvocation)
                        {
                            invocationResult            = csharpInvocation;
                            isExtensionMethodInvocation = true;
                            var resolvedMethod = invocationResult.Member as IMethod;
                            if (resolvedMethod != null && resolvedMethod.IsExtensionMethod)
                            {
                                string inline   = this.Emitter.GetInline(resolvedMethod);
                                bool   isNative = this.IsNativeMethod(resolvedMethod);

                                if (string.IsNullOrWhiteSpace(inline) && isNative)
                                {
                                    invocationResult = null;
                                }
                            }
                        }
                        else
                        {
                            invocationResult = null;
                        }

                        if (this.IsEmptyPartialInvoking(csharpInvocation.Member as IMethod) || IsConditionallyRemoved(invocationExpression, csharpInvocation.Member))
                        {
                            this.Emitter.SkipSemiColon           = true;
                            this.Emitter.ReplaceAwaiterByVar     = oldValue;
                            this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                            return;
                        }
                    }
                    else
                    {
                        invocationResult = targetResolve as InvocationResolveResult;

                        if (invocationResult != null && (this.IsEmptyPartialInvoking(invocationResult.Member as IMethod) || IsConditionallyRemoved(invocationExpression, invocationResult.Member)))
                        {
                            this.Emitter.SkipSemiColon           = true;
                            this.Emitter.ReplaceAwaiterByVar     = oldValue;
                            this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                            return;
                        }
                    }

                    if (invocationResult == null)
                    {
                        invocationResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as InvocationResolveResult;
                    }

                    if (invocationResult != null)
                    {
                        var resolvedMethod = invocationResult.Member as IMethod;

                        if (resolvedMethod != null && (resolvedMethod.IsExtensionMethod || isObjectLiteral))
                        {
                            string inline   = this.Emitter.GetInline(resolvedMethod);
                            bool   isNative = this.IsNativeMethod(resolvedMethod);

                            if (isExtensionMethodInvocation || isObjectLiteral)
                            {
                                if (!string.IsNullOrWhiteSpace(inline))
                                {
                                    this.Write("");
                                    StringBuilder savedBuilder = this.Emitter.Output;
                                    this.Emitter.Output = new StringBuilder();
                                    this.WriteThisExtension(invocationExpression.Target);
                                    argsInfo.ThisArgument = this.Emitter.Output.ToString();
                                    this.Emitter.Output   = savedBuilder;
                                    new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit();
                                }
                                else if (!isNative)
                                {
                                    var overloads = OverloadsCollection.Create(this.Emitter, resolvedMethod);

                                    if (isObjectLiteral && !resolvedMethod.IsStatic && resolvedMethod.DeclaringType.Kind == TypeKind.Interface)
                                    {
                                        this.Write("Bridge.getType(");
                                        this.WriteThisExtension(invocationExpression.Target);
                                        this.Write(").");
                                    }
                                    else
                                    {
                                        string name = BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter, ignoreLiteralName: false) + ".";
                                        this.Write(name);
                                    }

                                    if (isObjectLiteral && !resolvedMethod.IsStatic)
                                    {
                                        this.Write(JS.Fields.PROTOTYPE + "." + overloads.GetOverloadName() + "." + JS.Funcs.CALL);
                                    }
                                    else
                                    {
                                        this.Write(overloads.GetOverloadName());
                                    }

                                    var isIgnoreClass = resolvedMethod.DeclaringTypeDefinition != null && this.Emitter.Validator.IsExternalType(resolvedMethod.DeclaringTypeDefinition);
                                    int openPos       = this.Emitter.Output.Length;
                                    this.WriteOpenParentheses();

                                    this.Emitter.Comma = false;

                                    if (isObjectLiteral && !resolvedMethod.IsStatic)
                                    {
                                        this.WriteThisExtension(invocationExpression.Target);
                                        this.Emitter.Comma = true;
                                    }

                                    if (!isIgnoreClass && !Helpers.IsIgnoreGeneric(resolvedMethod, this.Emitter) && argsInfo.HasTypeArguments)
                                    {
                                        this.EnsureComma(false);
                                        new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit();
                                        this.Emitter.Comma = true;
                                    }

                                    if (!isObjectLiteral && resolvedMethod.IsStatic)
                                    {
                                        this.EnsureComma(false);
                                        this.WriteThisExtension(invocationExpression.Target);
                                        this.Emitter.Comma = true;
                                    }

                                    if (invocationExpression.Arguments.Count > 0)
                                    {
                                        this.EnsureComma(false);
                                    }

                                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit();

                                    this.WriteCloseParentheses();
                                }

                                if (!string.IsNullOrWhiteSpace(inline) || !isNative)
                                {
                                    this.Emitter.ReplaceAwaiterByVar     = oldValue;
                                    this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                                    return;
                                }
                            }
                            else if (isNative)
                            {
                                if (!string.IsNullOrWhiteSpace(inline))
                                {
                                    this.Write("");
                                    StringBuilder savedBuilder = this.Emitter.Output;
                                    this.Emitter.Output = new StringBuilder();
                                    this.WriteThisExtension(invocationExpression.Target);
                                    argsInfo.ThisArgument = this.Emitter.Output.ToString();
                                    this.Emitter.Output   = savedBuilder;
                                    new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit();
                                }
                                else
                                {
                                    argsExpressions.First().AcceptVisitor(this.Emitter);
                                    this.WriteDot();
                                    string name = this.Emitter.GetEntityName(resolvedMethod);
                                    this.Write(name);
                                    int openPos = this.Emitter.Output.Length;
                                    this.WriteOpenParentheses();
                                    new ExpressionListBlock(this.Emitter, argsExpressions.Skip(1), paramsArg, invocationExpression, openPos).Emit();
                                    this.WriteCloseParentheses();
                                }

                                this.Emitter.ReplaceAwaiterByVar     = oldValue;
                                this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                                return;
                            }
                        }
                    }
                }
            }

            var proto = false;

            if (targetMember != null && targetMember.Target is BaseReferenceExpression)
            {
                var rr = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter) as MemberResolveResult;

                if (rr != null)
                {
                    proto = rr.IsVirtualCall;

                    /*var method = rr.Member as IMethod;
                     * if (method != null && method.IsVirtual)
                     * {
                     *  proto = true;
                     * }
                     * else
                     * {
                     *  var prop = rr.Member as IProperty;
                     *
                     *  if (prop != null && prop.IsVirtual)
                     *  {
                     *      proto = true;
                     *  }
                     * }*/
                }
            }

            if (proto)
            {
                var baseType = this.Emitter.GetBaseMethodOwnerTypeDefinition(targetMember.MemberName, targetMember.TypeArguments.Count);

                bool isIgnore = this.Emitter.Validator.IsExternalType(baseType);

                bool needComma = false;

                var resolveResult = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter);

                string name = null;

                if (this.Emitter.TypeInfo.GetBaseTypes(this.Emitter).Any())
                {
                    name = BridgeTypes.ToJsName(this.Emitter.TypeInfo.GetBaseClass(this.Emitter), this.Emitter);
                }
                else
                {
                    name = BridgeTypes.ToJsName(baseType, this.Emitter);
                }

                string baseMethod;
                bool   isIgnoreGeneric = false;
                if (resolveResult is MemberResolveResult)
                {
                    MemberResolveResult memberResult = (MemberResolveResult)resolveResult;
                    baseMethod      = OverloadsCollection.Create(this.Emitter, memberResult.Member).GetOverloadName();
                    isIgnoreGeneric = Helpers.IsIgnoreGeneric(memberResult.Member, this.Emitter);
                }
                else
                {
                    baseMethod = targetMember.MemberName;
                    baseMethod = Object.Net.Utilities.StringUtils.ToLowerCamelCase(baseMethod);
                }

                this.Write(name, "." + JS.Fields.PROTOTYPE + ".", baseMethod);

                this.WriteCall();
                this.WriteOpenParentheses();
                this.WriteThis();
                this.Emitter.Comma = true;
                if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments)
                {
                    new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit();
                }

                needComma = false;

                foreach (var arg in argsExpressions)
                {
                    if (arg == null)
                    {
                        continue;
                    }

                    this.EnsureComma(false);

                    if (needComma)
                    {
                        this.WriteComma();
                    }

                    needComma = true;
                    arg.AcceptVisitor(this.Emitter);
                }
                this.Emitter.Comma = false;
                this.WriteCloseParentheses();
            }
            else
            {
                var     dynamicResolveResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as DynamicInvocationResolveResult;
                IMethod method = null;

                if (dynamicResolveResult != null)
                {
                    var group = dynamicResolveResult.Target as MethodGroupResolveResult;

                    if (group != null && group.Methods.Count() > 1)
                    {
                        method = group.Methods.FirstOrDefault(m =>
                        {
                            if (dynamicResolveResult.Arguments.Count != m.Parameters.Count)
                            {
                                return(false);
                            }

                            for (int i = 0; i < m.Parameters.Count; i++)
                            {
                                var argType = dynamicResolveResult.Arguments[i].Type;

                                if (argType.Kind == TypeKind.Dynamic)
                                {
                                    argType = this.Emitter.Resolver.Compilation.FindType(TypeCode.Object);
                                }

                                if (!m.Parameters[i].Type.Equals(argType))
                                {
                                    return(false);
                                }
                            }

                            return(true);
                        });

                        if (method == null)
                        {
                            throw new EmitterException(invocationExpression, Bridge.Translator.Constants.Messages.Exceptions.DYNAMIC_INVOCATION_TOO_MANY_OVERLOADS);
                        }
                    }
                }
                else
                {
                    var targetResolveResult     = this.Emitter.Resolver.ResolveNode(invocationExpression.Target, this.Emitter);
                    var invocationResolveResult = targetResolveResult as MemberResolveResult;

                    if (invocationResolveResult != null)
                    {
                        method = invocationResolveResult.Member as IMethod;
                    }
                }

                if (this.IsEmptyPartialInvoking(method) || IsConditionallyRemoved(invocationExpression, method))
                {
                    this.Emitter.SkipSemiColon           = true;
                    this.Emitter.ReplaceAwaiterByVar     = oldValue;
                    this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
                    return;
                }

                bool isIgnore = method != null && method.DeclaringTypeDefinition != null && this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition);

                bool needExpand = false;
                if (method != null)
                {
                    string paramsName = null;

                    var paramsParam = method.Parameters.FirstOrDefault(p => p.IsParams);
                    if (paramsParam != null)
                    {
                        paramsName = paramsParam.Name;
                    }

                    if (paramsName != null)
                    {
                        if (csharpInvocation != null && !csharpInvocation.IsExpandedForm)
                        {
                            needExpand = true;
                        }
                    }
                }

                int count = this.Emitter.Writers.Count;
                invocationExpression.Target.AcceptVisitor(this.Emitter);

                if (this.Emitter.Writers.Count > count)
                {
                    var writer = this.Emitter.Writers.Pop();

                    if (method != null && method.IsExtensionMethod)
                    {
                        StringBuilder savedBuilder = this.Emitter.Output;
                        this.Emitter.Output = new StringBuilder();
                        this.WriteThisExtension(invocationExpression.Target);
                        argsInfo.ThisArgument = this.Emitter.Output.ToString();
                        this.Emitter.Output   = savedBuilder;
                    }
                    else if (writer.ThisArg != null)
                    {
                        argsInfo.ThisArgument = writer.ThisArg;
                    }

                    new InlineArgumentsBlock(this.Emitter, argsInfo, writer.InlineCode)
                    {
                        IgnoreRange = writer.IgnoreRange
                    }.Emit();
                    var result = this.Emitter.Output.ToString();
                    this.Emitter.Output    = writer.Output;
                    this.Emitter.IsNewLine = writer.IsNewLine;
                    this.Write(result);

                    if (writer.Callback != null)
                    {
                        writer.Callback.Invoke();
                    }
                }
                else
                {
                    if (needExpand && isIgnore)
                    {
                        this.Write("." + JS.Funcs.APPLY);
                    }
                    int openPos = this.Emitter.Output.Length;
                    this.WriteOpenParentheses();

                    bool isIgnoreGeneric  = false;
                    var  invocationResult = targetResolve as InvocationResolveResult;

                    if (invocationResult != null)
                    {
                        isIgnoreGeneric = Helpers.IsIgnoreGeneric(invocationResult.Member, this.Emitter);
                    }

                    if (needExpand && isIgnore)
                    {
                        StringBuilder savedBuilder = this.Emitter.Output;
                        this.Emitter.Output = new StringBuilder();
                        this.WriteThisExtension(invocationExpression.Target);
                        var thisArg = this.Emitter.Output.ToString();
                        this.Emitter.Output = savedBuilder;

                        this.Write(thisArg);

                        this.Emitter.Comma = true;

                        if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments)
                        {
                            new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit();
                        }

                        this.EnsureComma(false);

                        if (argsExpressions.Length > 1)
                        {
                            this.WriteOpenBracket();
                            var elb = new ExpressionListBlock(this.Emitter, argsExpressions.Take(argsExpressions.Length - 1).ToArray(), paramsArg, invocationExpression, openPos);
                            elb.IgnoreExpandParams = true;
                            elb.Emit();
                            this.WriteCloseBracket();
                            this.Write(".concat(");
                            elb = new ExpressionListBlock(this.Emitter, new Expression[] { argsExpressions[argsExpressions.Length - 1] }, paramsArg, invocationExpression, openPos);
                            elb.IgnoreExpandParams = true;
                            elb.Emit();
                            this.Write(")");
                        }
                        else
                        {
                            new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, -1).Emit();
                        }
                    }
                    else
                    {
                        this.Emitter.Comma = false;
                        if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments)
                        {
                            new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit();
                        }

                        if (invocationExpression.Arguments.Count > 0 || argsExpressions.Length > 0 && !argsExpressions.All(expr => expr == null))
                        {
                            this.EnsureComma(false);
                        }

                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit();
                    }
                    this.Emitter.Comma = false;
                    this.WriteCloseParentheses();
                }
            }

            var irr = targetResolve as InvocationResolveResult;

            if (irr != null && irr.Member.MemberDefinition != null && irr.Member.MemberDefinition.ReturnType.Kind == TypeKind.TypeParameter)
            {
                Helpers.CheckValueTypeClone(this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter), invocationExpression, this, pos);
            }

            this.Emitter.ReplaceAwaiterByVar     = oldValue;
            this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
        }
        protected void VisitMemberReferenceExpression()
        {
            MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression;
            int pos = this.Emitter.Output.Length;

            ResolveResult resolveResult           = null;
            ResolveResult expressionResolveResult = null;
            string        targetVar     = null;
            string        valueVar      = null;
            bool          isStatement   = false;
            bool          isConstTarget = false;

            var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter);

            if (targetrr is ConstantResolveResult)
            {
                isConstTarget = true;
            }

            var memberTargetrr = targetrr as MemberResolveResult;

            if (memberTargetrr != null)
            {
                if (memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField)
                {
                    isConstTarget = true;
                }
                else if (memberTargetrr.IsCompileTimeConstantToString())
                {
                    isConstTarget = true;
                }
            }

            if (memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression))
            {
                resolveResult           = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);
                expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);

                if (expressionResolveResult is InvocationResolveResult)
                {
                    resolveResult = expressionResolveResult;
                }
            }
            else
            {
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);
            }

            bool oldIsAssignment = this.Emitter.IsAssignment;
            bool oldUnary        = this.Emitter.IsUnaryAccessor;

            if (resolveResult == null)
            {
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                if (isConstTarget)
                {
                    this.Write("(");
                }
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                if (isConstTarget)
                {
                    this.Write(")");
                }
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.WriteDot();
                string name = memberReferenceExpression.MemberName;
                this.Write(name.ToLowerCamelCase());

                return;
            }

            if (resolveResult is DynamicInvocationResolveResult)
            {
                resolveResult = ((DynamicInvocationResolveResult)resolveResult).Target;
            }

            if (resolveResult is MethodGroupResolveResult)
            {
                var oldResult = (MethodGroupResolveResult)resolveResult;
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);

                if (resolveResult is DynamicInvocationResolveResult)
                {
                    var method = oldResult.Methods.Last();
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                }
            }

            MemberResolveResult        member     = resolveResult as MemberResolveResult;
            Tuple <bool, bool, string> inlineInfo = member != null?this.Emitter.GetInlineCode(memberReferenceExpression) : null;

            //string inline = member != null ? this.Emitter.GetInline(member.Member) : null;
            string inline    = inlineInfo != null ? inlineInfo.Item3 : null;
            bool   hasInline = !string.IsNullOrEmpty(inline);
            bool   hasThis   = hasInline && inline.Contains("{this}");

            if (hasThis)
            {
                this.Write("");
                var oldBuilder = this.Emitter.Output;
                this.Emitter.Output          = new StringBuilder();
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                if (isConstTarget)
                {
                    this.Write("(");
                }
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                if (isConstTarget)
                {
                    this.Write(")");
                }
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                inline = inline.Replace("{this}", this.Emitter.Output.ToString());
                this.Emitter.Output = oldBuilder;

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    if (member != null && member.Member is IMethod)
                    {
                        throw new EmitterException(memberReferenceExpression, "The templated method (" + member.Member.FullName + ") cannot be used like reference");
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }

                return;
            }

            if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && !hasInline)
            {
                this.WriteScript(member.ConstantValue);
            }
            else if (hasInline && member.Member.IsStatic)
            {
                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    if (member != null && member.Member is IMethod)
                    {
                        var r     = new Regex(@"([$\w\.]+)\(\s*\S.*\)");
                        var match = r.Match(inline);

                        if (match.Success)
                        {
                            this.Write(match.Groups[1].Value);
                        }
                        else
                        {
                            throw new EmitterException(memberReferenceExpression, "The templated method (" + member.Member.FullName + ") cannot be used like reference");
                        }
                    }
                    else
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                    }
                }
            }
            else
            {
                if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum)
                {
                    var typeDef = member.Member.DeclaringType as DefaultResolvedTypeDefinition;

                    if (typeDef != null)
                    {
                        var enumMode = this.Emitter.Validator.EnumEmitMode(typeDef);

                        if ((this.Emitter.Validator.IsIgnoreType(typeDef) && enumMode == -1) || enumMode == 2)
                        {
                            this.WriteScript(member.ConstantValue);

                            return;
                        }

                        if (enumMode >= 3)
                        {
                            string enumStringName = member.Member.Name;
                            var    attr           = Helpers.GetInheritedAttribute(member.Member, Translator.Bridge_ASSEMBLY + ".NameAttribute");

                            if (attr != null)
                            {
                                enumStringName = this.Emitter.GetEntityName(member.Member);
                            }
                            else
                            {
                                switch (enumMode)
                                {
                                case 3:
                                    enumStringName = Object.Net.Utilities.StringUtils.ToLowerCamelCase(member.Member.Name);
                                    break;

                                case 4:
                                    break;

                                case 5:
                                    enumStringName = enumStringName.ToLowerInvariant();
                                    break;

                                case 6:
                                    enumStringName = enumStringName.ToUpperInvariant();
                                    break;
                                }
                            }

                            this.WriteScript(enumStringName);

                            return;
                        }
                    }
                }

                bool isInvokeInCurClass = false;
                if (resolveResult is TypeResolveResult)
                {
                    TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult;
                    this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter));

                    /*
                     * var isNative = this.Emitter.Validator.IsIgnoreType(typeResolveResult.Type.GetDefinition());
                     * if(isNative) {
                     *  this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter));
                     * }
                     * else {
                     *  this.Write("Bridge.get(" + BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter) + ")");
                     * }*/
                    return;
                }
                else if (member != null &&
                         member.Member is IMethod &&
                         !(member is InvocationResolveResult) &&
                         !(
                             memberReferenceExpression.Parent is InvocationExpression &&
                             memberReferenceExpression.NextSibling != null &&
                             memberReferenceExpression.NextSibling.Role is TokenRole &&
                             ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "("
                             )
                         )
                {
                    var  resolvedMethod = (IMethod)member.Member;
                    bool isStatic       = resolvedMethod != null && resolvedMethod.IsStatic;

                    var isExtensionMethod = resolvedMethod.IsExtensionMethod;

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;

                    if (!isStatic)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + "." + (isExtensionMethod ? Bridge.Translator.Emitter.DELEGATE_BIND_SCOPE : Bridge.Translator.Emitter.DELEGATE_BIND) + "(");
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        this.Write(", ");
                    }

                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (isExtensionMethod)
                    {
                        this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter));
                    }
                    else
                    {
                        this.Emitter.IsAssignment    = false;
                        this.Emitter.IsUnaryAccessor = false;
                        if (isConstTarget)
                        {
                            this.Write("(");
                        }
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        if (isConstTarget)
                        {
                            this.Write(")");
                        }
                        this.Emitter.IsAssignment    = oldIsAssignment;
                        this.Emitter.IsUnaryAccessor = oldUnary;
                    }

                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());

                    if (!isStatic)
                    {
                        this.Write(")");
                    }

                    return;
                }
                else
                {
                    bool isProperty = false;

                    if (member != null && member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                    {
                        isProperty = true;
                        bool writeTargetVar = false;

                        if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                        {
                            writeTargetVar = true;
                        }
                        else if (this.Emitter.IsUnaryAccessor)
                        {
                            writeTargetVar = true;

                            isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement;

                            if (NullableType.IsNullable(member.Type))
                            {
                                isStatement = false;
                            }

                            if (!isStatement)
                            {
                                this.WriteOpenParentheses();
                            }
                        }

                        if (writeTargetVar)
                        {
                            bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult);

                            if (!(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField))
                            {
                                targetVar = this.GetTempVarName();
                                this.WriteVar();
                                this.Write(targetVar);
                                this.Write(" = ");
                            }
                        }
                    }

                    if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
                    {
                        valueVar = this.GetTempVarName();

                        this.Write(valueVar);
                        this.Write(" = ");
                    }

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;
                    if (isConstTarget)
                    {
                        this.Write("(");
                    }
                    isInvokeInCurClass = resolveResult is InvocationResolveResult && member.Member.IsInternalMember();
                    if (!isInvokeInCurClass)
                    {
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                    }
                    if (isConstTarget)
                    {
                        this.Write(")");
                    }
                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (targetVar != null)
                    {
                        if (this.Emitter.IsUnaryAccessor && !isStatement)
                        {
                            this.WriteComma(false);

                            valueVar = this.GetTempVarName();

                            this.Write(valueVar);
                            this.Write(" = ");

                            this.Write(targetVar);
                        }
                        else
                        {
                            this.WriteSemiColon();
                            this.WriteNewLine();
                            this.Write(targetVar);
                        }
                    }
                }

                if (member != null && member.Member != null)
                {
                    if (!isInvokeInCurClass)
                    {
                        if (!member.Member.IsStatic && ((member.Member.SymbolKind == SymbolKind.Method && !this.Emitter.Validator.IsDelegateOrLambda(expressionResolveResult)) || (member.Member.SymbolKind == SymbolKind.Property && !Helpers.IsFieldProperty(member.Member, this.Emitter))))
                        {
                            this.WriteObjectColon();
                        }
                        else
                        {
                            this.WriteDot();
                        }
                    }
                }
                else
                {
                    this.WriteDot();
                }

                if (member == null)
                {
                    if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic)
                    {
                        this.Write(memberReferenceExpression.MemberName);
                    }
                    else
                    {
                        this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase());
                    }
                }
                else if (!string.IsNullOrEmpty(inline))
                {
                    if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment))
                    {
                        this.PushWriter(inline);
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                {
                    var proto = false;
                    if (this.MemberReferenceExpression.Target is BaseReferenceExpression && member != null)
                    {
                        var prop = member.Member as IProperty;

                        if (prop != null && (prop.IsVirtual || prop.IsOverride))
                        {
                            proto = true;
                        }
                    }

                    if (Helpers.IsFieldProperty(member.Member, this.Emitter))
                    {
                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                    }
                    else if (!this.Emitter.IsAssignment)
                    {
                        if (this.Emitter.IsUnaryAccessor)
                        {
                            bool isNullable = NullableType.IsNullable(member.Member.ReturnType);
                            bool isDecimal  = Helpers.IsDecimalType(member.Member.ReturnType, this.Emitter.Resolver);

                            if (isStatement)
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                if (isDecimal)
                                {
                                    if (isNullable)
                                    {
                                        this.Write("Bridge.Nullable.lift1");
                                        this.WriteOpenParentheses();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.WriteScript("inc");
                                        }
                                        else
                                        {
                                            this.WriteScript("dec");
                                        }

                                        this.WriteComma();

                                        if (targetVar != null)
                                        {
                                            this.Write(targetVar);
                                        }
                                        else
                                        {
                                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        }

                                        this.WriteDot();

                                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                        if (proto)
                                        {
                                            this.Write(".call");
                                            this.WriteOpenParentheses();
                                            this.WriteThis();
                                            this.WriteCloseParentheses();
                                        }
                                        else
                                        {
                                            this.WriteOpenParentheses();
                                            this.WriteCloseParentheses();
                                        }

                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        if (targetVar != null)
                                        {
                                            this.Write(targetVar);
                                        }
                                        else
                                        {
                                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        }

                                        this.WriteDot();

                                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                        if (proto)
                                        {
                                            this.Write(".call");
                                            this.WriteOpenParentheses();
                                            this.WriteThis();
                                            this.WriteCloseParentheses();
                                        }
                                        else
                                        {
                                            this.WriteOpenParentheses();
                                            this.WriteCloseParentheses();
                                        }

                                        this.WriteDot();

                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.Write("inc");
                                        }
                                        else
                                        {
                                            this.Write("dec");
                                        }

                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();

                                        this.WriteCloseParentheses();
                                    }
                                }
                                else
                                {
                                    if (targetVar != null)
                                    {
                                        this.Write(targetVar);
                                    }
                                    else
                                    {
                                        if (isConstTarget)
                                        {
                                            this.Write("(");
                                        }
                                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        if (isConstTarget)
                                        {
                                            this.Write(")");
                                        }
                                    }

                                    this.WriteObjectColon();
                                    this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                    if (proto)
                                    {
                                        this.Write(".call");
                                        this.WriteOpenParentheses();
                                        this.WriteThis();
                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();
                                    }

                                    if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        this.Write(" + ");
                                    }
                                    else
                                    {
                                        this.Write(" - ");
                                    }

                                    this.Write("1");
                                    this.WriteCloseParentheses();
                                }
                            }
                            else
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }
                                this.WriteComma();

                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    if (isConstTarget)
                                    {
                                        this.Write("(");
                                    }
                                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                    if (isConstTarget)
                                    {
                                        this.Write(")");
                                    }
                                }

                                this.WriteDot();
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));

                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                if (isDecimal)
                                {
                                    if (isNullable)
                                    {
                                        this.Write("Bridge.Nullable.lift1");
                                        this.WriteOpenParentheses();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.WriteScript("inc");
                                        }
                                        else
                                        {
                                            this.WriteScript("dec");
                                        }
                                        this.WriteComma();
                                        this.Write(valueVar);
                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        this.Write(valueVar);
                                        this.WriteDot();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.Write("inc");
                                        }
                                        else
                                        {
                                            this.Write("dec");
                                        }
                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();
                                    }
                                }
                                else
                                {
                                    this.Write(valueVar);

                                    if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        this.Write("+");
                                    }
                                    else
                                    {
                                        this.Write("-");
                                    }
                                    this.Write("1");
                                }

                                this.WriteCloseParentheses();
                                this.WriteComma();

                                bool isPreOp = this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                               this.Emitter.UnaryOperatorType == UnaryOperatorType.Decrement;

                                if (isPreOp)
                                {
                                    if (targetVar != null)
                                    {
                                        this.Write(targetVar);
                                    }
                                    else
                                    {
                                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                    }
                                    this.WriteDot();
                                    this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.Write(valueVar);
                                }
                                this.WriteCloseParentheses();

                                if (valueVar != null)
                                {
                                    this.RemoveTempVar(valueVar);
                                }
                            }

                            if (targetVar != null)
                            {
                                this.RemoveTempVar(targetVar);
                            }
                        }
                        else
                        {
                            this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                            if (proto)
                            {
                                this.Write(".call");
                                this.WriteOpenParentheses();
                                this.WriteThis();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                this.WriteOpenParentheses();
                                this.WriteCloseParentheses();
                            }
                        }
                    }
                    else if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                    {
                        if (targetVar != null)
                        {
                            this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                                                          proto ? ".call(this, " : "(",
                                                          targetVar,
                                                          ".",
                                                          Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                                                          proto ? ".call(this)" : "()",
                                                          "{0})"), () => {
                                this.RemoveTempVar(targetVar);
                            });
                        }
                        else
                        {
                            var oldWriter = this.SaveWriter();
                            this.NewWriter();

                            this.Emitter.IsAssignment    = false;
                            this.Emitter.IsUnaryAccessor = false;
                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                            this.Emitter.IsAssignment    = oldIsAssignment;
                            this.Emitter.IsUnaryAccessor = oldUnary;
                            var trg = this.Emitter.Output.ToString();

                            this.RestoreWriter(oldWriter);
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + "({0})");

                            /*
                             * this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                             * proto ? ".call(this, " : "(",
                             * trg,
                             * ".",
                             * Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                             * proto ? ".call(this)" : "()",
                             * "{0})"));*/
                        }
                    }
                    else
                    {
                        if (proto)
                        {
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + ".call(this, {0})");
                        }
                        else
                        {
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + "({0})");
                        }
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Field)
                {
                    bool isConst = this.Emitter.IsMemberConst(member.Member);
                    if (isConst)
                    {
                        this.WriteScript(member.ConstantValue);
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());
                    }
                }
                else if (resolveResult is InvocationResolveResult)
                {
                    InvocationResolveResult       invocationResult  = (InvocationResolveResult)resolveResult;
                    CSharpInvocationResolveResult cInvocationResult = (CSharpInvocationResolveResult)resolveResult;
                    var expresssionMember = expressionResolveResult as MemberResolveResult;

                    if (expresssionMember != null &&
                        cInvocationResult != null &&
                        cInvocationResult.IsDelegateInvocation &&
                        invocationResult.Member != expresssionMember.Member)
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName());
                    }
                    else
                    {
                        string name = OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName();
                        if (isInvokeInCurClass && Emitter.LocalsNamesMap.ContainsKey(name))
                        {
                            string newName = this.GetUniqueName(name);
                            this.IntroduceTempVar(newName + " = " + name);
                            name = newName;
                        }
                        this.Write(name);
                    }
                }
                else if (member.Member is DefaultResolvedEvent)
                {
                    if (this.Emitter.IsAssignment &&
                        (this.Emitter.AssignmentType == AssignmentOperatorType.Add ||
                         this.Emitter.AssignmentType == AssignmentOperatorType.Subtract))
                    {
                        this.Write(this.Emitter.AssignmentType == AssignmentOperatorType.Add ? "add" : "remove");
                        this.Write(
                            OverloadsCollection.Create(this.Emitter, member.Member,
                                                       this.Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName());
                        this.WriteOpenParentheses();
                    }
                    else
                    {
                        this.Write(this.Emitter.GetEntityName(member.Member, true));
                    }
                }
                else
                {
                    this.Write(this.Emitter.GetEntityName(member.Member));
                }

                Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this, pos);
            }
        }
Exemplo n.º 7
0
        protected void VisitMemberReferenceExpression()
        {
            MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression;

            ResolveResult resolveResult           = null;
            ResolveResult expressionResolveResult = null;
            string        targetVar   = null;
            string        valueVar    = null;
            bool          isStatement = false;

            var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter);

            if (memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression))
            {
                resolveResult           = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);
                expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);

                if (expressionResolveResult is InvocationResolveResult)
                {
                    resolveResult = expressionResolveResult;
                }
            }
            else
            {
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);
            }

            bool oldIsAssignment = this.Emitter.IsAssignment;
            bool oldUnary        = this.Emitter.IsUnaryAccessor;

            if (resolveResult == null)
            {
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.WriteDot();
                string name = memberReferenceExpression.MemberName;
                this.Write(name.ToLowerCamelCase());

                return;
            }

            if (resolveResult is DynamicInvocationResolveResult)
            {
                resolveResult = ((DynamicInvocationResolveResult)resolveResult).Target;
            }

            if (resolveResult is MethodGroupResolveResult)
            {
                var oldResult = (MethodGroupResolveResult)resolveResult;
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);

                if (resolveResult is DynamicInvocationResolveResult)
                {
                    var method = oldResult.Methods.Last();
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                }
            }

            MemberResolveResult member = resolveResult as MemberResolveResult;
            var globalTarget           = member != null?this.Emitter.IsGlobalTarget(member.Member) : null;

            if (globalTarget != null && globalTarget.Item1)
            {
                var target = globalTarget.Item2;

                if (!string.IsNullOrWhiteSpace(target))
                {
                    bool assign           = false;
                    var  memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent;
                    var  targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression;
                    var  assignment       = memberExpression as AssignmentExpression;
                    if (assignment != null && assignment.Right == targetExpression)
                    {
                        assign = true;
                    }
                    else
                    {
                        var varInit = memberExpression as VariableInitializer;
                        if (varInit != null && varInit.Initializer == targetExpression)
                        {
                            assign = true;
                        }
                        else if (memberExpression is InvocationExpression)
                        {
                            var targetInvocation = (InvocationExpression)memberExpression;
                            if (targetInvocation.Arguments.Any(a => a == targetExpression))
                            {
                                assign = true;
                            }
                        }
                    }

                    if (assign)
                    {
                        if (resolveResult is InvocationResolveResult)
                        {
                            this.PushWriter(target);
                        }
                        else
                        {
                            this.Write(target);
                        }

                        return;
                    }
                }

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter("");
                }

                return;
            }

            string inline = member != null?this.Emitter.GetInline(member.Member) : null;

            bool hasInline = !string.IsNullOrEmpty(inline);
            bool hasThis   = hasInline && inline.Contains("{this}");

            if (hasThis)
            {
                this.Write("");
                var oldBuilder = this.Emitter.Output;
                this.Emitter.Output          = new StringBuilder();
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                inline = inline.Replace("{this}", this.Emitter.Output.ToString());
                this.Emitter.Output = oldBuilder;

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    this.Write(inline);
                }

                return;
            }

            if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member))
            {
                this.WriteScript(member.ConstantValue);
            }
            else if (hasInline && member.Member.IsStatic)
            {
                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    //this.Write(inline);
                    new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                }
            }
            else
            {
                if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum)
                {
                    var typeDef = member.Member.DeclaringType as DefaultResolvedTypeDefinition;

                    if (typeDef != null)
                    {
                        var enumMode = this.Emitter.Validator.EnumEmitMode(typeDef);

                        if ((this.Emitter.Validator.IsIgnoreType(typeDef) && enumMode == -1) || enumMode == 2)
                        {
                            this.WriteScript(member.ConstantValue);

                            return;
                        }

                        if (enumMode >= 3)
                        {
                            string enumStringName = member.Member.Name;
                            var    attr           = this.Emitter.GetAttribute(member.Member.Attributes, Translator.Bridge_ASSEMBLY + ".NameAttribute");

                            if (attr != null)
                            {
                                enumStringName = this.Emitter.GetEntityName(member.Member);
                            }
                            else
                            {
                                switch (enumMode)
                                {
                                case 3:
                                    enumStringName = Object.Net.Utilities.StringUtils.ToLowerCamelCase(member.Member.Name);
                                    break;

                                case 4:
                                    break;

                                case 5:
                                    enumStringName = enumStringName.ToLowerInvariant();
                                    break;

                                case 6:
                                    enumStringName = enumStringName.ToUpperInvariant();
                                    break;
                                }
                            }

                            this.WriteScript(enumStringName);

                            return;
                        }
                    }
                }

                if (resolveResult is TypeResolveResult)
                {
                    TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult;

                    this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter));

                    return;
                }
                else if (member != null &&
                         member.Member is IMethod &&
                         !(member is InvocationResolveResult) &&
                         !(
                             memberReferenceExpression.Parent is InvocationExpression &&
                             memberReferenceExpression.NextSibling != null &&
                             memberReferenceExpression.NextSibling.Role is TokenRole &&
                             ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "("
                             )
                         )
                {
                    var  resolvedMethod = (IMethod)member.Member;
                    bool isStatic       = resolvedMethod != null && resolvedMethod.IsStatic;

                    var isExtensionMethod = resolvedMethod.IsExtensionMethod;

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;

                    if (!isStatic)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + "." + (isExtensionMethod ? Bridge.Translator.Emitter.DELEGATE_BIND_SCOPE : Bridge.Translator.Emitter.DELEGATE_BIND) + "(");
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        this.Write(", ");
                    }

                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (isExtensionMethod)
                    {
                        this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter));
                    }
                    else
                    {
                        this.Emitter.IsAssignment    = false;
                        this.Emitter.IsUnaryAccessor = false;
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        this.Emitter.IsAssignment    = oldIsAssignment;
                        this.Emitter.IsUnaryAccessor = oldUnary;
                    }

                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());

                    if (!isStatic)
                    {
                        this.Write(")");
                    }

                    return;
                }
                else
                {
                    bool isProperty = false;

                    if (member != null && member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                    {
                        isProperty = true;
                        bool writeTargetVar = false;

                        if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                        {
                            writeTargetVar = true;
                        }
                        else if (this.Emitter.IsUnaryAccessor)
                        {
                            writeTargetVar = true;

                            isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement;

                            if (NullableType.IsNullable(member.Type))
                            {
                                isStatement = false;
                            }

                            if (!isStatement)
                            {
                                this.WriteOpenParentheses();
                            }
                        }

                        if (writeTargetVar)
                        {
                            var  memberTargetrr = targetrr as MemberResolveResult;
                            bool isField        = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult);

                            if (!(targetrr is ThisResolveResult || targetrr is LocalResolveResult || isField))
                            {
                                targetVar = this.GetTempVarName();

                                this.Write(targetVar);
                                this.Write(" = ");
                            }
                        }
                    }

                    if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
                    {
                        valueVar = this.GetTempVarName();

                        this.Write(valueVar);
                        this.Write(" = ");
                    }

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;
                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (targetVar != null)
                    {
                        if (this.Emitter.IsUnaryAccessor && !isStatement)
                        {
                            this.WriteComma(false);

                            valueVar = this.GetTempVarName();

                            this.Write(valueVar);
                            this.Write(" = ");

                            this.Write(targetVar);
                        }
                        else
                        {
                            this.WriteSemiColon();
                            this.WriteNewLine();
                            this.Write(targetVar);
                        }
                    }
                }

                var targetResolveResult = targetrr as MemberResolveResult;

                if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null)
                {
                    this.WriteDot();
                }

                if (member == null)
                {
                    if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic)
                    {
                        this.Write(memberReferenceExpression.MemberName);
                    }
                    else
                    {
                        this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase());
                    }
                }
                else if (!string.IsNullOrEmpty(inline))
                {
                    if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment))
                    {
                        this.PushWriter(inline);
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                {
                    var proto = false;
                    if (this.MemberReferenceExpression.Target is BaseReferenceExpression && member != null)
                    {
                        var prop = member.Member as IProperty;

                        if (prop != null && prop.IsVirtual)
                        {
                            proto = true;
                        }
                    }

                    if (Helpers.IsFieldProperty(member.Member, this.Emitter))
                    {
                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                    }
                    else if (!this.Emitter.IsAssignment)
                    {
                        if (this.Emitter.IsUnaryAccessor)
                        {
                            bool isNullable = NullableType.IsNullable(member.Member.ReturnType);
                            bool isDecimal  = Helpers.IsDecimalType(member.Member.ReturnType, this.Emitter.Resolver);

                            if (isStatement)
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                if (isDecimal)
                                {
                                    if (isNullable)
                                    {
                                        this.Write("Bridge.Nullable.lift1");
                                        this.WriteOpenParentheses();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.WriteScript("inc");
                                        }
                                        else
                                        {
                                            this.WriteScript("dec");
                                        }

                                        this.WriteComma();

                                        if (targetVar != null)
                                        {
                                            this.Write(targetVar);
                                        }
                                        else
                                        {
                                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        }

                                        this.WriteDot();

                                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                        if (proto)
                                        {
                                            this.Write(".call");
                                            this.WriteOpenParentheses();
                                            this.WriteThis();
                                            this.WriteCloseParentheses();
                                        }
                                        else
                                        {
                                            this.WriteOpenParentheses();
                                            this.WriteCloseParentheses();
                                        }

                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        if (targetVar != null)
                                        {
                                            this.Write(targetVar);
                                        }
                                        else
                                        {
                                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                        }

                                        this.WriteDot();

                                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                        if (proto)
                                        {
                                            this.Write(".call");
                                            this.WriteOpenParentheses();
                                            this.WriteThis();
                                            this.WriteCloseParentheses();
                                        }
                                        else
                                        {
                                            this.WriteOpenParentheses();
                                            this.WriteCloseParentheses();
                                        }

                                        this.WriteDot();

                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.Write("inc");
                                        }
                                        else
                                        {
                                            this.Write("dec");
                                        }

                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();

                                        this.WriteCloseParentheses();
                                    }
                                }
                                else
                                {
                                    if (targetVar != null)
                                    {
                                        this.Write(targetVar);
                                    }
                                    else
                                    {
                                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                    }

                                    this.WriteDot();

                                    this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                    if (proto)
                                    {
                                        this.Write(".call");
                                        this.WriteOpenParentheses();
                                        this.WriteThis();
                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();
                                    }

                                    if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        this.Write("+");
                                    }
                                    else
                                    {
                                        this.Write("-");
                                    }

                                    this.Write("1");
                                    this.WriteCloseParentheses();
                                }
                            }
                            else
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }
                                this.WriteComma();

                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));

                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                if (isDecimal)
                                {
                                    if (isNullable)
                                    {
                                        this.Write("Bridge.Nullable.lift1");
                                        this.WriteOpenParentheses();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.WriteScript("inc");
                                        }
                                        else
                                        {
                                            this.WriteScript("dec");
                                        }
                                        this.WriteComma();
                                        this.Write(valueVar);
                                        this.WriteCloseParentheses();
                                    }
                                    else
                                    {
                                        this.Write(valueVar);
                                        this.WriteDot();
                                        if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                        {
                                            this.Write("inc");
                                        }
                                        else
                                        {
                                            this.Write("dec");
                                        }
                                        this.WriteOpenParentheses();
                                        this.WriteCloseParentheses();
                                    }
                                }
                                else
                                {
                                    this.Write(valueVar);

                                    if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                    {
                                        this.Write("+");
                                    }
                                    else
                                    {
                                        this.Write("-");
                                    }
                                    this.Write("1");
                                }

                                this.WriteCloseParentheses();
                                this.WriteComma();

                                bool isPreOp = this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                               this.Emitter.UnaryOperatorType == UnaryOperatorType.Decrement;

                                if (isPreOp)
                                {
                                    if (targetVar != null)
                                    {
                                        this.Write(targetVar);
                                    }
                                    else
                                    {
                                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                    }
                                    this.WriteDot();
                                    this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.Write(valueVar);
                                }
                                this.WriteCloseParentheses();

                                if (valueVar != null)
                                {
                                    this.RemoveTempVar(valueVar);
                                }
                            }

                            if (targetVar != null)
                            {
                                this.RemoveTempVar(targetVar);
                            }
                        }
                        else
                        {
                            this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                            if (proto)
                            {
                                this.Write(".call");
                                this.WriteOpenParentheses();
                                this.WriteThis();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                this.WriteOpenParentheses();
                                this.WriteCloseParentheses();
                            }
                        }
                    }
                    else if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                    {
                        if (targetVar != null)
                        {
                            this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                                                          proto ? ".call(this, " : "(",
                                                          targetVar,
                                                          ".",
                                                          Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                                                          proto ? ".call(this)" : "()",
                                                          "{0})"), () => { this.RemoveTempVar(targetVar); });
                        }
                        else
                        {
                            var oldWriter = this.SaveWriter();
                            this.NewWriter();

                            this.Emitter.IsAssignment    = false;
                            this.Emitter.IsUnaryAccessor = false;
                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                            this.Emitter.IsAssignment    = oldIsAssignment;
                            this.Emitter.IsUnaryAccessor = oldUnary;
                            var trg = this.Emitter.Output.ToString();

                            this.RestoreWriter(oldWriter);
                            this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                                                          proto ? ".call(this, " : "(",
                                                          trg,
                                                          ".",
                                                          Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                                                          proto ? ".call(this)" : "()",
                                                          "{0})"));
                        }
                    }
                    else
                    {
                        if (proto)
                        {
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + ".call(this, {0})");
                        }
                        else
                        {
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + "({0})");
                        }
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Field)
                {
                    bool isConst = this.Emitter.IsMemberConst(member.Member);

                    if (isConst && this.Emitter.IsInlineConst(member.Member))
                    {
                        this.WriteScript(member.ConstantValue);
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());
                    }
                }
                else if (resolveResult is InvocationResolveResult)
                {
                    InvocationResolveResult       invocationResult  = (InvocationResolveResult)resolveResult;
                    CSharpInvocationResolveResult cInvocationResult = (CSharpInvocationResolveResult)resolveResult;
                    var expresssionMember = expressionResolveResult as MemberResolveResult;

                    if (expresssionMember != null &&
                        cInvocationResult != null &&
                        cInvocationResult.IsDelegateInvocation &&
                        invocationResult.Member != expresssionMember.Member)
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName());
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName());
                    }
                }
                else if (member.Member is DefaultResolvedEvent && this.Emitter.IsAssignment && (this.Emitter.AssignmentType == AssignmentOperatorType.Add || this.Emitter.AssignmentType == AssignmentOperatorType.Subtract))
                {
                    this.Write(this.Emitter.AssignmentType == AssignmentOperatorType.Add ? "add" : "remove");
                    this.Write(OverloadsCollection.Create(this.Emitter, member.Member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName());
                    this.WriteOpenParentheses();
                }
                else
                {
                    this.Write(this.Emitter.GetEntityName(member.Member));
                }

                Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this);
            }
        }
Exemplo n.º 8
0
        private void CheckFieldProperty(PropertyDeclaration propertyDeclaration, ref bool isResolvedProperty, ref MemberResolveResult resolvedProperty)
        {
            if (this.HasExternal(propertyDeclaration) || this.CurrentType.IsObjectLiteral)
            {
                return;
            }

            var possiblyWrongGetter = !propertyDeclaration.Getter.IsNull &&
                                      !propertyDeclaration.Getter.Body.IsNull &&
                                      !this.HasTemplate(propertyDeclaration.Getter) &&
                                      !this.HasScript(propertyDeclaration.Getter);

            var possiblyWrongSetter = !propertyDeclaration.Setter.IsNull &&
                                      !propertyDeclaration.Setter.Body.IsNull &&
                                      !this.HasTemplate(propertyDeclaration.Setter) &&
                                      !this.HasScript(propertyDeclaration.Setter);

            if (possiblyWrongGetter || possiblyWrongSetter)
            {
                if (!isResolvedProperty)
                {
                    resolvedProperty   = Resolver.ResolveNode(propertyDeclaration, null) as MemberResolveResult;
                    isResolvedProperty = true;
                }

                if (resolvedProperty != null && resolvedProperty.Member != null)
                {
                    var isField = Helpers.IsFieldProperty(resolvedProperty.Member, AssemblyInfo);

                    if (isField)
                    {
                        var message = string.Format(
                            "{0} is marked with [FieldProperty] attribute but implements {1}{2}. To fix the problem either remove [FieldProperty] (swith off bridge.json option `autoPropertyToField`) or add [External]/[Template] attributes",
                            resolvedProperty.Member.ToString(),
                            possiblyWrongGetter ? "getter" : string.Empty,
                            possiblyWrongSetter ? (possiblyWrongGetter ? " and " : string.Empty) + "setter" : string.Empty
                            );

                        throw new EmitterException(propertyDeclaration, message);
                    }
                }
            }
        }
Exemplo n.º 9
0
        protected void WriteTarget(MemberResolveResult memberResult)
        {
            if (memberResult.Member.IsStatic)
            {
                this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter));
            }
            else
            {
                this.WriteThis();
            }

            this.WriteDot();
        }
Exemplo n.º 10
0
        public void NestedClassParentStaticField()
        {
            MemberResolveResult mrr = Resolve <MemberResolveResult>(nestedClassProg, "outerField", "/*inner*/");

            Assert.AreEqual("Outer.outerField", mrr.ResolvedMember.FullyQualifiedName);
        }
Exemplo n.º 11
0
        private void WriteInterfaceMember(string interfaceTempVar, MemberResolveResult resolveResult, bool isSetter, string prefix = null)
        {
            var externalInterface = this.Emitter.Validator.IsExternalInterface(resolveResult.Member.DeclaringTypeDefinition);

            if (interfaceTempVar != null && externalInterface == null)
            {
                this.WriteComma();
                this.Write(interfaceTempVar);
            }

            if (externalInterface != null && externalInterface.IsDualImplementation)
            {
                if (interfaceTempVar != null)
                {
                    this.WriteCloseParentheses();
                }

                this.WriteOpenBracket();
                this.Write(JS.Funcs.BRIDGE_GET_I);
                this.WriteOpenParentheses();

                if (interfaceTempVar != null)
                {
                    this.Write(interfaceTempVar);
                }
                else
                {
                    this.WriteSimpleTarget(resolveResult);
                }

                this.WriteComma();

                var interfaceName = OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(false, prefix);

                if (interfaceName.StartsWith("\""))
                {
                    this.Write(interfaceName);
                }
                else
                {
                    this.WriteScript(interfaceName);
                }

                this.WriteComma();
                this.WriteScript(OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(true, prefix));

                this.Write(")");
                this.WriteCloseBracket();

                return;
            }

            this.WriteOpenBracket();
            this.Write(OverloadsCollection.Create(Emitter, resolveResult.Member, isSetter).GetOverloadName(externalInterface != null && externalInterface.IsSimpleImplementation, prefix));
            this.WriteCloseBracket();

            if (interfaceTempVar != null)
            {
                this.WriteCloseParentheses();
            }
        }
Exemplo n.º 12
0
        protected string WriteTarget(ResolveResult resolveResult, bool isInterfaceMember, MemberResolveResult memberTargetrr, ResolveResult targetrr, bool openParentheses)
        {
            string interfaceTempVar = null;

            if (isInterfaceMember)
            {
                MemberResolveResult member = resolveResult as MemberResolveResult;
                bool nativeImplementation  = true;
                var  externalInterface     = member != null && this.Emitter.Validator.IsExternalInterface(member.Member.DeclaringTypeDefinition, out nativeImplementation);
                bool isField = externalInterface && memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult);

                if (externalInterface && !nativeImplementation && !(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField))
                {
                    if (openParentheses)
                    {
                        this.WriteOpenParentheses();
                    }

                    interfaceTempVar = this.GetTempVarName();
                    this.Write(interfaceTempVar);
                    this.Write(" = ");
                }
            }

            this.WriteSimpleTarget(resolveResult);

            return(interfaceTempVar);
        }
Exemplo n.º 13
0
        protected void VisitMemberReferenceExpression()
        {
            MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression;
            int  pos      = this.Emitter.Output.Length;
            bool isRefArg = this.Emitter.IsRefArg;

            this.Emitter.IsRefArg = false;

            ResolveResult resolveResult           = null;
            ResolveResult expressionResolveResult = null;
            string        targetVar     = null;
            string        valueVar      = null;
            bool          isStatement   = false;
            bool          isConstTarget = false;

            var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter);

            if (targetrr is ConstantResolveResult)
            {
                isConstTarget = true;
            }

            var memberTargetrr = targetrr as MemberResolveResult;

            if (memberTargetrr != null && memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField && this.Emitter.Validator.EnumEmitMode(memberTargetrr.Type) == 2)
            {
                isConstTarget = true;
            }

            if (memberReferenceExpression.Target is ParenthesizedExpression ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Int64)) ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.UInt64)) ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Decimal)))
            {
                isConstTarget = false;
            }

            var isInvoke = memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression);

            if (isInvoke)
            {
                resolveResult           = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);
                expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);

                if (expressionResolveResult is InvocationResolveResult)
                {
                    resolveResult = expressionResolveResult;
                }
                else if (expressionResolveResult is MemberResolveResult)
                {
                    if (((MemberResolveResult)expressionResolveResult).Member is IProperty)
                    {
                        resolveResult = expressionResolveResult;
                    }
                }
            }
            else
            {
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);
            }

            bool oldIsAssignment = this.Emitter.IsAssignment;
            bool oldUnary        = this.Emitter.IsUnaryAccessor;

            if (resolveResult == null)
            {
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                if (isConstTarget)
                {
                    this.Write("(");
                }
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                if (isConstTarget)
                {
                    this.Write(")");
                }
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.WriteDot();
                string name = memberReferenceExpression.MemberName;
                this.Write(name.ToLowerCamelCase());

                return;
            }

            bool isDynamic = false;

            if (resolveResult is DynamicInvocationResolveResult)
            {
                var dynamicResolveResult = (DynamicInvocationResolveResult)resolveResult;
                var group = dynamicResolveResult.Target as MethodGroupResolveResult;

                if (group != null && group.Methods.Count() > 1)
                {
                    var method = group.Methods.FirstOrDefault(m =>
                    {
                        if (dynamicResolveResult.Arguments.Count != m.Parameters.Count)
                        {
                            return(false);
                        }

                        for (int i = 0; i < m.Parameters.Count; i++)
                        {
                            var argType = dynamicResolveResult.Arguments[i].Type;

                            if (argType.Kind == TypeKind.Dynamic)
                            {
                                argType = this.Emitter.Resolver.Compilation.FindType(TypeCode.Object);
                            }

                            if (!m.Parameters[i].Type.Equals(argType))
                            {
                                return(false);
                            }
                        }

                        return(true);
                    }) ?? group.Methods.Last();

                    isDynamic     = true;
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                    resolveResult = new InvocationResolveResult(resolveResult, method, dynamicResolveResult.Arguments);
                }
            }

            if (resolveResult is MethodGroupResolveResult)
            {
                var oldResult = (MethodGroupResolveResult)resolveResult;
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);

                if (resolveResult is DynamicInvocationResolveResult)
                {
                    var method = oldResult.Methods.Last();
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                }
            }

            MemberResolveResult member = resolveResult as MemberResolveResult;
            var globalTarget           = member != null?this.Emitter.IsGlobalTarget(member.Member) : null;

            if (member != null &&
                member.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.NonScriptableAttribute"))
            {
                throw new EmitterException(this.MemberReferenceExpression, "Member " + member.ToString() + " is marked as not usable from script");
            }

            if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod)
            {
                var interceptor = this.Emitter.Plugins.OnReference(this, this.MemberReferenceExpression, member);

                if (interceptor.Cancel)
                {
                    return;
                }

                if (!string.IsNullOrEmpty(interceptor.Replacement))
                {
                    this.Write(interceptor.Replacement);
                    return;
                }
            }

            if (globalTarget != null && globalTarget.Item1)
            {
                var target = globalTarget.Item2;

                if (!string.IsNullOrWhiteSpace(target))
                {
                    bool assign           = false;
                    var  memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent;
                    var  targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression;
                    var  assignment       = memberExpression as AssignmentExpression;
                    if (assignment != null && assignment.Right == targetExpression)
                    {
                        assign = true;
                    }
                    else
                    {
                        var varInit = memberExpression as VariableInitializer;
                        if (varInit != null && varInit.Initializer == targetExpression)
                        {
                            assign = true;
                        }
                        else if (memberExpression is InvocationExpression)
                        {
                            var targetInvocation = (InvocationExpression)memberExpression;
                            if (targetInvocation.Arguments.Any(a => a == targetExpression))
                            {
                                assign = true;
                            }
                        }
                    }

                    if (assign)
                    {
                        if (resolveResult is InvocationResolveResult)
                        {
                            this.PushWriter(target);
                        }
                        else
                        {
                            this.Write(target);
                        }

                        return;
                    }
                }

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter("");
                }

                return;
            }

            Tuple <bool, bool, string> inlineInfo = member != null ? (isDynamic ? ((Emitter)this.Emitter).GetInlineCodeFromMember(member.Member, null) : this.Emitter.GetInlineCode(memberReferenceExpression)) : null;
            //string inline = member != null ? this.Emitter.GetInline(member.Member) : null;
            string inline = inlineInfo != null ? inlineInfo.Item3 : null;

            if (string.IsNullOrEmpty(inline) && member != null &&
                member.Member is IMethod &&
                !(member is InvocationResolveResult) &&
                !(
                    memberReferenceExpression.Parent is InvocationExpression &&
                    memberReferenceExpression.NextSibling != null &&
                    memberReferenceExpression.NextSibling.Role is TokenRole &&
                    ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "("
                    )
                )
            {
                var method = (IMethod)member.Member;
                if (method.TypeArguments.Count > 0)
                {
                    inline = MemberReferenceBlock.GenerateInlineForMethodReference(method, this.Emitter);
                }
            }

            if (member != null && member.Member is IMethod && isInvoke)
            {
                var i_rr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter) as CSharpInvocationResolveResult;

                if (i_rr != null && !i_rr.IsExpandedForm)
                {
                    var tpl = this.Emitter.GetAttribute(member.Member.Attributes, JS.NS.BRIDGE + ".TemplateAttribute");

                    if (tpl != null && tpl.PositionalArguments.Count == 2)
                    {
                        inline = tpl.PositionalArguments[1].ConstantValue.ToString();
                    }
                }
            }

            bool hasInline         = !string.IsNullOrEmpty(inline);
            bool hasThis           = hasInline && inline.Contains("{this}");
            bool isInterfaceMember = false;

            if (hasInline && inline.StartsWith("<self>"))
            {
                hasThis = true;
                inline  = inline.Substring(6);
            }

            bool nativeImplementation = true;
            bool isInterface          = inline == null && member != null && member.Member.DeclaringTypeDefinition != null && member.Member.DeclaringTypeDefinition.Kind == TypeKind.Interface;
            var  hasTypeParemeter     = isInterface && Helpers.IsTypeParameterType(member.Member.DeclaringType);

            if (isInterface)
            {
                var ei = this.Emitter.Validator.IsExternalInterface(member.Member.DeclaringTypeDefinition);

                if (ei != null)
                {
                    nativeImplementation = ei.IsNativeImplementation;
                }
                else
                {
                    nativeImplementation = member.Member.DeclaringTypeDefinition.ParentAssembly.AssemblyName == CS.NS.ROOT ||
                                           !this.Emitter.Validator.IsExternalType(member.Member.DeclaringTypeDefinition);
                }

                if (ei != null && ei.IsSimpleImplementation)
                {
                    nativeImplementation = false;
                    isInterfaceMember    = false;
                }
                else if (ei != null || hasTypeParemeter)
                {
                    if (hasTypeParemeter || !nativeImplementation)
                    {
                        isInterfaceMember = true;
                    }
                }
            }

            string interfaceTempVar = null;

            if (hasThis)
            {
                this.Write("");
                var    oldBuilder = this.Emitter.Output;
                var    oldInline  = inline;
                string thisArg    = null;
                bool   isSimple   = true;

                if (this.MemberReferenceExpression.Target is BaseReferenceExpression)
                {
                    thisArg = "this";
                }
                else
                {
                    this.Emitter.Output          = new StringBuilder();
                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;
                    if (isConstTarget)
                    {
                        this.Write("(");
                    }
                    this.WriteSimpleTarget(resolveResult);
                    if (isConstTarget)
                    {
                        this.Write(")");
                    }

                    thisArg = this.Emitter.Output.ToString();

                    if (Regex.Matches(inline, @"\{(\*?)this\}").Count > 1)
                    {
                        var  mrr     = resolveResult as MemberResolveResult;
                        bool isField = mrr != null && mrr.Member is IField &&
                                       (mrr.TargetResult is ThisResolveResult ||
                                        mrr.TargetResult is LocalResolveResult || mrr.TargetResult is MemberResolveResult && ((MemberResolveResult)mrr.TargetResult).Member is IField);

                        isSimple = (mrr != null && (mrr.TargetResult is ThisResolveResult || mrr.TargetResult is ConstantResolveResult || mrr.TargetResult is LocalResolveResult)) || isField;
                    }
                }

                int thisIndex;

                if (!isSimple)
                {
                    StringBuilder sb = new StringBuilder();

                    sb.Append("(");
                    var tempVar = this.GetTempVarName();
                    inline    = inline.Replace("{this}", tempVar);
                    thisIndex = tempVar.Length + 2;

                    sb.Append(tempVar);
                    sb.Append(" = ");
                    sb.Append(thisArg);
                    sb.Append(", ");

                    sb.Append(inline);
                    sb.Append(")");

                    inline = sb.ToString();
                }
                else
                {
                    thisIndex = inline.IndexOf("{this}", StringComparison.Ordinal);
                    inline    = inline.Replace("{this}", thisArg);
                }

                if (member != null && member.Member is IProperty)
                {
                    this.Emitter.Output = new StringBuilder();
                    inline = inline.Replace("{0}", "[[0]]");
                    new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                    inline = this.Emitter.Output.ToString();
                    inline = inline.Replace("[[0]]", "{0}");
                }

                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.Emitter.Output          = oldBuilder;

                int[] range = null;

                if (thisIndex > -1)
                {
                    range = new[] { thisIndex, thisIndex + thisArg.Length };
                }

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline, null, thisArg, range);
                }
                else
                {
                    if (member != null && member.Member is IMethod)
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), oldInline, (IMethod)member.Member, targetrr).EmitFunctionReference();
                    }
                    else if (member != null && member.Member is IField && inline.Contains("{0}"))
                    {
                        this.PushWriter(inline, null, thisArg, range);
                    }
                    else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inline))
                    {
                        this.PushWriter(inline, null, thisArg, range);
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }

                return;
            }

            if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member))
            {
                var  parentExpression = memberReferenceExpression.Parent as MemberReferenceExpression;
                bool wrap             = false;

                if (parentExpression != null)
                {
                    var ii = this.Emitter.GetInlineCode(parentExpression);

                    if (string.IsNullOrEmpty(ii.Item3))
                    {
                        wrap = true;
                        this.WriteOpenParentheses();
                    }
                }

                this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter));

                if (wrap)
                {
                    this.WriteCloseParentheses();
                }
            }
            else if (hasInline && member.Member.IsStatic)
            {
                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    if (member != null && member.Member is IMethod)
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference();
                    }
                    else
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit();
                    }
                }
            }
            else
            {
                if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum)
                {
                    var typeDef = member.Member.DeclaringType as ITypeDefinition;

                    if (typeDef != null)
                    {
                        var enumMode = this.Emitter.Validator.EnumEmitMode(typeDef);

                        if ((this.Emitter.Validator.IsExternalType(typeDef) && enumMode == -1) || enumMode == 2)
                        {
                            this.WriteScript(member.ConstantValue);

                            return;
                        }

                        if (enumMode >= 3 && enumMode < 7)
                        {
                            string enumStringName = member.Member.Name;
                            var    attr           = Helpers.GetInheritedAttribute(member.Member, Translator.Bridge_ASSEMBLY + ".NameAttribute");

                            if (attr != null)
                            {
                                enumStringName = this.Emitter.GetEntityName(member.Member);
                            }
                            else
                            {
                                switch (enumMode)
                                {
                                case 3:
                                    enumStringName = Object.Net.Utilities.StringUtils.ToLowerCamelCase(member.Member.Name);
                                    break;

                                case 4:
                                    enumStringName = member.Member.Name;
                                    break;

                                case 5:
                                    enumStringName = enumStringName.ToLowerInvariant();
                                    break;

                                case 6:
                                    enumStringName = enumStringName.ToUpperInvariant();
                                    break;
                                }
                            }

                            this.WriteScript(enumStringName);

                            return;
                        }
                    }
                }

                if (resolveResult is TypeResolveResult)
                {
                    TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult;
                    this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter));
                    return;
                }
                else if (member != null &&
                         member.Member is IMethod &&
                         !(member is InvocationResolveResult) &&
                         !(
                             memberReferenceExpression.Parent is InvocationExpression &&
                             memberReferenceExpression.NextSibling != null &&
                             memberReferenceExpression.NextSibling.Role is TokenRole &&
                             ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "("
                             )
                         )
                {
                    if (!string.IsNullOrEmpty(inline))
                    {
                        if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod)
                        {
                            new InlineArgumentsBlock(this.Emitter,
                                                     new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline,
                                                     (IMethod)member.Member, targetrr).EmitFunctionReference();
                        }
                        else if (resolveResult is InvocationResolveResult ||
                                 (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment))
                        {
                            this.PushWriter(inline);
                        }
                        else
                        {
                            this.Write(inline);
                        }
                    }
                    else
                    {
                        var  resolvedMethod = (IMethod)member.Member;
                        bool isStatic       = resolvedMethod != null && resolvedMethod.IsStatic;

                        var isExtensionMethod = resolvedMethod.IsExtensionMethod;

                        this.Emitter.IsAssignment    = false;
                        this.Emitter.IsUnaryAccessor = false;

                        if (!isStatic)
                        {
                            this.Write(isExtensionMethod ? JS.Funcs.BRIDGE_BIND_SCOPE : JS.Funcs.BRIDGE_CACHE_BIND);
                            this.WriteOpenParentheses();

                            if (memberReferenceExpression.Target is BaseReferenceExpression)
                            {
                                this.WriteThis();
                            }
                            else
                            {
                                interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, false);
                            }

                            this.Write(", ");
                        }

                        this.Emitter.IsAssignment    = oldIsAssignment;
                        this.Emitter.IsUnaryAccessor = oldUnary;

                        if (isExtensionMethod)
                        {
                            this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter));
                        }
                        else
                        {
                            this.Emitter.IsAssignment    = false;
                            this.Emitter.IsUnaryAccessor = false;
                            if (isConstTarget)
                            {
                                this.Write("(");
                            }

                            if (interfaceTempVar != null)
                            {
                                this.Write(interfaceTempVar);
                            }
                            else
                            {
                                this.WriteSimpleTarget(resolveResult);
                            }

                            if (isConstTarget)
                            {
                                this.Write(")");
                            }
                            this.Emitter.IsAssignment    = oldIsAssignment;
                            this.Emitter.IsUnaryAccessor = oldUnary;
                        }

                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar, member, false);
                        }
                        else
                        {
                            this.WriteDot();
                            this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation));
                        }

                        if (!isStatic)
                        {
                            this.Write(")");
                        }
                    }

                    return;
                }
                else
                {
                    bool isProperty = false;

                    if (member != null && member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition)))
                    {
                        isProperty = true;
                        bool writeTargetVar = false;

                        if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                        {
                            writeTargetVar = true;
                        }
                        else if (this.Emitter.IsUnaryAccessor)
                        {
                            writeTargetVar = true;

                            isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement;

                            if (NullableType.IsNullable(member.Type))
                            {
                                isStatement = false;
                            }

                            if (!isStatement)
                            {
                                this.WriteOpenParentheses();
                            }
                        }

                        if (writeTargetVar)
                        {
                            bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult);

                            if (!(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField))
                            {
                                targetVar = this.GetTempVarName();

                                this.Write(targetVar);
                                this.Write(" = ");
                            }
                        }
                    }

                    if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
                    {
                        valueVar = this.GetTempVarName();

                        this.Write(valueVar);
                        this.Write(" = ");
                    }

                    this.Emitter.IsAssignment    = false;
                    this.Emitter.IsUnaryAccessor = false;
                    if (isConstTarget)
                    {
                        this.Write("(");
                    }

                    if (targetVar == null && isInterfaceMember)
                    {
                        interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, true);
                    }
                    else
                    {
                        this.WriteSimpleTarget(resolveResult);
                    }

                    if (member != null && targetrr != null && targetrr.Type.Kind == TypeKind.Delegate && (member.Member.Name == "Invoke"))
                    {
                        var method = member.Member as IMethod;
                        if (!(method != null && method.IsExtensionMethod))
                        {
                            return;
                        }
                    }

                    if (isConstTarget)
                    {
                        this.Write(")");
                    }
                    this.Emitter.IsAssignment    = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (targetVar != null)
                    {
                        if (this.Emitter.IsUnaryAccessor && !isStatement)
                        {
                            this.WriteComma(false);

                            valueVar = this.GetTempVarName();

                            this.Write(valueVar);
                            this.Write(" = ");

                            this.Write(targetVar);
                        }
                        else
                        {
                            this.WriteSemiColon();
                            this.WriteNewLine();
                            this.Write(targetVar);
                        }
                    }
                }

                var targetResolveResult = targetrr as MemberResolveResult;

                if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null)
                {
                    if (isRefArg)
                    {
                        this.WriteComma();
                    }
                    else if (!isInterfaceMember && !this.NoTarget)
                    {
                        this.WriteDot();
                    }
                }

                if (member == null)
                {
                    if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic)
                    {
                        this.Write(memberReferenceExpression.MemberName);
                    }
                    else
                    {
                        this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase());
                    }
                }
                else if (!string.IsNullOrEmpty(inline))
                {
                    if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod)
                    {
                        new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference();
                    }
                    else if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment))
                    {
                        this.PushWriter(inline);
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || (!this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition) || member.Member.IsStatic)))
                {
                    if (member.Member is IProperty && targetrr != null && targetrr.Type.GetDefinition() != null && this.Emitter.Validator.IsObjectLiteral(targetrr.Type.GetDefinition()) && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                    {
                        this.Write(this.Emitter.GetEntityName(member.Member));
                    }
                    else
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                        }
                        else
                        {
                            var name     = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation);
                            var property = (IProperty)member.Member;
                            var proto    = member.IsVirtualCall || property.IsVirtual || property.IsOverride;

                            if (this.MemberReferenceExpression.Target is BaseReferenceExpression && !property.IsIndexer && proto)
                            {
                                var alias = BridgeTypes.ToJsName(member.Member.DeclaringType, this.Emitter,
                                                                 isAlias: true);
                                if (alias.StartsWith("\""))
                                {
                                    alias = alias.Insert(1, "$");
                                    name  = alias + "+\"$" + name + "\"";
                                    this.WriteIdentifier(name, false);
                                }
                                else
                                {
                                    name = "$" + alias + "$" + name;
                                    this.WriteIdentifier(name);
                                }
                            }
                            else
                            {
                                this.WriteIdentifier(name);
                            }
                        }
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Field)
                {
                    bool isConst = this.Emitter.IsMemberConst(member.Member);

                    if (isConst && this.Emitter.IsInlineConst(member.Member))
                    {
                        this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter));
                    }
                    else
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                        }
                        else
                        {
                            var fieldName = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation);

                            if (isRefArg)
                            {
                                this.WriteScript(fieldName);
                            }
                            else
                            {
                                this.WriteIdentifier(fieldName);
                            }
                        }
                    }
                }
                else if (resolveResult is InvocationResolveResult)
                {
                    InvocationResolveResult       invocationResult  = (InvocationResolveResult)resolveResult;
                    CSharpInvocationResolveResult cInvocationResult = (CSharpInvocationResolveResult)resolveResult;
                    var expresssionMember = expressionResolveResult as MemberResolveResult;

                    if (isInterfaceMember)
                    {
                        this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                    }
                    else if (expresssionMember != null &&
                             cInvocationResult != null &&
                             cInvocationResult.IsDelegateInvocation &&
                             invocationResult.Member != expresssionMember.Member)
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName(!nativeImplementation));
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName(!nativeImplementation));
                    }
                }
                else if (member.Member is IEvent)
                {
                    if (this.Emitter.IsAssignment &&
                        (this.Emitter.AssignmentType == AssignmentOperatorType.Add ||
                         this.Emitter.AssignmentType == AssignmentOperatorType.Subtract))
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract, Helpers.GetAddOrRemove(this.Emitter.AssignmentType == AssignmentOperatorType.Add));
                        }
                        else
                        {
                            this.Write(Helpers.GetEventRef(member.Member, this.Emitter, this.Emitter.AssignmentType != AssignmentOperatorType.Add, ignoreInterface: !nativeImplementation));
                        }

                        this.WriteOpenParentheses();
                    }
                    else
                    {
                        if (isInterfaceMember)
                        {
                            this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                        }
                        else
                        {
                            this.Write(this.Emitter.GetEntityName(member.Member, true, ignoreInterface: !nativeImplementation));
                        }
                    }
                }
                else
                {
                    if (isInterfaceMember)
                    {
                        this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false);
                    }
                    else
                    {
                        this.Write(this.Emitter.GetEntityName(member.Member, ignoreInterface: !nativeImplementation));
                    }
                }

                Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this, pos);
            }
        }
Exemplo n.º 14
0
        public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
        {
            if (resolver.Language == SupportedLanguage.CSharp && resolver.CallingClass != null)
            {
                if (invocationExpression.TargetObject is ThisReferenceExpression)
                {
                    // call to constructor
                    return(ResolveConstructorOverload(resolver.CallingClass, invocationExpression.Arguments));
                }
                else if (invocationExpression.TargetObject is BaseReferenceExpression)
                {
                    return(ResolveConstructorOverload(resolver.CallingClass.BaseType, invocationExpression.Arguments));
                }
            }

            ResolveResult      rr      = Resolve(invocationExpression.TargetObject);
            MixedResolveResult mixedRR = rr as MixedResolveResult;

            if (mixedRR != null)
            {
                rr = mixedRR.PrimaryResult;
            }
            MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;

            if (mgrr != null)
            {
                if (resolver.Language == SupportedLanguage.VBNet)
                {
                    if (mgrr.Methods.All(mg => mg.Count == 0))
                    {
                        return(CreateMemberResolveResult(GetVisualBasicIndexer(invocationExpression)));
                    }
//					IMethod empty = mgrr.GetMethodWithEmptyParameterList();
//					if (empty != null)
//						return CreateMemberResolveResult(empty);
                }

                IReturnType[] argumentTypes = invocationExpression.Arguments.Select <Expression, IReturnType>(ResolveType).ToArray();

                MemberResolveResult firstResult = null;
                foreach (MethodGroup methodGroup in mgrr.Methods)
                {
                    bool    resultIsAcceptable;
                    IMethod method;
                    if (methodGroup.IsExtensionMethodGroup)
                    {
                        IReturnType[] extendedTypes = new IReturnType[argumentTypes.Length + 1];
                        extendedTypes[0] = mgrr.ContainingType;
                        argumentTypes.CopyTo(extendedTypes, 1);
                        method = MemberLookupHelper.FindOverload(methodGroup, extendedTypes, out resultIsAcceptable);
                    }
                    else
                    {
                        method = MemberLookupHelper.FindOverload(methodGroup, argumentTypes, out resultIsAcceptable);
                    }
                    MemberResolveResult result = CreateMemberResolveResult(method);
                    if (result != null && methodGroup.IsExtensionMethodGroup)
                    {
                        result.IsExtensionMethodCall = true;
                    }
                    if (resultIsAcceptable)
                    {
                        return(result);
                    }
                    if (firstResult == null)
                    {
                        firstResult = result;
                    }
                }
                if (firstResult != null)
                {
                    return(firstResult);
                }
                else
                {
                    return(FallbackResolveMethod(invocationExpression, mgrr, argumentTypes));
                }
            }
            else if (rr != null && rr.ResolvedType != null)
            {
                IClass c = rr.ResolvedType.GetUnderlyingClass();
                if (c != null && c.ClassType == ClassType.Delegate)
                {
                    // We don't want to show "System.EventHandler.Invoke" in the tooltip
                    // of "EventCall(this, EventArgs.Empty)", we just show the event/delegate for now
                    // but for DelegateCall(params).* completion, we use the delegate's
                    // return type instead of the delegate type itself

                    IMethod method = rr.ResolvedType.GetMethods().FirstOrDefault(innerMethod => innerMethod.Name == "Invoke");
                    if (method != null)
                    {
                        return(new DelegateCallResolveResult(rr, method));
                    }
                }
            }
            if (resolver.Language == SupportedLanguage.VBNet)
            {
                return(CreateMemberResolveResult(GetVisualBasicIndexer(invocationExpression)));
            }

            return(resolver.CreateUnknownMethodResolveResult(invocationExpression));
        }
Exemplo n.º 15
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();
                }

                bool close = false;
                if (isProperty)
                {
                    var member_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult;

                    if (member_rr != null)
                    {
                        var    setterName = Helpers.GetPropertyRef(member_rr.Member, this.Emitter, true);
                        var    getterName = Helpers.GetPropertyRef(member_rr.Member, this.Emitter, false);
                        string names      = null;

                        if (setterName != ("set" + mname) && getterName != ("get" + mname))
                        {
                            names = string.Format("{{ getter:'{0}', setter: '{1}'", getterName, setterName);
                        }
                        else if (setterName != ("set" + mname))
                        {
                            names = string.Format("{{ setter: '{0}'", setterName);
                        }
                        else if (getterName != ("get" + mname))
                        {
                            names = string.Format("{{ getter: '{0}'", getterName);
                        }

                        if (names != null)
                        {
                            this.Write(names);
                            this.Write(", value: ");
                            close = true;
                        }
                    }
                }

                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 (close)
                {
                    this.Write(" }");
                }

                if (this.IsObjectLiteral)
                {
                    this.WriteSemiColon(true);
                }

                this.Emitter.Comma = true;
            }

            if (count > 0 && objectName != null)
            {
                this.WriteNewLine();
                this.EndBlock();
            }

            return(count > 0);
        }
		Value Visit(MemberResolveResult result)
		{
			var importedMember = Import(result.Member);
			if (importedMember == null)
				throw new GetValueException("Member not found!");
			Value target = null;
			if (!importedMember.IsStatic) {
				if (importedMember.DeclaringType.Equals(context.MethodInfo.DeclaringType) && result.TargetResult == null)
					target = context.GetThisValue(true);
				else if (result.TargetResult == null)
					throw new GetValueException("An object reference is required for the non-static field, method, or property '" + importedMember.FullName + "'");
				else
					target = Convert(result.TargetResult);
			}
			if (!allowMethodInvoke && (importedMember is IMethod))
				throw new InvalidOperationException("Method invocation not allowed in the current context!");
			Value val = Value.GetMemberValue(evalThread, target, importedMember);
			if (val == null)
				throw new GetValueException("Member not found!");
			return val;
		}
Exemplo n.º 17
0
            public override object TrackedVisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
            {
                if (this.FoundResourceSet == null &&                                                                                                        // skip if already found to improve performance
                    assignmentExpression.Op == AssignmentOperatorType.Assign && this.PositionAvailable &&
                    (!this.isLocalVariable || this.resourceManagerMember.Region.IsInside(this.CurrentNodeStartLocation.Y, this.CurrentNodeStartLocation.X)) // skip if local variable is out of scope
                    )
                {
                    IMember       resolvedMember = null;
                    ResolveResult rr             = this.Resolve(assignmentExpression.Left);
                    if (rr != null)
                    {
                        // Support both local variables and member variables
                        MemberResolveResult mrr = rr as MemberResolveResult;
                        if (mrr != null)
                        {
                            resolvedMember = mrr.ResolvedMember;
                        }
                        else
                        {
                            LocalResolveResult lrr = rr as LocalResolveResult;
                            if (lrr != null)
                            {
                                resolvedMember = lrr.Field;
                            }
                        }
                    }

                    if (resolvedMember != null)
                    {
                                                #if DEBUG
                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: Resolved member: " + resolvedMember.ToString());
                                                #endif

                        // HACK: The GetType()s are necessary because the DOM IComparable implementations try to cast the parameter object to their own interface type which may fail.
                        if (resolvedMember.GetType().Equals(this.resourceManagerMember.GetType()) && resolvedMember.CompareTo(this.resourceManagerMember) == 0)
                        {
                                                        #if DEBUG
                            LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found assignment to field: " + assignmentExpression.ToString());
                                                        #endif
                            data = true;

                            // Resolving the property association only makes sense if
                            // there is a possible relationship between the return types
                            // of the resolved member and the member we are looking for.
                        }
                        else if (this.compilationUnit != null && !this.isLocalVariable &&
                                 IsTypeRelationshipPossible(resolvedMember, this.resourceManagerMember))
                        {
                            if (this.resourceManagerMember is IProperty && resolvedMember is IField)
                            {
                                // Find out if the resourceManagerMember is a property whose get block returns the value of the resolved member.

                                // We might already have found this association in the
                                // resourceManagerFieldAccessedByProperty field.
                                this.TryResolveResourceManagerProperty();

                                if (this.resourceManagerFieldAccessedByProperty != null && this.resourceManagerFieldAccessedByProperty.CompareTo(resolvedMember) == 0)
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found assignment to field: " + assignmentExpression.ToString());
                                                                        #endif
                                    data = true;
                                }
                            }
                            else if (this.resourceManagerMember is IField && resolvedMember is IProperty)
                            {
                                // Find out if the resolved member is a property whose set block assigns the value to the resourceManagerMember.

                                PropertyFieldAssociationVisitor visitor = new PropertyFieldAssociationVisitor((IField)this.resourceManagerMember, this.FileName, this.FileContent);
                                this.compilationUnit.AcceptVisitor(visitor, null);
                                if (visitor.AssociatedProperty != null && visitor.AssociatedProperty.CompareTo(resolvedMember) == 0)
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found assignment to property: " + assignmentExpression.ToString());
                                                                        #endif
                                    data = true;
                                }
                            }
                        }
                    }
                }
                return(base.TrackedVisitAssignmentExpression(assignmentExpression, data));
            }
		public IEnumerable<IInsightItem> MemberInsight(MemberResolveResult result)
		{
			switch (result.Type.FullName) {
				case "System.Windows.Thickness":
					yield return new MemberInsightItem(result.Member, "uniformLength");
					yield return new MemberInsightItem(result.Member, "left, top");
					yield return new MemberInsightItem(result.Member, "left, top, right, bottom");
					break;
				case "System.Windows.Size":
					yield return new MemberInsightItem(result.Member, "width, height");
					break;
				case "System.Windows.Point":
					yield return new MemberInsightItem(result.Member, "x, y");
					break;
				case "System.Windows.Rect":
					yield return new MemberInsightItem(result.Member, "x, y, width, height");
					break;
			}
		}
Exemplo n.º 19
0
        /// <summary>
        /// Tries to find a resource reference in the specified expression.
        /// </summary>
        /// <param name="expressionResult">The ExpressionResult for the expression.</param>
        /// <param name="expr">The AST representation of the full expression.</param>
        /// <param name="resolveResult">SharpDevelop's ResolveResult for the expression.</param>
        /// <param name="caretLine">The 0-based line where the expression is located.</param>
        /// <param name="caretColumn">The 0-based column where the expression is located.</param>
        /// <param name="fileName">The name of the source file where the expression is located.</param>
        /// <param name="fileContent">The content of the source file where the expression is located.</param>
        /// <param name="expressionFinder">The ExpressionFinder for the file.</param>
        /// <param name="charTyped">The character that has been typed at the caret position but is not yet in the buffer (this is used when invoked from code completion), or <c>null</c>.</param>
        /// <returns>A ResourceResolveResult describing the referenced resource, or <c>null</c>, if this expression does not reference a resource using the standard .NET framework classes.</returns>
        public ResourceResolveResult Resolve(ExpressionResult expressionResult, Expression expr, ResolveResult resolveResult, int caretLine, int caretColumn, string fileName, string fileContent, IExpressionFinder expressionFinder, char?charTyped)
        {
            /*
             * We need to catch the following cases here:
             *
             * Something.GetString(
             * Something.GetString("...")
             * Something.ApplyResources(obj, "...")
             * Something[
             * Something["..."]
             *
             */

            if (charTyped == '(')
            {
                // Something.GetString
                // This is a MethodResolveResult and we need the reference to "Something",
                // which is the next outer expression.
                // This is only valid when invoked from code completion
                // and the method invocation character ('(' in C# and VB)
                // has been typed.

                // This code is also reused when reducing a complete InvocationExpression
                // (MemberResolveResult) to the method reference by passing '(' as
                // charTyped explicitly.

                MethodGroupResolveResult methrr = resolveResult as MethodGroupResolveResult;
                if (methrr != null)
                {
                    if ((methrr.Name == "GetString" || methrr.Name == "GetObject" || methrr.Name == "GetStream" || methrr.Name == "ApplyResources") &&
                        (resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null)
                    {
                        return(ResolveResource(resolveResult, expr));
                    }
                    else
                    {
                        return(null);
                    }
                }
            }

            // Do not use "else if" here.
            // '(' is also the IndexerExpressionStartToken for VB,
            // so the "else" block further down might still apply.

            if (charTyped == null)
            {
                // A MemberResolveResult with a complete expression
                // must only be considered a valid resource reference
                // when Resolve is not invoked from code completion
                // (i.e. charTyped == null) because this indicates
                // that the resource reference is already before the typed character
                // and we are not interested in the following expression.
                // This may happen when typing something like:
                // Something.GetString("...")[

                MemberResolveResult mrr = resolveResult as MemberResolveResult;
                if (mrr != null)
                {
                    if (mrr.ResolvedMember is IMethod &&
                        (mrr.ResolvedMember.Name == "GetString" || mrr.ResolvedMember.Name == "GetObject" || mrr.ResolvedMember.Name == "GetStream" || mrr.ResolvedMember.Name == "ApplyResources"))
                    {
                        // Something.GetString("...")
                        // This is a MemberResolveResult and we need the reference to "Something".
                        // The expression finder may only remove the string literal, so
                        // we have to call Resolve again in this case to resolve
                        // the method reference.

                        if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null)
                        {
                            if (resolveResult is MethodGroupResolveResult)
                            {
                                return(this.Resolve(expressionResult, expr, resolveResult, caretLine, caretColumn, fileName, fileContent, expressionFinder, '('));
                            }
                            else
                            {
                                return(ResolveResource(resolveResult, expr));
                            }
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else if (expr is IndexerExpression &&
                             IsResourceManager(mrr.ResolvedMember.DeclaringType.DefaultReturnType, fileName))
                    {
                        // Something["..."] is an IndexerExpression.
                        // We need the reference to Something and this is
                        // the next outer expression.

                        if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, fileContent, expressionFinder)) != null)
                        {
                            return(ResolveResource(resolveResult, expr));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
            }
            else
            {
                // This request is triggered from code completion.
                // The only case that has not been caught above is:
                // Something[
                // The reference to "Something" is already in this expression.
                // So we have to test the trigger character against the
                // indexer expression start token of the file's language.

                LanguageProperties lp = NRefactoryResourceResolver.GetLanguagePropertiesForFile(fileName);
                if (lp != null &&
                    !String.IsNullOrEmpty(lp.IndexerExpressionStartToken) &&
                    lp.IndexerExpressionStartToken[0] == charTyped)
                {
                                        #if DEBUG
                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: Indexer expression start typed, ResolveResult: " + resolveResult.ToString());
                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: -> Expression: " + expr.ToString());
                                        #endif

                    return(ResolveResource(resolveResult, expr));
                }
            }

            return(null);
        }
Exemplo n.º 20
0
        public MonoDevelop.Projects.Dom.ResolveResult GetLanguageItem(ProjectDom dom, Mono.TextEditor.TextEditorData data, int offset)
        {
            if (offset < 0)
            {
                return(null);
            }
            string  fileName = data.Document.FileName;
            IParser parser   = ProjectDomService.GetParser(fileName);

            if (parser == null)
            {
                return(null);
            }

            MonoDevelop.Ide.Gui.Document doc = IdeApp.Workbench.ActiveDocument;
            if (doc == null)
            {
                return(null);
            }

            IResolver resolver = parser.CreateResolver(dom, doc, fileName);

            if (resolver == null)
            {
                return(null);
            }
            var expressionFinder = new NewCSharpExpressionFinder(dom);

            int wordEnd = Math.Min(offset, data.Length - 1);

            if (wordEnd < 0)
            {
                return(null);
            }
            if (data.GetCharAt(wordEnd) == '@')
            {
                wordEnd++;
            }
            while (wordEnd < data.Length && (Char.IsLetterOrDigit(data.GetCharAt(wordEnd)) || data.GetCharAt(wordEnd) == '_'))
            {
                wordEnd++;
            }

            while (wordEnd < data.Length - 1 && Char.IsWhiteSpace(data.GetCharAt(wordEnd)))
            {
                wordEnd++;
            }

            /* is checked at the end.
             * int saveEnd = wordEnd;
             * if (wordEnd < data.Length && data.GetCharAt (wordEnd) == '<') {
             *      int matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd);
             *      if (matchingBracket > 0)
             *              wordEnd = matchingBracket;
             *      while (wordEnd < data.Length - 1 && Char.IsWhiteSpace (data.GetCharAt (wordEnd)))
             *              wordEnd++;
             * }
             *
             * bool wasMethodCall = false;
             * if (data.GetCharAt (wordEnd) == '(') {
             *      int matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd);
             *      if (matchingBracket > 0) {
             *              wordEnd = matchingBracket;
             *              wasMethodCall = true;
             *      }
             * }
             * if (!wasMethodCall)
             *      wordEnd = saveEnd;*/

            ExpressionResult expressionResult = expressionFinder.FindExpression(data, wordEnd);

            if (expressionResult == null)
            {
                return(null);
            }
            ResolveResult    resolveResult;
            DocumentLocation loc             = data.Document.OffsetToLocation(offset);
            string           savedExpression = null;

            // special handling for 'var' "keyword"
            if (expressionResult.ExpressionContext == ExpressionContext.IdentifierExpected && expressionResult.Expression != null && expressionResult.Expression.Trim() == "var")
            {
                int           endOffset = data.Document.LocationToOffset(expressionResult.Region.End.Line, expressionResult.Region.End.Column);
                StringBuilder identifer = new StringBuilder();
                for (int i = endOffset; i >= 0 && i < data.Document.Length; i++)
                {
                    char ch = data.Document.GetCharAt(i);
                    if (Char.IsWhiteSpace(ch))
                    {
                        if (identifer.Length > 0)
                        {
                            break;
                        }
                        continue;
                    }
                    if (ch == '=' || ch == ';')
                    {
                        break;
                    }
                    if (Char.IsLetterOrDigit(ch) || ch == '_')
                    {
                        identifer.Append(ch);
                        continue;
                    }
                    identifer.Length = 0;
                    break;
                }
                if (identifer.Length > 0)
                {
                    expressionResult.Expression = identifer.ToString();
                    resolveResult = resolver.Resolve(expressionResult, new DomLocation(loc.Line, int.MaxValue));
                    if (resolveResult != null)
                    {
                        resolveResult = new MemberResolveResult(dom.GetType(resolveResult.ResolvedType));
                        resolveResult.ResolvedExpression = expressionResult;
                        return(resolveResult);
                    }
                }
            }

            if (expressionResult.ExpressionContext == ExpressionContext.Attribute && !string.IsNullOrEmpty(expressionResult.Expression))
            {
                savedExpression                    = expressionResult.Expression;
                expressionResult.Expression        = expressionResult.Expression.Trim() + "Attribute";
                expressionResult.ExpressionContext = ExpressionContext.ObjectCreation;
            }

            resolveResult = resolver.Resolve(expressionResult, new DomLocation(loc.Line, loc.Column));
            if (savedExpression != null && resolveResult == null)
            {
                expressionResult.Expression = savedExpression;
                resolveResult = resolver.Resolve(expressionResult, new DomLocation(loc.Line, loc.Column));
            }

            // identifier may not be valid at that point, try to resolve it at line end (ex. foreach loop variable)
            if (resolveResult != null && (resolveResult.ResolvedType == null || string.IsNullOrEmpty(resolveResult.ResolvedType.FullName)))
            {
                resolveResult = resolver.Resolve(expressionResult, new DomLocation(loc.Line, int.MaxValue));
            }

            // Search for possible generic parameters.
//			if (this.resolveResult == null || this.resolveResult.ResolvedType == null || String.IsNullOrEmpty (this.resolveResult.ResolvedType.Name)) {
            if (!expressionResult.Region.IsEmpty)
            {
                int j       = data.Document.LocationToOffset(expressionResult.Region.End.Line, expressionResult.Region.End.Column);
                int bracket = 0;
                for (int i = j; i >= 0 && i < data.Document.Length; i++)
                {
                    char ch = data.Document.GetCharAt(i);
                    if (Char.IsWhiteSpace(ch))
                    {
                        continue;
                    }
                    if (ch == '<')
                    {
                        bracket++;
                    }
                    else if (ch == '>')
                    {
                        bracket--;
                        if (bracket == 0)
                        {
                            expressionResult.Expression       += data.Document.GetTextBetween(j, i + 1);
                            expressionResult.ExpressionContext = ExpressionContext.ObjectCreation;
                            resolveResult = resolver.Resolve(expressionResult, new DomLocation(loc.Line, loc.Column));
                            break;
                        }
                    }
                    else
                    {
                        if (bracket == 0)
                        {
                            break;
                        }
                    }
                }
            }

            // To resolve method overloads the full expression must be parsed.
            // ex.: Overload (1)/ Overload("one") - parsing "Overload" gives just a MethodResolveResult
            // and for constructor initializers it's tried too to to resolve constructor overloads.
            if (resolveResult is ThisResolveResult ||
                resolveResult is BaseResolveResult ||
                resolveResult is MethodResolveResult && ((MethodResolveResult)resolveResult).Methods.Count > 1)
            {
                // put the search offset at the end of the invocation to be able to find the full expression
                // the resolver finds it itself if spaces are between the method name and the argument opening parentheses.
                while (wordEnd < data.Length - 1 && Char.IsWhiteSpace(data.GetCharAt(wordEnd)))
                {
                    wordEnd++;
                }
                if (data.GetCharAt(wordEnd) == '(')
                {
                    int matchingBracket = data.Document.GetMatchingBracketOffset(wordEnd);
                    if (matchingBracket > 0)
                    {
                        wordEnd = matchingBracket;
                    }
                }
                //Console.WriteLine (expressionFinder.FindFullExpression (txt, wordEnd));
                ResolveResult possibleResult = resolver.Resolve(expressionFinder.FindFullExpression(data, wordEnd), new DomLocation(loc.Line, loc.Column)) ?? resolveResult;
                //Console.WriteLine ("possi:" + resolver.Resolve (expressionFinder.FindFullExpression (txt, wordEnd), new DomLocation (loc.Line, loc.Column)));
                if (possibleResult is MethodResolveResult)
                {
                    resolveResult = possibleResult;
                }
            }
            return(resolveResult);
        }
Exemplo n.º 21
0
            public override object TrackedVisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
            {
                if (data as bool? ?? false)
                {
                                        #if DEBUG
                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found object initialization: " + objectCreateExpression.ToString());
                                        #endif

                    // Resolve the constructor.
                    // A type derived from the declaration type is also allowed.
                    MemberResolveResult mrr = this.Resolve(objectCreateExpression) as MemberResolveResult;

                                        #if DEBUG
                    if (mrr != null)
                    {
                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: resolved constructor: " + mrr.ResolvedMember.ToString());
                    }
                                        #endif

                    if (mrr != null &&
                        mrr.ResolvedMember is IMethod &&
                        (mrr.ResolvedMember.DeclaringType.CompareTo(this.resourceManagerMember.ReturnType.GetUnderlyingClass()) == 0 ||
                         mrr.ResolvedMember.DeclaringType.IsTypeInInheritanceTree(this.resourceManagerMember.ReturnType.GetUnderlyingClass()))
                        )
                    {
                                                #if DEBUG
                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: This is the correct constructor.");
                                                #endif

                        // This most probably is the resource manager initialization we are looking for.
                        // Find a parameter that indicates the resources being referenced.

                        foreach (Expression param in objectCreateExpression.Parameters)
                        {
                            PrimitiveExpression p = param as PrimitiveExpression;
                            if (p != null)
                            {
                                string pValue = p.Value as string;
                                if (!String.IsNullOrEmpty(pValue))
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found string parameter: '" + pValue + "'");
                                                                        #endif

                                    this.foundResourceSet = NRefactoryResourceResolver.GetResourceSetReference(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, pValue);
                                                                        #if DEBUG
                                    if (this.foundResourceSet.FileName != null)
                                    {
                                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: " + this.foundResourceSet.FileName);
                                    }
                                                                        #endif

                                    break;
                                }

                                continue;
                            }

                            // Support typeof(...)
                            TypeOfExpression t = param as TypeOfExpression;
                            if (t != null && this.PositionAvailable)
                            {
                                                                #if DEBUG
                                LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: Found TypeOfExpression in constructor call: " + t.ToString());
                                                                #endif

                                ResolveResult rr = this.Resolve(new TypeReferenceExpression(t.TypeReference), ExpressionContext.Type);

                                                                #if DEBUG
                                if (rr == null)
                                {
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: The TypeReference of the TypeOfExpression could not be resolved.");
                                }
                                else
                                {
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver: The TypeReference resolved to: " + rr.ToString());
                                }
                                                                #endif

                                if (rr != null)
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found typeof(...) parameter, type: '" + rr.ResolvedType.ToString() + "'");
                                                                        #endif

                                    this.foundResourceSet = NRefactoryResourceResolver.GetResourceSetReference(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, rr.ResolvedType.FullyQualifiedName);
                                                                        #if DEBUG
                                    if (this.foundResourceSet.FileName != null)
                                    {
                                        LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: " + this.foundResourceSet.FileName);
                                    }
                                                                        #endif

                                    break;
                                }
                            }
                        }
                    }
                }

                return(base.TrackedVisitObjectCreateExpression(objectCreateExpression, data));
            }
Exemplo n.º 22
0
        protected void WriteTarget(MemberResolveResult memberResult)
        {
            if (memberResult.Member.IsStatic)
            {
                switch (memberResult.Member.SymbolKind)
                {
                case SymbolKind.Method: {
                    if (memberResult.Member.DeclaringType != TransformCtx.CurClass)
                    {
                        this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter));
                        this.WriteDot();
                    }
                    break;
                }

                case SymbolKind.Property: {
                    if (Helpers.IsFieldProperty(memberResult.Member, this.Emitter))
                    {
                        this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter));
                        this.WriteDot();
                    }
                    else
                    {
                        if (memberResult.Member.DeclaringType != TransformCtx.CurClass)
                        {
                            this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter));
                            this.WriteDot();
                        }
                    }
                    break;
                }

                default: {
                    this.Write(BridgeTypes.ToJsName(memberResult.Member.DeclaringType, this.Emitter));
                    this.WriteDot();
                    break;
                }
                }
            }
            else
            {
                switch (memberResult.Member.SymbolKind)
                {
                case SymbolKind.Method: {
                    if (!memberResult.Member.IsInternalMember())
                    {
                        this.WriteThis();
                        if (this.IdentifierExpression.Role == Roles.TargetExpression)
                        {
                            this.WriteObjectColon();
                        }
                        else
                        {
                            this.WriteDot();
                        }
                    }
                    break;
                }

                case SymbolKind.Property: {
                    if (Helpers.IsFieldProperty(memberResult.Member, this.Emitter))
                    {
                        this.WriteThis();
                        this.WriteDot();
                    }
                    else
                    {
                        if (!memberResult.Member.IsInternalMember())
                        {
                            this.WriteThis();
                            this.WriteObjectColon();
                        }
                    }
                    break;
                }

                default: {
                    this.WriteThis();
                    this.WriteDot();
                    break;
                }
                }
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// This method can be used in three modes (like RunFindReferences)
        /// </summary>
        static void AddReferences(List <Reference> list,
                                  IClass parentClass, IMember member,
                                  bool isLocal,
                                  string fileName, string fileContent)
        {
            string lowerFileContent = fileContent.ToLowerInvariant();
            string searchedText;             // the text that is searched for
            bool   searchingIndexer = false;

            if (member == null)
            {
                searchedText = parentClass.Name.ToLowerInvariant();
            }
            else
            {
                // When looking for a member, the name of the parent class does not always exist
                // in the file where the member is accessed.
                // (examples: derived classes, partial classes)
                if (member is IMethod && ((IMethod)member).IsConstructor)
                {
                    searchedText = parentClass.Name.ToLowerInvariant();
                }
                else
                {
                    if (member is IProperty && ((IProperty)member).IsIndexer)
                    {
                        searchingIndexer = true;
                        searchedText     = GetIndexerExpressionStartToken(fileName);
                    }
                    else
                    {
                        searchedText = member.Name.ToLowerInvariant();
                    }
                }
            }

            // It is possible that a class or member does not have a name (when parsing incomplete class definitions)
            // - in that case, we cannot find references.
            if (searchedText.Length == 0)
            {
                return;
            }

            int pos = -1;
            int exprPos;
            IExpressionFinder expressionFinder = null;

            while ((pos = lowerFileContent.IndexOf(searchedText, pos + 1)) >= 0)
            {
                if (!searchingIndexer)
                {
                    if (pos > 0 && char.IsLetterOrDigit(fileContent, pos - 1))
                    {
                        continue;                         // memberName is not a whole word (a.SomeName cannot reference Name)
                    }
                    if (pos < fileContent.Length - searchedText.Length - 1 &&
                        char.IsLetterOrDigit(fileContent, pos + searchedText.Length))
                    {
                        continue;                         // memberName is not a whole word (a.Name2 cannot reference Name)
                    }
                    exprPos = pos;
                }
                else
                {
                    exprPos = pos - 1;                          // indexer expressions are found by resolving the part before the indexer
                }

                if (expressionFinder == null)
                {
                    expressionFinder = ParserService.GetExpressionFinder(fileName);
                }
                ExpressionResult expr = expressionFinder.FindFullExpression(fileContent, exprPos);
                if (expr.Expression != null)
                {
                    Point position = GetPosition(fileContent, exprPos);
repeatResolve:
                    // TODO: Optimize by re-using the same resolver if multiple expressions were
                    // found in this file (the resolver should parse all methods at once)
                    ResolveResult rr = ParserService.Resolve(expr, position.Y, position.X, fileName, fileContent);
                    MemberResolveResult mrr = rr as MemberResolveResult;
                    if (isLocal)
                    {
                        // find reference to local variable
                        if (IsReferenceToLocalVariable(rr, member))
                        {
                            list.Add(new Reference(fileName, pos, searchedText.Length, expr.Expression, rr));
                        }
                        else if (FixIndexerExpression(expressionFinder, ref expr, mrr))
                        {
                            goto repeatResolve;
                        }
                    }
                    else if (member != null)
                    {
                        // find reference to member
                        if (IsReferenceToMember(member, rr))
                        {
                            list.Add(new Reference(fileName, pos, searchedText.Length, expr.Expression, rr));
                        }
                        else if (FixIndexerExpression(expressionFinder, ref expr, mrr))
                        {
                            goto repeatResolve;
                        }
                    }
                    else
                    {
                        // find reference to class
                        if (mrr != null)
                        {
                            if (mrr.ResolvedMember is IMethod && ((IMethod)mrr.ResolvedMember).IsConstructor)
                            {
                                if (mrr.ResolvedMember.DeclaringType.FullyQualifiedName == parentClass.FullyQualifiedName)
                                {
                                    list.Add(new Reference(fileName, pos, searchedText.Length, expr.Expression, rr));
                                }
                            }
                        }
                        else
                        {
                            if (rr is TypeResolveResult && rr.ResolvedType.FullyQualifiedName == parentClass.FullyQualifiedName)
                            {
                                list.Add(new Reference(fileName, pos, searchedText.Length, expr.Expression, rr));
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 24
0
 public virtual object VisitMemberResolveResult(MemberResolveResult rr, object data)
 {
     VisitChildResolveResults(rr, data);
     return(null);
 }
Exemplo n.º 25
0
 /// <summary>
 /// Makes the given ExpressionResult point to the underlying expression if
 /// the expression is an indexer expression.
 /// </summary>
 /// <returns><c>true</c>, if the expression was an indexer expression and has been changed, <c>false</c> otherwise.</returns>
 public static bool FixIndexerExpression(IExpressionFinder expressionFinder, ref ExpressionResult expr, MemberResolveResult mrr)
 {
     if (mrr != null && mrr.ResolvedMember is IProperty && ((IProperty)mrr.ResolvedMember).IsIndexer)
     {
         // we got an indexer call as expression ("objectList[0].ToString()[2]")
         // strip the index from the expression to resolve the underlying expression
         string newExpr = expressionFinder.RemoveLastPart(expr.Expression);
         if (newExpr.Length >= expr.Expression.Length)
         {
             throw new ApplicationException("new expression must be shorter than old expression");
         }
         expr.Expression = newExpr;
         return(true);
     }
     return(false);
 }
Exemplo n.º 26
0
 public virtual TResult VisitMemberResolveResult(MemberResolveResult rr, TData data)
 {
     VisitChildResolveResults(rr, data);
     return(default(TResult));
 }
Exemplo n.º 27
0
 static void DoStaticMethodGlobalOperation(AstNode fnode, RefactoringContext fctx, MemberResolveResult rr,
                                           Script fscript)
 {
     if (fnode is MemberReferenceExpression)
     {
         var memberReference = new MemberReferenceExpression(
             new TypeReferenceExpression(fctx.CreateShortType(rr.Member.DeclaringType)),
             rr.Member.Name
             );
         fscript.Replace(fnode, memberReference);
     }
     else
     {
         var invoke = fnode as InvocationExpression;
         if (invoke == null)
         {
             return;
         }
         if ((invoke.Target is MemberReferenceExpression))
         {
             return;
         }
         var memberReference = new MemberReferenceExpression(
             new TypeReferenceExpression(fctx.CreateShortType(rr.Member.DeclaringType)),
             rr.Member.Name
             );
         fscript.Replace(invoke.Target, memberReference);
     }
 }
Exemplo n.º 28
0
        public ResolveResult ResolveNode(AstNode node, ILog log)
        {
            var syntaxTree = node.GetParent <SyntaxTree>();

            this.InitResolver(syntaxTree);

            var result = this.resolver.Resolve(node);

            if (result is MethodGroupResolveResult && node.Parent != null)
            {
                var methodGroupResolveResult = (MethodGroupResolveResult)result;
                var parentResolveResult      = this.ResolveNode(node.Parent, log);
                var parentInvocation         = parentResolveResult as InvocationResolveResult;
                IParameterizedMember method  = methodGroupResolveResult.Methods.LastOrDefault();
                bool isInvocation            = node.Parent is InvocationExpression && (((InvocationExpression)(node.Parent)).Target == node);

                if (node is Expression)
                {
                    var conversion = this.Resolver.GetConversion((Expression)node);
                    if (conversion != null && conversion.IsMethodGroupConversion)
                    {
                        return(new MemberResolveResult(new TypeResolveResult(conversion.Method.DeclaringType), conversion.Method));
                    }
                }

                if (isInvocation && parentInvocation != null)
                {
                    var or = methodGroupResolveResult.PerformOverloadResolution(this.compilation, parentInvocation.GetArgumentsForCall().ToArray());
                    if (or.FoundApplicableCandidate)
                    {
                        method = or.BestCandidate;
                        return(new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method));
                    }
                }

                if (parentInvocation != null && method == null)
                {
                    var typeDef = methodGroupResolveResult.TargetType as DefaultResolvedTypeDefinition;

                    if (typeDef != null)
                    {
                        var methods = typeDef.Methods.Where(m => m.Name == methodGroupResolveResult.MethodName);
                        method = methods.FirstOrDefault();
                    }
                }

                if (method == null)
                {
                    var extMethods = methodGroupResolveResult.GetEligibleExtensionMethods(false);

                    if (extMethods.Count() == 0)
                    {
                        extMethods = methodGroupResolveResult.GetExtensionMethods();
                    }

                    if (extMethods.Count() == 0 || extMethods.First().Count() == 0)
                    {
                        throw new Exception("Cannot find method defintion for " + node.ToString());
                    }

                    method = extMethods.First().First();
                }

                if (parentInvocation == null || method.FullName != parentInvocation.Member.FullName)
                {
                    MemberResolveResult memberResolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                    return(memberResolveResult);
                }

                return(parentResolveResult);
            }

            if ((result == null || result.IsError) && log != null)
            {
                if (result is CSharpInvocationResolveResult && ((CSharpInvocationResolveResult)result).OverloadResolutionErrors != OverloadResolutionErrors.None)
                {
                    return(result);
                }

                log.LogWarning(string.Format("Node resolving has failed {0}: {1}", node.StartLocation, node.ToString()));
            }

            return(result);
        }
Exemplo n.º 29
0
        protected virtual IEnumerable <string> GetDefineMethods(InitPosition value, Func <MethodDeclaration, IMethod, string> fn)
        {
            var methods  = TypeInfo.InstanceMethods;
            var attrName = "H5.InitAttribute";

            foreach (var methodGroup in methods)
            {
                foreach (var method in methodGroup.Value)
                {
                    foreach (var attrSection in method.Attributes)
                    {
                        foreach (var attr in attrSection.Attributes)
                        {
                            var rr = Emitter.Resolver.ResolveNode(attr.Type);
                            if (rr.Type.FullName == attrName)
                            {
                                throw new EmitterException(attr, "Instance method cannot be Init method");
                            }
                        }
                    }
                }
            }

            methods = TypeInfo.StaticMethods;
            List <string> list = new List <string>();

            foreach (var methodGroup in methods)
            {
                foreach (var method in methodGroup.Value)
                {
                    MemberResolveResult rrMember = null;
                    IMethod             rrMethod = null;
                    foreach (var attrSection in method.Attributes)
                    {
                        foreach (var attr in attrSection.Attributes)
                        {
                            var rr = Emitter.Resolver.ResolveNode(attr.Type);
                            if (rr.Type.FullName == attrName)
                            {
                                InitPosition?initPosition = null;
                                if (attr.HasArgumentList)
                                {
                                    if (attr.Arguments.Count > 0)
                                    {
                                        var argExpr = attr.Arguments.First();
                                        var argrr   = Emitter.Resolver.ResolveNode(argExpr);
                                        if (argrr.ConstantValue is int)
                                        {
                                            initPosition = (InitPosition)argrr.ConstantValue;
                                        }
                                    }
                                    else
                                    {
                                        initPosition = InitPosition.After;
                                    }
                                }
                                else
                                {
                                    initPosition = InitPosition.After;
                                }

                                if (initPosition == value)
                                {
                                    if (rrMember == null)
                                    {
                                        rrMember = Emitter.Resolver.ResolveNode(method) as MemberResolveResult;
                                        rrMethod = rrMember != null ? rrMember.Member as IMethod : null;
                                    }

                                    if (rrMethod != null)
                                    {
                                        if (rrMethod.TypeParameters.Count > 0)
                                        {
                                            throw new EmitterException(method, "Init method cannot be generic");
                                        }

                                        if (rrMethod.Parameters.Count > 0)
                                        {
                                            throw new EmitterException(method, "Init method should not have parameters");
                                        }

                                        if (rrMethod.ReturnType.Kind != TypeKind.Void &&
                                            !rrMethod.ReturnType.IsKnownType(KnownTypeCode.Void))
                                        {
                                            throw new EmitterException(method, "Init method should not return anything");
                                        }

                                        list.Add(fn(method, rrMethod));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(list);
        }
Exemplo n.º 30
0
        protected void VisitInvocationExpression()
        {
            InvocationExpression invocationExpression = this.InvocationExpression;
            int pos = this.Emitter.Output.Length;

            if (this.Emitter.IsForbiddenInvocation(invocationExpression))
            {
                throw new EmitterException(invocationExpression, "This method cannot be invoked directly");
            }

            var oldValue = this.Emitter.ReplaceAwaiterByVar;
            var oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling;

            if (this.Emitter.IsAsync && !this.Emitter.AsyncExpressionHandling)
            {
                this.WriteAwaiters(invocationExpression);
                this.Emitter.ReplaceAwaiterByVar     = true;
                this.Emitter.AsyncExpressionHandling = true;
            }

            Tuple <bool, bool, string> inlineInfo = this.Emitter.GetInlineCode(invocationExpression);
            var argsInfo = new ArgumentsInfo(this.Emitter, invocationExpression);

            var argsExpressions = argsInfo.ArgumentsExpressions;
            var paramsArg       = argsInfo.ParamsExpression;
            var argsCount       = argsExpressions.Count();

            if (inlineInfo != null)
            {
                bool   isStaticMethod = inlineInfo.Item1;
                bool   isInlineMethod = inlineInfo.Item2;
                string inlineScript   = inlineInfo.Item3;

                if (isInlineMethod)
                {
                    if (invocationExpression.Arguments.Count > 0)
                    {
                        var code             = invocationExpression.Arguments.First();
                        var inlineExpression = code as PrimitiveExpression;

                        if (inlineExpression == null)
                        {
                            throw new EmitterException(invocationExpression, "Only primitive expression can be inlined");
                        }

                        string value = inlineExpression.Value.ToString().Trim();

                        if (value.Length > 0)
                        {
                            value = InlineArgumentsBlock.ReplaceInlineArgs(this, inlineExpression.Value.ToString(), invocationExpression.Arguments.Skip(1).ToArray());
                            this.Write(value);

                            if (value[value.Length - 1] == ';')
                            {
                                this.Emitter.EnableSemicolon = false;
                                this.WriteNewLine();
                            }
                        }
                        else
                        {
                            // Empty string, emit nothing.
                            this.Emitter.EnableSemicolon = false;
                        }

                        this.Emitter.ReplaceAwaiterByVar     = oldValue;
                        this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                        return;
                    }
                }
                else
                {
                    MemberReferenceExpression targetMemberRef = invocationExpression.Target as MemberReferenceExpression;
                    bool isBase = targetMemberRef != null && targetMemberRef.Target is BaseReferenceExpression;

                    if (!String.IsNullOrEmpty(inlineScript) && (isBase || invocationExpression.Target is IdentifierExpression))
                    {
                        argsInfo.ThisArgument = "this";
                        bool noThis = !inlineScript.Contains("{this}");

                        if (!isStaticMethod && noThis)
                        {
                            this.WriteThis();
                            this.WriteDot();
                        }

                        new InlineArgumentsBlock(this.Emitter, argsInfo, inlineScript).Emit();
                        this.Emitter.ReplaceAwaiterByVar     = oldValue;
                        this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                        return;
                    }
                }
            }

            MemberReferenceExpression targetMember = invocationExpression.Target as MemberReferenceExpression;

            ResolveResult targetMemberResolveResult = null;

            if (targetMember != null)
            {
                targetMemberResolveResult = this.Emitter.Resolver.ResolveNode(targetMember.Target, this.Emitter);
            }

            if (targetMember != null)
            {
                var member = this.Emitter.Resolver.ResolveNode(targetMember.Target, this.Emitter);

                //var targetResolve = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter);
                var targetResolve = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter);

                if (targetResolve != null)
                {
                    var csharpInvocation = targetResolve as CSharpInvocationResolveResult;

                    InvocationResolveResult invocationResult;
                    bool isExtensionMethodInvocation = false;
                    if (csharpInvocation != null)
                    {
                        if (member != null && member.Type.Kind == TypeKind.Delegate && !csharpInvocation.IsExtensionMethodInvocation)
                        {
                            throw new EmitterException(invocationExpression, "Delegate's methods are not supported. Please use direct delegate invoke.");
                        }

                        if (csharpInvocation.IsExtensionMethodInvocation)
                        {
                            invocationResult            = csharpInvocation;
                            isExtensionMethodInvocation = true;
                            var resolvedMethod = invocationResult.Member as IMethod;
                            if (resolvedMethod != null && resolvedMethod.IsExtensionMethod)
                            {
                                string inline   = this.Emitter.GetInline(resolvedMethod);
                                bool   isNative = this.IsNativeMethod(resolvedMethod);

                                if (string.IsNullOrWhiteSpace(inline) && isNative)
                                {
                                    invocationResult = null;
                                }
                            }
                        }
                        else
                        {
                            invocationResult = null;
                        }

                        if (this.IsEmptyPartialInvoking(csharpInvocation.Member as IMethod))
                        {
                            this.Emitter.SkipSemiColon           = true;
                            this.Emitter.ReplaceAwaiterByVar     = oldValue;
                            this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                            return;
                        }
                    }
                    else
                    {
                        invocationResult = targetResolve as InvocationResolveResult;

                        if (invocationResult != null && this.IsEmptyPartialInvoking(invocationResult.Member as IMethod))
                        {
                            this.Emitter.SkipSemiColon           = true;
                            this.Emitter.ReplaceAwaiterByVar     = oldValue;
                            this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                            return;
                        }
                    }

                    if (invocationResult == null)
                    {
                        invocationResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as InvocationResolveResult;
                    }

                    if (invocationResult != null)
                    {
                        var resolvedMethod = invocationResult.Member as IMethod;

                        if (resolvedMethod != null && resolvedMethod.IsExtensionMethod)
                        {
                            string inline   = this.Emitter.GetInline(resolvedMethod);
                            bool   isNative = this.IsNativeMethod(resolvedMethod);

                            if (isExtensionMethodInvocation)
                            {
                                if (!string.IsNullOrWhiteSpace(inline))
                                {
                                    this.Write("");
                                    StringBuilder savedBuilder = this.Emitter.Output;
                                    this.Emitter.Output = new StringBuilder();
                                    this.WriteThisExtension(invocationExpression.Target);
                                    argsInfo.ThisArgument = this.Emitter.Output.ToString();
                                    this.Emitter.Output   = savedBuilder;
                                    new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit();
                                }
                                else if (!isNative)
                                {
                                    var    overloads     = OverloadsCollection.Create(this.Emitter, resolvedMethod);
                                    string name          = BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter) + "." + overloads.GetOverloadName();
                                    var    isIgnoreClass = resolvedMethod.DeclaringTypeDefinition != null && this.Emitter.Validator.IsIgnoreType(resolvedMethod.DeclaringTypeDefinition);

                                    this.Write(name);

                                    if (!isIgnoreClass && argsInfo.HasTypeArguments)
                                    {
                                        this.WriteOpenParentheses();
                                        new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit();
                                        this.WriteCloseParentheses();
                                    }

                                    this.WriteOpenParentheses();

                                    this.WriteThisExtension(invocationExpression.Target);

                                    if (invocationExpression.Arguments.Count > 0)
                                    {
                                        this.WriteComma();
                                    }

                                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression).Emit();

                                    this.WriteCloseParentheses();
                                }

                                if (!string.IsNullOrWhiteSpace(inline) || !isNative)
                                {
                                    this.Emitter.ReplaceAwaiterByVar     = oldValue;
                                    this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                                    return;
                                }
                            }
                            else if (isNative)
                            {
                                if (!string.IsNullOrWhiteSpace(inline))
                                {
                                    this.Write("");
                                    StringBuilder savedBuilder = this.Emitter.Output;
                                    this.Emitter.Output = new StringBuilder();
                                    this.WriteThisExtension(invocationExpression.Target);
                                    argsInfo.ThisArgument = this.Emitter.Output.ToString();
                                    this.Emitter.Output   = savedBuilder;
                                    new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit();
                                }
                                else
                                {
                                    argsExpressions.First().AcceptVisitor(this.Emitter);
                                    this.WriteDot();
                                    string name = this.Emitter.GetEntityName(resolvedMethod);
                                    this.Write(name);
                                    this.WriteOpenParentheses();
                                    new ExpressionListBlock(this.Emitter, argsExpressions.Skip(1), paramsArg, invocationExpression).Emit();
                                    this.WriteCloseParentheses();
                                }

                                this.Emitter.ReplaceAwaiterByVar     = oldValue;
                                this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

                                return;
                            }
                        }
                    }
                }
            }

            var proto = false;

            if (targetMember != null && targetMember.Target is BaseReferenceExpression)
            {
                var rr = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter) as MemberResolveResult;

                if (rr != null)
                {
                    proto = rr.IsVirtualCall;

                    /*var method = rr.Member as IMethod;
                     * if (method != null && method.IsVirtual)
                     * {
                     *  proto = true;
                     * }
                     * else
                     * {
                     *  var prop = rr.Member as IProperty;
                     *
                     *  if (prop != null && prop.IsVirtual)
                     *  {
                     *      proto = true;
                     *  }
                     * }*/
                }
            }

            if (proto)
            {
                var baseType = this.Emitter.GetBaseMethodOwnerTypeDefinition(targetMember.MemberName, targetMember.TypeArguments.Count);
                var method   = invocationExpression.GetParent <MethodDeclaration>();

                bool isIgnore = this.Emitter.Validator.IsIgnoreType(baseType);

                if (isIgnore)
                {
                    //throw (System.Exception)this.Emitter.CreateException(targetMember.Target, "Cannot call base method, because parent class code is ignored");
                }

                bool needComma = false;

                var resolveResult = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter);

                string name = null;

                if (this.Emitter.TypeInfo.GetBaseTypes(this.Emitter).Any())
                {
                    name = BridgeTypes.ToJsName(this.Emitter.TypeInfo.GetBaseClass(this.Emitter), this.Emitter);
                }
                else
                {
                    name = BridgeTypes.ToJsName(baseType, this.Emitter);
                }

                string baseMethod;

                if (resolveResult is InvocationResolveResult)
                {
                    InvocationResolveResult invocationResult = (InvocationResolveResult)resolveResult;
                    baseMethod = OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName();
                }
                else if (resolveResult is MemberResolveResult)
                {
                    MemberResolveResult memberResult = (MemberResolveResult)resolveResult;
                    baseMethod = OverloadsCollection.Create(this.Emitter, memberResult.Member).GetOverloadName();
                }
                else
                {
                    baseMethod = targetMember.MemberName;
                    baseMethod = this.Emitter.AssemblyInfo.PreserveMemberCase ? baseMethod : Object.Net.Utilities.StringUtils.ToLowerCamelCase(baseMethod);
                }

                this.Write(name, ".prototype.", baseMethod);

                if (!isIgnore && argsInfo.HasTypeArguments)
                {
                    this.WriteOpenParentheses();
                    new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit();
                    this.WriteCloseParentheses();
                }

                this.WriteDot();

                this.Write("call");
                this.WriteOpenParentheses();

                this.WriteThis();
                needComma = true;

                foreach (var arg in argsExpressions)
                {
                    if (needComma)
                    {
                        this.WriteComma();
                    }

                    needComma = true;
                    arg.AcceptVisitor(this.Emitter);
                }

                this.WriteCloseParentheses();
            }
            else
            {
                var dynamicResolveResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as DynamicInvocationResolveResult;

                if (dynamicResolveResult != null)
                {
                    var group = dynamicResolveResult.Target as MethodGroupResolveResult;

                    if (group != null && group.Methods.Count() > 1)
                    {
                        throw new EmitterException(invocationExpression, "Cannot compile this dynamic invocation because there are two or more method overloads with the same parameter count. To work around this limitation, assign the dynamic value to a non-dynamic variable before use or call a method with different parameter count");
                    }
                }

                var     targetResolveResult     = this.Emitter.Resolver.ResolveNode(invocationExpression.Target, this.Emitter);
                var     invocationResolveResult = targetResolveResult as MemberResolveResult;
                IMethod method = null;

                if (invocationResolveResult != null)
                {
                    method = invocationResolveResult.Member as IMethod;
                }

                if (this.IsEmptyPartialInvoking(method))
                {
                    this.Emitter.SkipSemiColon           = true;
                    this.Emitter.ReplaceAwaiterByVar     = oldValue;
                    this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
                    return;
                }

                int count = this.Emitter.Writers.Count;
                invocationExpression.Target.AcceptVisitor(this.Emitter);

                if (this.Emitter.Writers.Count > count)
                {
                    var tuple = this.Emitter.Writers.Pop();

                    if (method != null && method.IsExtensionMethod)
                    {
                        StringBuilder savedBuilder = this.Emitter.Output;
                        this.Emitter.Output = new StringBuilder();
                        this.WriteThisExtension(invocationExpression.Target);
                        argsInfo.ThisArgument = this.Emitter.Output.ToString();
                        this.Emitter.Output   = savedBuilder;
                    }

                    new InlineArgumentsBlock(this.Emitter, argsInfo, tuple.Item1).Emit();
                    var result = this.Emitter.Output.ToString();
                    this.Emitter.Output    = tuple.Item2;
                    this.Emitter.IsNewLine = tuple.Item3;
                    this.Write(result);
                }
                else
                {
                    var isIgnore = false;

                    if (method != null && method.DeclaringTypeDefinition != null && this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                    {
                        isIgnore = true;
                    }

                    if (!isIgnore && argsInfo.HasTypeArguments)
                    {
                        this.WriteOpenParentheses();
                        new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit();
                        this.WriteCloseParentheses();
                    }

                    this.WriteOpenParentheses();
                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression).Emit();
                    this.WriteCloseParentheses();
                }
            }

            Helpers.CheckValueTypeClone(this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter), invocationExpression, this, pos);

            this.Emitter.ReplaceAwaiterByVar     = oldValue;
            this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;
        }
Exemplo n.º 31
0
        void GotoMember(IMember member)
        {
            MemberResolveResult resolveResult = new MemberResolveResult(null, null, member);

            GotoFilePosition(resolveResult.GetDefinitionPosition());
        }
Exemplo n.º 32
0
        protected void VisitMemberReferenceExpression()
        {
            MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression;

            ResolveResult resolveResult = null;
            ResolveResult expressionResolveResult = null;
            string targetVar = null;
            string valueVar = null;
            bool isStatement = false;

            var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter);

            if (memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression))
            {
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);
                expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);

                if (expressionResolveResult is InvocationResolveResult)
                {
                    resolveResult = expressionResolveResult;
                }
            }
            else
            {
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter);
            }

            bool oldIsAssignment = this.Emitter.IsAssignment;
            bool oldUnary = this.Emitter.IsUnaryAccessor;

            if (resolveResult == null)
            {
                this.Emitter.IsAssignment = false;
                this.Emitter.IsUnaryAccessor = false;
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                this.Emitter.IsAssignment = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                this.WriteDot();
                string name = memberReferenceExpression.MemberName;
                this.Write(name.ToLowerCamelCase());

                return;
            }

            if (resolveResult is DynamicInvocationResolveResult)
            {
                resolveResult = ((DynamicInvocationResolveResult)resolveResult).Target;
            }

            if (resolveResult is MethodGroupResolveResult)
            {
                var oldResult = (MethodGroupResolveResult)resolveResult;
                resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter);

                if (resolveResult is DynamicInvocationResolveResult)
                {
                    var method = oldResult.Methods.Last();
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                }
            }

            MemberResolveResult member = resolveResult as MemberResolveResult;
            var globalTarget = member != null ? this.Emitter.IsGlobalTarget(member.Member) : null;

            if (globalTarget != null && globalTarget.Item1)
            {
                var target = globalTarget.Item2;

                if (!string.IsNullOrWhiteSpace(target))
                {
                    bool assign = false;
                    var memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent;
                    var targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression;
                    var assignment = memberExpression as AssignmentExpression;
                    if (assignment != null && assignment.Right == targetExpression)
                    {
                        assign = true;
                    }
                    else
                    {
                        var varInit = memberExpression as VariableInitializer;
                        if (varInit != null && varInit.Initializer == targetExpression)
                        {
                            assign = true;
                        }
                        else if (memberExpression is InvocationExpression)
                        {
                            var targetInvocation = (InvocationExpression)memberExpression;
                            if (targetInvocation.Arguments.Any(a => a == targetExpression))
                            {
                                assign = true;
                            }
                        }
                    }

                    if(assign)
                    {
                        if (resolveResult is InvocationResolveResult)
                        {
                            this.PushWriter(target);
                        }
                        else
                        {
                            this.Write(target);
                        }

                        return;
                    }
                }

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter("");
                }

                return;
            }

            string inline = member != null ? this.Emitter.GetInline(member.Member) : null;
            bool hasInline = !string.IsNullOrEmpty(inline);
            bool hasThis = hasInline && inline.Contains("{this}");

            if (hasThis)
            {
                this.Write("");
                var oldBuilder = this.Emitter.Output;
                this.Emitter.Output = new StringBuilder();
                this.Emitter.IsAssignment = false;
                this.Emitter.IsUnaryAccessor = false;
                memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                this.Emitter.IsAssignment = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
                inline = inline.Replace("{this}", this.Emitter.Output.ToString());
                this.Emitter.Output = oldBuilder;

                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    this.Write(inline);
                }

                return;
            }

            if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member))
            {
                this.WriteScript(member.ConstantValue);
            }
            else if (hasInline && member.Member.IsStatic)
            {
                if (resolveResult is InvocationResolveResult)
                {
                    this.PushWriter(inline);
                }
                else
                {
                    this.Write(inline);
                }
            }
            else
            {
                if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum)
                {
                    var typeDef = member.Member.DeclaringType as DefaultResolvedTypeDefinition;

                    if (typeDef != null)
                    {
                        var enumMode = this.Emitter.Validator.EnumEmitMode(typeDef);

                        if ((this.Emitter.Validator.IsIgnoreType(typeDef) && enumMode == -1) || enumMode == 2)
                        {
                            this.WriteScript(member.ConstantValue);

                            return;
                        }

                        if (enumMode >= 3)
                        {
                            string enumStringName = member.Member.Name;
                            var attr = this.Emitter.GetAttribute(member.Member.Attributes, Translator.Bridge_ASSEMBLY + ".NameAttribute");

                            if (attr != null)
                            {
                                enumStringName = this.Emitter.GetEntityName(member.Member);
                            }
                            else
                            {
                                switch (enumMode)
                                {
                                    case 3:
                                        enumStringName = Object.Net.Utilities.StringUtils.ToLowerCamelCase(member.Member.Name);
                                        break;
                                    case 4:
                                        break;
                                    case 5:
                                        enumStringName = enumStringName.ToLowerInvariant();
                                        break;
                                    case 6:
                                        enumStringName = enumStringName.ToUpperInvariant();
                                        break;
                                }
                            }

                            this.WriteScript(enumStringName);

                            return;
                        }
                    }
                }

                if (resolveResult is TypeResolveResult)
                {
                    TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult;

                    this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter));

                    return;
                }
                else if (member != null &&
                         member.Member is IMethod &&
                         !(member is InvocationResolveResult) &&
                         !(
                            memberReferenceExpression.Parent is InvocationExpression &&
                            memberReferenceExpression.NextSibling != null &&
                            memberReferenceExpression.NextSibling.Role is TokenRole &&
                            ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "("
                         )
                    )
                {
                    var resolvedMethod = (IMethod)member.Member;
                    bool isStatic = resolvedMethod != null && resolvedMethod.IsStatic;

                    var isExtensionMethod = resolvedMethod.IsExtensionMethod;

                    this.Emitter.IsAssignment = false;
                    this.Emitter.IsUnaryAccessor = false;

                    if (!isStatic)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + "." + (isExtensionMethod ? Bridge.Translator.Emitter.DELEGATE_BIND_SCOPE : Bridge.Translator.Emitter.DELEGATE_BIND) + "(");
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        this.Write(", ");
                    }

                    this.Emitter.IsAssignment = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (isExtensionMethod)
                    {
                        this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter));
                    }
                    else
                    {
                        this.Emitter.IsAssignment = false;
                        this.Emitter.IsUnaryAccessor = false;
                        memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                        this.Emitter.IsAssignment = oldIsAssignment;
                        this.Emitter.IsUnaryAccessor = oldUnary;
                    }

                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());

                    if (!isStatic)
                    {
                        this.Write(")");
                    }

                    return;
                }
                else
                {
                    bool isProperty = false;

                    if (member != null && member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                    {
                        isProperty = true;
                        bool writeTargetVar = false;

                        if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                        {
                            writeTargetVar = true;
                        }
                        else if (this.Emitter.IsUnaryAccessor)
                        {
                            writeTargetVar = true;

                            isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement;

                            if (NullableType.IsNullable(member.Type))
                            {
                                isStatement = false;
                            }

                            if (!isStatement)
                            {
                                this.WriteOpenParentheses();
                            }
                        }

                        if (writeTargetVar)
                        {
                            var memberTargetrr = targetrr as MemberResolveResult;
                            bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult);

                            if (!(targetrr is ThisResolveResult || targetrr is LocalResolveResult || isField))
                            {
                                targetVar = this.GetTempVarName();

                                this.Write(targetVar);
                                this.Write(" = ");
                            }
                        }
                    }

                    if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
                    {
                        valueVar = this.GetTempVarName();

                        this.Write(valueVar);
                        this.Write(" = ");
                    }

                    this.Emitter.IsAssignment = false;
                    this.Emitter.IsUnaryAccessor = false;
                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                    this.Emitter.IsAssignment = oldIsAssignment;
                    this.Emitter.IsUnaryAccessor = oldUnary;

                    if (targetVar != null)
                    {
                        if (this.Emitter.IsUnaryAccessor && !isStatement)
                        {
                            this.WriteComma(false);

                            valueVar = this.GetTempVarName();

                            this.Write(valueVar);
                            this.Write(" = ");

                            this.Write(targetVar);
                        }
                        else
                        {
                            this.WriteSemiColon();
                            this.WriteNewLine();
                            this.Write(targetVar);
                        }
                    }
                }

                var targetResolveResult = targetrr as MemberResolveResult;

                if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null)
                {
                    this.WriteDot();
                }

                if (member == null)
                {
                    if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic)
                    {
                        this.Write(memberReferenceExpression.MemberName);
                    }
                    else
                    {
                        this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase());
                    }
                }
                else if (!string.IsNullOrEmpty(inline))
                {
                    if (resolveResult is InvocationResolveResult)
                    {
                        this.PushWriter(inline);
                    }
                    else
                    {
                        this.Write(inline);
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Property && member.TargetResult.Type.Kind != TypeKind.Anonymous && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))
                {
                    var proto = false;
                    if (this.MemberReferenceExpression.Target is BaseReferenceExpression && member != null)
                    {
                        var prop = member.Member as IProperty;

                        if (prop != null && prop.IsVirtual)
                        {
                            proto = true;
                        }
                    }

                    if (Helpers.IsFieldProperty(member.Member, this.Emitter))
                    {
                        this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                    }
                    else if (!this.Emitter.IsAssignment)
                    {
                        if(this.Emitter.IsUnaryAccessor)
                        {
                            if (isStatement)
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();

                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));

                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }

                                if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    this.Write("+");
                                }
                                else
                                {
                                    this.Write("-");
                                }

                                this.Write("1");
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, false));
                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteCloseParentheses();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                    this.WriteCloseParentheses();
                                }
                                this.WriteComma();

                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();
                                this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter, true));

                                if (proto)
                                {
                                    this.Write(".call");
                                    this.WriteOpenParentheses();
                                    this.WriteThis();
                                    this.WriteComma();
                                }
                                else
                                {
                                    this.WriteOpenParentheses();
                                }

                                this.WriteOpenParentheses();
                                this.Write(valueVar);

                                if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    this.Write("+");
                                }
                                else
                                {
                                    this.Write("-");
                                }

                                this.Write("1");
                                this.WriteCloseParentheses();
                                this.WriteComma();

                                this.Write(valueVar);

                                if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.Decrement)
                                {
                                    if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment)
                                    {
                                        this.Write("+");
                                    }
                                    else
                                    {
                                        this.Write("-");
                                    }

                                    this.Write("1");
                                }

                                this.WriteCloseParentheses();

                                if (valueVar != null)
                                {
                                    this.RemoveTempVar(valueVar);
                                }
                            }

                            if (targetVar != null)
                            {
                                this.RemoveTempVar(targetVar);
                            }
                        }
                        else
                        {
                            this.Write(Helpers.GetPropertyRef(member.Member, this.Emitter));
                            if (proto)
                            {
                                this.Write(".call");
                                this.WriteOpenParentheses();
                                this.WriteThis();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                this.WriteOpenParentheses();
                                this.WriteCloseParentheses();
                            }
                        }
                    }
                    else if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                    {
                        if(targetVar != null)
                        {
                            this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                                proto ? ".call(this, " : "(",
                                targetVar,
                                ".",
                                Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                                proto ? ".call(this)" : "()",
                                "{0})"), () => { this.RemoveTempVar(targetVar); });
                        }
                        else
                        {
                            var oldWriter = this.SaveWriter();
                            this.NewWriter();

                            this.Emitter.IsAssignment = false;
                            this.Emitter.IsUnaryAccessor = false;
                            memberReferenceExpression.Target.AcceptVisitor(this.Emitter);
                            this.Emitter.IsAssignment = oldIsAssignment;
                            this.Emitter.IsUnaryAccessor = oldUnary;
                            var trg = this.Emitter.Output.ToString();

                            this.RestoreWriter(oldWriter);
                            this.PushWriter(string.Concat(Helpers.GetPropertyRef(member.Member, this.Emitter, true),
                                proto ? ".call(this, " : "(",
                                trg,
                                ".",
                                Helpers.GetPropertyRef(member.Member, this.Emitter, false),
                                proto ? ".call(this)" : "()",
                                "{0})"));
                        }
                    }
                    else
                    {
                        if (proto)
                        {
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + ".call(this, {0})");
                        }
                        else
                        {
                            this.PushWriter(Helpers.GetPropertyRef(member.Member, this.Emitter, true) + "({0})");
                        }
                    }
                }
                else if (member.Member.SymbolKind == SymbolKind.Field)
                {
                    bool isConst = this.Emitter.IsMemberConst(member.Member);

                    if (isConst && this.Emitter.IsInlineConst(member.Member))
                    {
                        this.WriteScript(member.ConstantValue);
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName());
                    }
                }
                else if (resolveResult is InvocationResolveResult)
                {
                    InvocationResolveResult invocationResult = (InvocationResolveResult)resolveResult;
                    CSharpInvocationResolveResult cInvocationResult = (CSharpInvocationResolveResult)resolveResult;
                    var expresssionMember = expressionResolveResult as MemberResolveResult;

                    if (expresssionMember != null &&
                        cInvocationResult != null &&
                        cInvocationResult.IsDelegateInvocation &&
                        invocationResult.Member != expresssionMember.Member)
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName());
                    }
                    else
                    {
                        this.Write(OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName());
                    }
                }
                else if (member.Member is DefaultResolvedEvent && this.Emitter.IsAssignment && (this.Emitter.AssignmentType == AssignmentOperatorType.Add || this.Emitter.AssignmentType == AssignmentOperatorType.Subtract))
                {
                    this.Write(this.Emitter.AssignmentType == AssignmentOperatorType.Add ? "add" : "remove");
                    this.Write(OverloadsCollection.Create(this.Emitter, member.Member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName());
                    this.WriteOpenParentheses();
                }
                else
                {
                    this.Write(this.Emitter.GetEntityName(member.Member));
                }

                Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this);
            }
        }
Exemplo n.º 33
0
        ExpressionWithResolveResult HandleAccessorCall(ExpectedTargetDetails expectedTargetDetails, IMethod method, TranslatedExpression target, IList <TranslatedExpression> arguments)
        {
            bool requireTarget = expressionBuilder.HidesVariableWithName(method.AccessorOwner.Name) ||
                                 (method.IsStatic ? !expressionBuilder.IsCurrentOrContainingType(method.DeclaringTypeDefinition) : !(target.Expression is ThisReferenceExpression));
            bool targetCasted        = false;
            var  targetResolveResult = requireTarget ? target.ResolveResult : null;

            IMember foundMember;

            while (!IsUnambiguousAccess(expectedTargetDetails, targetResolveResult, method, out foundMember))
            {
                if (!requireTarget)
                {
                    requireTarget       = true;
                    targetResolveResult = target.ResolveResult;
                }
                else if (!targetCasted)
                {
                    targetCasted        = true;
                    target              = target.ConvertTo(method.AccessorOwner.DeclaringType, expressionBuilder);
                    targetResolveResult = target.ResolveResult;
                }
                else
                {
                    foundMember = method.AccessorOwner;
                    break;
                }
            }

            var rr = new MemberResolveResult(target.ResolveResult, foundMember);

            if (method.ReturnType.IsKnownType(KnownTypeCode.Void))
            {
                var value = arguments.Last();
                arguments.Remove(value);
                TranslatedExpression expr;

                if (arguments.Count != 0)
                {
                    expr = new IndexerExpression(target.Expression, arguments.Select(a => a.Expression))
                           .WithoutILInstruction().WithRR(rr);
                }
                else if (requireTarget)
                {
                    expr = new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name)
                           .WithoutILInstruction().WithRR(rr);
                }
                else
                {
                    expr = new IdentifierExpression(method.AccessorOwner.Name)
                           .WithoutILInstruction().WithRR(rr);
                }

                var op          = AssignmentOperatorType.Assign;
                var parentEvent = method.AccessorOwner as IEvent;
                if (parentEvent != null)
                {
                    if (method.Equals(parentEvent.AddAccessor))
                    {
                        op = AssignmentOperatorType.Add;
                    }
                    if (method.Equals(parentEvent.RemoveAccessor))
                    {
                        op = AssignmentOperatorType.Subtract;
                    }
                }
                return(new AssignmentExpression(expr, op, value.Expression).WithRR(new TypeResolveResult(method.AccessorOwner.ReturnType)));
            }
            else
            {
                if (arguments.Count != 0)
                {
                    return(new IndexerExpression(target.Expression, arguments.Select(a => a.Expression))
                           .WithoutILInstruction().WithRR(rr));
                }
                else if (requireTarget)
                {
                    return(new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name)
                           .WithoutILInstruction().WithRR(rr));
                }
                else
                {
                    return(new IdentifierExpression(method.AccessorOwner.Name)
                           .WithoutILInstruction().WithRR(rr));
                }
            }
        }
		string Visit(MemberResolveResult result)
		{
			string text = PrintInternal(result.TargetResult);
			if (!string.IsNullOrWhiteSpace(text))
				text += ".";
			return text + result.Member.Name;
		}
Exemplo n.º 35
0
        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);
        }
Exemplo n.º 36
0
        public ResolveResult ResolveNode(AstNode node, ILog log)
        {
            var syntaxTree = node.GetParent<SyntaxTree>();
            this.InitResolver(syntaxTree);

            var result = this.resolver.Resolve(node);

            if (result is MethodGroupResolveResult && node.Parent != null)
            {
                var methodGroupResolveResult = (MethodGroupResolveResult)result;
                var parentResolveResult = this.ResolveNode(node.Parent, log);
                var parentInvocation = parentResolveResult as InvocationResolveResult;
                IParameterizedMember method = methodGroupResolveResult.Methods.LastOrDefault();
                bool isInvocation = node.Parent is InvocationExpression && (((InvocationExpression)(node.Parent)).Target == node);

                if (node is Expression)
                {
                    var conversion = this.Resolver.GetConversion((Expression)node);
                    if (conversion != null && conversion.IsMethodGroupConversion)
                    {
                        return new MemberResolveResult(new TypeResolveResult(conversion.Method.DeclaringType), conversion.Method);
                    }
                }

                if (isInvocation && parentInvocation != null)
                {
                    var or = methodGroupResolveResult.PerformOverloadResolution(this.compilation, parentInvocation.GetArgumentsForCall().ToArray());
                    if (or.FoundApplicableCandidate)
                    {
                        method = or.BestCandidate;
                        return new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                    }
                }

                if (parentInvocation != null && method == null)
                {
                    var typeDef = methodGroupResolveResult.TargetType as DefaultResolvedTypeDefinition;

                    if (typeDef != null)
                    {
                        var methods = typeDef.Methods.Where(m => m.Name == methodGroupResolveResult.MethodName);
                        method = methods.FirstOrDefault();
                    }
                }

                if (method == null)
                {
                    var extMethods = methodGroupResolveResult.GetEligibleExtensionMethods(false);

                    if (!extMethods.Any())
                    {
                        extMethods = methodGroupResolveResult.GetExtensionMethods();
                    }

                    if (!extMethods.Any() || !extMethods.First().Any())
                    {
                        throw new EmitterException(node, "Cannot find method defintion");
                    }

                    method = extMethods.First().First();
                }

                if (parentInvocation == null || method.FullName != parentInvocation.Member.FullName)
                {
                    MemberResolveResult memberResolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                    return memberResolveResult;
                }

                return parentResolveResult;
            }

            if ((result == null || result.IsError) && log != null)
            {
                if (result is CSharpInvocationResolveResult && ((CSharpInvocationResolveResult)result).OverloadResolutionErrors != OverloadResolutionErrors.None)
                {
                    return result;
                }

                log.LogWarning(string.Format("Node resolving has failed {0}: {1}", node.StartLocation, node.ToString()));
            }

            return result;
        }
Exemplo n.º 37
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            List <Change>          result        = new List <Change> ();
            TextEditorData         data          = options.GetTextEditorData();
            MemberResolveResult    resolveResult = options.ResolveResult as MemberResolveResult;
            IProperty              property      = resolveResult.ResolvedMember as IProperty;
            INRefactoryASTProvider astProvider   = options.GetASTProvider();
            string backingStoreName = RetrieveBackingStore(options, astProvider, property);

            int    backinStoreStart;
            int    backinStoreEnd;
            IField backingStore = GetBackingStoreField(options, backingStoreName, out backinStoreStart, out backinStoreEnd);

            if (backingStore != null)
            {
                using (var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor(true, true)) {
                    foreach (MemberReference memberRef in ReferenceFinder.FindReferences(backingStore, monitor))
                    {
                        result.Add(new TextReplaceChange()
                        {
                            FileName     = memberRef.FileName,
                            Offset       = memberRef.Position,
                            RemovedChars = memberRef.Name.Length,
                            InsertedText = property.Name
                        });
                    }
                }

                result.RemoveAll(c => backinStoreStart <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset <= backinStoreEnd);
                result.Add(new TextReplaceChange()
                {
                    FileName     = options.Document.FileName,
                    Offset       = backinStoreStart,
                    RemovedChars = backinStoreEnd - backinStoreStart
                });
            }

            if (property.HasGet)
            {
                int startOffset = data.Document.LocationToOffset(property.GetRegion.Start.ToDocumentLocation(data.Document));
                int endOffset   = data.Document.LocationToOffset(property.GetRegion.End.ToDocumentLocation(data.Document));

                string text = astProvider.OutputNode(options.Dom, new PropertyGetRegion(null, null), options.GetIndent(property) + "\t").Trim();

                result.RemoveAll(c => startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset <= endOffset);
                result.Add(new TextReplaceChange()
                {
                    FileName     = options.Document.FileName,
                    Offset       = startOffset,
                    RemovedChars = endOffset - startOffset,
                    InsertedText = text
                });
            }

            int setStartOffset;
            int setEndOffset;
            PropertySetRegion setRegion = new PropertySetRegion(null, null);
            string            setText;

            if (property.HasSet)
            {
                setStartOffset = data.Document.LocationToOffset(property.SetRegion.Start.ToDocumentLocation(data.Document));
                setEndOffset   = data.Document.LocationToOffset(property.SetRegion.End.ToDocumentLocation(data.Document));
                setText        = astProvider.OutputNode(options.Dom, setRegion, options.GetIndent(property) + "\t").Trim();
            }
            else
            {
                setEndOffset       = setStartOffset = data.Document.LocationToOffset(property.GetRegion.End.ToDocumentLocation(data.Document));
                setRegion.Modifier = ICSharpCode.NRefactory.Ast.Modifiers.Private;
                setText            = Environment.NewLine + astProvider.OutputNode(options.Dom, setRegion, options.GetIndent(property) + "\t").TrimEnd();
            }
            result.RemoveAll(c => setStartOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset <= setEndOffset);
            result.Add(new TextReplaceChange()
            {
                FileName     = options.Document.FileName,
                Offset       = setStartOffset,
                RemovedChars = setEndOffset - setStartOffset,
                InsertedText = setText
            });
            return(result);
        }
Exemplo n.º 38
0
        private void BuildTypedArguments(MemberResolveResult rr)
        {
            var typeParams = rr.Member.DeclaringTypeDefinition.TypeParameters;
            var typeArgs = rr.Member.DeclaringType.TypeArguments;
            var temp = new TypeParamExpression[typeParams.Count];

            for (int i = 0; i < typeParams.Count; i++)
            {
                temp[i] = new TypeParamExpression(typeParams[i].Name, null, typeArgs[i], true);
            }

            this.TypeArguments = temp;
        }
Exemplo n.º 39
0
        public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
        {
            if (propertyDeclaration.HasModifier(Modifiers.Abstract))
            {
                return;
            }

            bool isStatic = propertyDeclaration.HasModifier(Modifiers.Static);

            IDictionary <string, List <EntityDeclaration> > dict = isStatic
                ? CurrentType.StaticProperties
                : CurrentType.InstanceProperties;

            var key = propertyDeclaration.Name;

            if (dict.ContainsKey(key))
            {
                dict[key].Add(propertyDeclaration);
            }
            else
            {
                dict.Add(key, new List <EntityDeclaration>(new[] { propertyDeclaration }));
            }

            var rr = this.Resolver.ResolveNode(propertyDeclaration, null) as MemberResolveResult;

            if (OverloadsCollection.NeedCreateAlias(rr))
            {
                var config = rr.Member.IsStatic
                ? CurrentType.StaticConfig
                : CurrentType.InstanceConfig;
                config.Alias.Add(new TypeConfigItem {
                    Entity = propertyDeclaration
                });
            }

            var isResolvedProperty = false;
            MemberResolveResult resolvedProperty = null;

            CheckFieldProperty(propertyDeclaration, ref isResolvedProperty, ref resolvedProperty);

            if (!propertyDeclaration.Getter.IsNull &&
                !this.HasExternal(propertyDeclaration) &&
                !this.HasTemplate(propertyDeclaration.Getter) &&
                propertyDeclaration.Getter.Body.IsNull &&
                !this.HasScript(propertyDeclaration.Getter))
            {
                Expression     initializer = this.GetDefaultFieldInitializer(propertyDeclaration.ReturnType);
                TypeConfigInfo info        = isStatic ? this.CurrentType.StaticConfig : this.CurrentType.InstanceConfig;

                if (!isResolvedProperty)
                {
                    resolvedProperty   = Resolver.ResolveNode(propertyDeclaration, null) as MemberResolveResult;
                    isResolvedProperty = true;
                }

                bool autoPropertyToField = false;
                if (resolvedProperty != null && resolvedProperty.Member != null)
                {
                    autoPropertyToField = Helpers.IsFieldProperty(resolvedProperty.Member, AssemblyInfo);
                }
                else
                {
                    autoPropertyToField = AssemblyInfo.AutoPropertyToField;
                }

                var autoInitializer = info.AutoPropertyInitializers.FirstOrDefault(f => f.Name == key);

                if (autoInitializer != null)
                {
                    initializer = autoInitializer.Initializer;
                }

                if (!autoPropertyToField)
                {
                    if (resolvedProperty != null && resolvedProperty.Member.ImplementedInterfaceMembers.Count > 0 && resolvedProperty.Member.ImplementedInterfaceMembers.Any(m => Helpers.IsFieldProperty(m, this.AssemblyInfo)))
                    {
                        throw new EmitterException(propertyDeclaration, string.Format("The property {0} is not marked as FieldProperty but implemented interface member has such attribute", resolvedProperty.Member.ToString()));
                    }

                    info.Properties.Add(new TypeConfigItem
                    {
                        Name        = key,
                        Entity      = propertyDeclaration,
                        Initializer = initializer
                    });
                }
                else
                {
                    if (resolvedProperty != null && resolvedProperty.Member.ImplementedInterfaceMembers.Count > 0 && !resolvedProperty.Member.ImplementedInterfaceMembers.All(m => Helpers.IsFieldProperty(m, this.AssemblyInfo)))
                    {
                        throw new EmitterException(propertyDeclaration, string.Format("The property {0} is marked as FieldProperty but implemented interface member has no such attribute", resolvedProperty.Member.ToString()));
                    }

                    info.Fields.Add(new TypeConfigItem
                    {
                        Name        = key,
                        Entity      = propertyDeclaration,
                        Initializer = initializer
                    });
                }
            }
        }