Пример #1
0
        public override ValueReference Evaluate(EvaluationContext ctx, string expression, object expectedType)
        {
            expression = expression.Trim();

            if (expression.Length > 0 && expression[0] == '?')
            {
                expression = expression.Substring(1).TrimStart();
            }

            if (expression.Length > 3 && expression.StartsWith("var", StringComparison.Ordinal) && char.IsWhiteSpace(expression[3]))
            {
                expression = expression.Substring(4).TrimStart();
                string variable = null;

                for (int n = 0; n < expression.Length; n++)
                {
                    if (!char.IsLetterOrDigit(expression[n]) && expression[n] != '_')
                    {
                        variable = expression.Substring(0, n);
                        if (!expression.Substring(n).TrimStart().StartsWith("=", StringComparison.Ordinal))
                        {
                            variable = null;
                        }
                        break;
                    }

                    if (n == expression.Length - 1)
                    {
                        variable   = expression;
                        expression = null;
                        break;
                    }
                }

                if (!string.IsNullOrEmpty(variable))
                {
                    userVariables[variable] = new UserVariableReference(ctx, variable);
                }

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

            expression = ReplaceExceptionTag(expression, ctx.Options.CurrentExceptionTag);

            var expr = new CSharpParser().ParseExpression(expression);

            if (expr == null)
            {
                throw new EvaluatorException("Could not parse expression '{0}'", expression);
            }

            var evaluator = new NRefactoryExpressionEvaluatorVisitor(ctx, expression, expectedType, userVariables);

            return(expr.AcceptVisitor(evaluator));
        }
		ValueReference Evaluate (EvaluationContext ctx, string exp, object expectedType, bool tryTypeOf)
		{
			exp = exp.TrimStart ();
			if (exp.StartsWith ("?"))
				exp = exp.Substring (1).Trim ();
			if (exp.StartsWith ("var ")) {
				exp = exp.Substring (4).Trim (' ','\t');
				string var = null;
				for (int n=0; n<exp.Length; n++) {
					if (!char.IsLetterOrDigit (exp[n]) && exp[n] != '_') {
						var = exp.Substring (0, n);
						if (!exp.Substring (n).Trim (' ','\t').StartsWith ("="))
							var = null;
						break;
					}
					if (n == exp.Length - 1) {
						var = exp;
						exp = null;
						break;
					}
				}
				if (!string.IsNullOrEmpty (var))
					userVariables [var] = new UserVariableReference (ctx, var);
				if (exp == null)
					return null;
			}
			
			exp = ReplaceExceptionTag (exp, ctx.Options.CurrentExceptionTag);
			
			StringReader codeStream = new StringReader (exp);
			IParser parser = ParserFactory.CreateParser (SupportedLanguage.CSharp, codeStream);
			Expression expObj = parser.ParseExpression ();
			if (expObj == null)
				throw new EvaluatorException ("Could not parse expression '{0}'", exp);
			
			try {
				EvaluatorVisitor ev = new EvaluatorVisitor (ctx, exp, expectedType, userVariables, tryTypeOf);
				return (ValueReference) expObj.AcceptVisitor (ev, null);
			} catch {
				if (!tryTypeOf && (expObj is BinaryOperatorExpression) && IsTypeName (exp)) {
					// This is a hack to be able to parse expressions such as "List<string>". The NRefactory parser
					// can parse a single type name, so a solution is to wrap it around a typeof(). We do it if
					// the evaluation fails.
					return Evaluate (ctx, "typeof(" + exp + ")", expectedType, true);
				} else
					throw;
			}
		}
		public override ValueReference Evaluate (EvaluationContext ctx, string expression, object expectedType)
		{
			expression = expression.TrimStart ();

			if (expression.Length > 0 && expression[0] == '?')
				expression = expression.Substring (1).Trim ();

			if (expression.StartsWith ("var", StringComparison.Ordinal) && char.IsWhiteSpace (expression[3])) {
				expression = expression.Substring (4).Trim (' ', '\t');
				string variable = null;

				for (int n = 0; n < expression.Length; n++) {
					if (!char.IsLetterOrDigit (expression[n]) && expression[n] != '_') {
						variable = expression.Substring (0, n);
						if (!expression.Substring (n).Trim (' ', '\t').StartsWith ("=", StringComparison.Ordinal))
							variable = null;
						break;
					}

					if (n == expression.Length - 1) {
						variable = expression;
						expression = null;
						break;
					}
				}

				if (!string.IsNullOrEmpty (variable))
					userVariables[variable] = new UserVariableReference (ctx, variable);

				if (expression == null)
					return null;
			}

			expression = ReplaceExceptionTag (expression, ctx.Options.CurrentExceptionTag);

			var expr = new CSharpParser ().ParseExpression (expression);
			if (expr == null)
				throw new EvaluatorException ("Could not parse expression '{0}'", expression);

			var evaluator = new NRefactoryExpressionEvaluatorVisitor (ctx, expression, expectedType, userVariables);
			return expr.AcceptVisitor<ValueReference> (evaluator);
		}