Пример #1
0
        private static void RenderPropertyOrField(SyntaxTreeNode syntaxTree, StringBuilder builder, bool checkedScope)
        {
            if (syntaxTree == null)
            {
                throw new ArgumentNullException("syntaxTree");
            }
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

            var target = syntaxTree.GetExpression(throwOnError: false);
            var propertyOrFieldName = syntaxTree.GetMemberName(throwOnError: true);
            var useNullPropagation  = syntaxTree.GetUseNullPropagation(throwOnError: false);
            var arguments           = syntaxTree.GetArguments(throwOnError: false);

            if (target != null)
            {
                Render(target, builder, false, checkedScope);
                if (useNullPropagation)
                {
                    builder.Append("?.");
                }
                else
                {
                    builder.Append(".");
                }
            }
            builder.Append(propertyOrFieldName);
            if (arguments != null && arguments.Count > 0)
            {
                builder.Append("<");
                for (var i = 0; i < arguments.Count; i++)
                {
                    if (i != 0)
                    {
                        builder.Append(",");
                    }
                    var typeArgument = default(SyntaxTreeNode);
                    if (arguments.TryGetValue(i, out typeArgument))
                    {
                        Render(typeArgument, builder, true, checkedScope);
                    }
                }
                builder.Append(">");
            }
        }
Пример #2
0
        public static bool TryBind(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (bindingContext == null)
            {
                throw new ArgumentNullException("bindingContext");
            }
            if (expectedType == null)
            {
                throw new ArgumentNullException("expectedType");
            }

            bindingError = null;

            var name = node.GetMemberName(throwOnError: true);

            if (bindingContext.TryGetParameter(name, out boundExpression))
            {
                return(true);
            }

            var typeName = node.GetTypeName(throwOnError: false);
            var type     = default(Type);

            if (bindingContext.TryResolveType(typeName, out type) == false)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVETYPE, typeName), node);
                return(false);
            }

            boundExpression = Expression.Parameter(type, name);
            return(true);
        }
Пример #3
0
        public static bool TryBind(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (bindingContext == null)
            {
                throw new ArgumentNullException("bindingContext");
            }
            if (expectedType == null)
            {
                throw new ArgumentNullException("expectedType");
            }

            boundExpression = null;
            bindingError    = null;

            var target     = default(Expression);
            var targetNode = node.GetExpression(throwOnError: false);
            var memberNode = node.GetMember(throwOnError: false);
            var member     = default(MemberDescription);

            if (memberNode != null && bindingContext.TryResolveMember(memberNode, out member))
            {
                if (targetNode != null && AnyBinder.TryBind(targetNode, bindingContext, TypeDescription.ObjectType, out target, out bindingError) == false)
                {
                    return(false);
                }
                boundExpression = Expression.MakeMemberAccess(target, member);
                return(true);
            }

            var isStatic            = false;
            var targetType          = default(Type);
            var propertyOrFieldName = node.GetMemberName(throwOnError: true);
            var useNullPropagation  = node.GetUseNullPropagation(throwOnError: false);

            if (bindingContext.TryResolveType(targetNode, out targetType))
            {
                target   = null;
                isStatic = true;
            }
            else if (targetNode == null)
            {
                target     = bindingContext.Global;
                targetType = target != null ? target.Type : null;
                isStatic   = false;

                switch (propertyOrFieldName)
                {
                case Constants.VALUE_NULL_STRING:
                    boundExpression = ExpressionUtils.NullConstant;
                    return(true);

                case Constants.VALUE_TRUE_STRING:
                    boundExpression = ExpressionUtils.TrueConstant;
                    return(true);

                case Constants.VALUE_FALSE_STRING:
                    boundExpression = ExpressionUtils.TrueConstant;
                    return(false);

                default:
                    if (bindingContext.TryGetParameter(propertyOrFieldName, out boundExpression))
                    {
                        return(true);
                    }
                    break;
                }
            }
            else if (AnyBinder.TryBind(targetNode, bindingContext, TypeDescription.ObjectType, out target, out bindingError))
            {
                Debug.Assert(target != null, "target != null");

                targetType = target.Type;
                isStatic   = false;
            }
            else
            {
                target     = null;
                targetType = null;
            }

            if (target == null && targetType == null)
            {
                if (bindingError == null)
                {
                    bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVENAME, propertyOrFieldName), node);
                }
                return(false);
            }

            Debug.Assert(targetType != null, "type != null");

            var targetTypeDescription = TypeDescription.GetTypeDescription(targetType);
            var foundMember           = default(MemberDescription);

            if (isStatic && targetTypeDescription.IsEnum)
            {
                var fieldMemberDescription = targetTypeDescription.GetMembers(propertyOrFieldName).FirstOrDefault(m => m.IsStatic);
                if (fieldMemberDescription == null)
                {
                    bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVEMEMBERONTYPE, propertyOrFieldName, targetType), node);
                    return(false);
                }
                boundExpression = fieldMemberDescription.ConstantValueExpression;
            }
            else
            {
                foreach (var declaredMember in targetTypeDescription.GetMembers(propertyOrFieldName))
                {
                    if (declaredMember.IsStatic != isStatic)
                    {
                        continue;
                    }

                    foundMember = foundMember ?? declaredMember;

                    if (declaredMember.IsPropertyOrField == false)
                    {
                        continue;
                    }

                    if (declaredMember.TryMakeAccessor(target, out boundExpression))
                    {
                        break;
                    }
                }
            }

            if (boundExpression == null)
            {
                if (foundMember != null)
                {
                    bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETOBINDMEMBER, propertyOrFieldName, targetType), node);
                }
                else
                {
                    bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVEMEMBERONTYPE, propertyOrFieldName, targetType), node);
                }
                return(false);
            }

            if (useNullPropagation && isStatic)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETOAPPLYNULLCONDITIONALOPERATORONTYPEREF, targetType));
                return(false);
            }

            if (useNullPropagation && targetTypeDescription.CanBeNull)
            {
                bindingContext.RegisterNullPropagationTarget(target);
            }

            if (targetTypeDescription.IsAssignableFrom(typeof(Type)) &&
                bindingContext.IsKnownType(typeof(Type)) == false &&
                bindingContext.IsKnownType(targetType) == false)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_RESTRICTED_MEMBER_INVOCATION, propertyOrFieldName, targetType, typeof(ITypeResolver)), node);
                return(false);
            }

            return(true);
        }