Ejemplo n.º 1
0
		public override void VisitIndexerExpression(IndexerExpression indexerExpression)
		{
			base.VisitIndexerExpression(indexerExpression);

			var localResolveResult = context.Resolve(indexerExpression.Target) as LocalResolveResult;
			if (localResolveResult == null)
				return;
			var resolveResult = context.Resolve(indexerExpression);
			if (localResolveResult == null)
				return;
			var parent = indexerExpression.Parent;
			while (parent is ParenthesizedExpression)
				parent = parent.Parent;
			if (parent is DirectionExpression) {
				// The only types which are indexable and where the indexing expression
				// results in a variable is an actual array type
				AddCriterion(localResolveResult.Variable, new IsArrayTypeCriterion());
			} else if (resolveResult is ArrayAccessResolveResult) {
				var arrayResolveResult = (ArrayAccessResolveResult)resolveResult;
				var arrayType = arrayResolveResult.Array.Type as ArrayType;
				if (arrayType != null) {
					var parameterTypes = arrayResolveResult.Indexes.Select(index => index.Type);
					var criterion = new SupportsIndexingCriterion(arrayType.ElementType, parameterTypes, CSharpConversions.Get(context.Compilation));
					AddCriterion(localResolveResult.Variable, criterion);
				}
			} else if (resolveResult is CSharpInvocationResolveResult) {
				var invocationResolveResult = (CSharpInvocationResolveResult)resolveResult;
				var parameterTypes = invocationResolveResult.Arguments.Select(arg => arg.Type);
				var criterion = new SupportsIndexingCriterion(invocationResolveResult.Member.ReturnType, parameterTypes, CSharpConversions.Get(context.Compilation));
				AddCriterion(localResolveResult.Variable, criterion);
			}
		}
        public void ArrayCreationInIndexer()
        {
            Expression expr = new IndexerExpression {
                Target = new ArrayCreateExpression {
                    Type = new PrimitiveType("int"),
                    Arguments = { new PrimitiveExpression(1) }
                },
                Arguments = { new PrimitiveExpression(0) }
            };

            Assert.AreEqual("(new int[1]) [0]", InsertRequired(expr));
            Assert.AreEqual("(new int[1]) [0]", InsertReadable(expr));
        }
Ejemplo n.º 3
0
        public ArgumentsInfo(IEmitter emitter, IndexerExpression invocationExpression)
        {
            this.Emitter = emitter;
            this.Expression = invocationExpression;

            var arguments = invocationExpression.Arguments.ToList();
            this.ResolveResult = emitter.Resolver.ResolveNode(invocationExpression, emitter) as InvocationResolveResult;

            this.BuildArgumentsList(arguments);
            if (this.ResolveResult != null)
            {
                this.BuildTypedArguments(invocationExpression.Target);
            }
        }
Ejemplo n.º 4
0
				public override void VisitIndexerExpression (IndexerExpression indexerExpression)
				{
					base.VisitIndexerExpression (indexerExpression);

					if (Match (indexerExpression.Target) && First == null) {
						First = indexerExpression;
					}
				}
Ejemplo n.º 5
0
 public IndexerBlock(IEmitter emitter, IndexerExpression indexerExpression)
     : base(emitter, indexerExpression)
 {
     this.Emitter           = emitter;
     this.IndexerExpression = indexerExpression;
 }
Ejemplo n.º 6
0
		public void ArrayCreationWithInitializerInIndexer()
		{
			Expression expr = new IndexerExpression {
				Target = new ArrayCreateExpression {
					Type = new PrimitiveType("int"),
					Arguments = { new PrimitiveExpression(1) },
					Initializer = new ArrayInitializerExpression {
						Elements = { new PrimitiveExpression(42) }
					}
				},
				Arguments = { new PrimitiveExpression(0) }
			};
			
			Assert.AreEqual("new int[1] { 42 } [0]", InsertRequired(expr));
			Assert.AreEqual("(new int[1] { 42 }) [0]", InsertReadable(expr));
		}
Ejemplo n.º 7
0
 public void VisitIndexerExpression(IndexerExpression indexExpr)
 {
     indexExpr.Target.AcceptWalker(this);
     indexExpr.Arguments.AcceptWalker(this);
 }
Ejemplo n.º 8
0
 public abstract StringBuilder VisitIndexerExpression(IndexerExpression indexerExpression, int data);
        public override void VisitIndexerExpression(IndexerExpression indexerExpression)
        {
            ForceSpacesBefore(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets);
            ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets);

            if (!indexerExpression.Target.IsNull)
                indexerExpression.Target.AcceptVisitor(this);

            FormatArguments(indexerExpression);
        }
Ejemplo n.º 10
0
        public override AstNode VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
        {
            if (this.Rules.Integer == IntegerRule.Managed && (unaryOperatorExpression.Operator == UnaryOperatorType.Increment ||
                                                              unaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement ||
                                                              unaryOperatorExpression.Operator == UnaryOperatorType.Decrement ||
                                                              unaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement))
            {
                var rr            = this.Resolver.ResolveNode(unaryOperatorExpression, null);
                var expression_rr = this.Resolver.ResolveNode(unaryOperatorExpression.Expression, null);

                if (rr is ErrorResolveResult)
                {
                    UnaryOperatorExpression clonUnaryOperatorExpression = (UnaryOperatorExpression)base.VisitUnaryOperatorExpression(unaryOperatorExpression);
                    if (clonUnaryOperatorExpression == null)
                    {
                        clonUnaryOperatorExpression = (UnaryOperatorExpression)unaryOperatorExpression.Clone();
                    }

                    bool isPost = clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement ||
                                  clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;

                    var isStatement = unaryOperatorExpression.Parent is ExpressionStatement;
                    var isIncr      = clonUnaryOperatorExpression.Operator == UnaryOperatorType.Increment || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;
                    AssignmentExpression ae;

                    ae = new AssignmentExpression(clonUnaryOperatorExpression.Expression.Clone(), new BinaryOperatorExpression(clonUnaryOperatorExpression.Expression.Clone(), isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, new PrimitiveExpression(1)));

                    if (isPost && !isStatement)
                    {
                        return(new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                        {
                            IsDoubleColon = true
                        }), "Script"), "Identity"), clonUnaryOperatorExpression.Expression.Clone(), ae));
                    }
                    else
                    {
                        if (isStatement)
                        {
                            return(ae);
                        }

                        return(new ParenthesizedExpression(ae));
                    }
                }
                else
                {
                    var orr = (OperatorResolveResult)rr;

                    if (Helpers.IsFloatType(orr.Type, this.Resolver) || Helpers.Is64Type(orr.Type, this.Resolver))
                    {
                        return(base.VisitUnaryOperatorExpression(unaryOperatorExpression));
                    }

                    UnaryOperatorExpression clonUnaryOperatorExpression = (UnaryOperatorExpression)base.VisitUnaryOperatorExpression(unaryOperatorExpression);
                    if (clonUnaryOperatorExpression == null)
                    {
                        clonUnaryOperatorExpression = (UnaryOperatorExpression)unaryOperatorExpression.Clone();
                    }

                    bool isPost = clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement ||
                                  clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;

                    var isStatement        = unaryOperatorExpression.Parent is ExpressionStatement;
                    var isIncr             = clonUnaryOperatorExpression.Operator == UnaryOperatorType.Increment || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement;
                    var needReturnOriginal = isPost && !isStatement;

                    Expression expression      = clonUnaryOperatorExpression.Expression.Clone();
                    Expression expressionAfter = clonUnaryOperatorExpression.Expression.Clone();

                    AssignmentExpression ae = null;

                    if (orr.UserDefinedOperatorMethod != null)
                    {
                        ae = new AssignmentExpression(expressionAfter.Clone(), clonUnaryOperatorExpression);
                    }
                    else if (clonUnaryOperatorExpression.Expression is MemberReferenceExpression mre && expression_rr is MemberResolveResult member_rr)
                    {
                        if (needReturnOriginal)
                        {
                            bool isSimple = (member_rr != null &&
                                             (member_rr.TargetResult is ThisResolveResult ||
                                              member_rr.TargetResult is LocalResolveResult ||
                                              member_rr.TargetResult is TypeResolveResult ||
                                              member_rr.TargetResult is ConstantResolveResult));

                            expression = isSimple ? mre.Clone() : new MemberReferenceExpression(new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), mre.Target.Clone()), mre.MemberName);
                            expressionAfter = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), mre.Target.Clone());
                        }
                        else
                        {
                            expressionAfter = null;
                        }

                        ae = BuildMemberReferenceReplacement(isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, mre, member_rr, expressionAfter);
                    }
                    else if (clonUnaryOperatorExpression.Expression is IndexerExpression ie && expression_rr is ArrayAccessResolveResult array_rr)
                    {
                        IndexerExpression cacheIndexer = null;
                        if (needReturnOriginal)
                        {
                            var  array_target_rr = array_rr.Array as MemberResolveResult;
                            bool isSimpleTarget  = (array_target_rr != null && array_target_rr.Member is IField &&
                                                    (array_target_rr.TargetResult is ThisResolveResult ||
                                                     array_target_rr.TargetResult is LocalResolveResult ||
                                                     array_target_rr.TargetResult is TypeResolveResult ||
                                                     array_target_rr.TargetResult is ConstantResolveResult)) ||
                                                   (array_rr.Array is ThisResolveResult ||
                                                    array_rr.Array is LocalResolveResult ||
                                                    array_rr.Array is ConstantResolveResult);

                            bool simpleIndex = true;

                            foreach (var index in array_rr.Indexes)
                            {
                                var  indexMemberTargetrr = index as MemberResolveResult;
                                bool isIndexSimple       = (indexMemberTargetrr != null && indexMemberTargetrr.Member is IField &&
                                                            (indexMemberTargetrr.TargetResult is ThisResolveResult ||
                                                             indexMemberTargetrr.TargetResult is LocalResolveResult)) || index is ThisResolveResult || index is LocalResolveResult || index is ConstantResolveResult;

                                if (!isIndexSimple)
                                {
                                    simpleIndex = false;
                                    break;
                                }
                            }
                            var leftIndexerArgs  = new List <Expression>();
                            var rightIndexerArgs = new List <Expression>();

                            foreach (var index in ie.Arguments)
                            {
                                var expr = simpleIndex ? index.Clone() : new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                                {
                                    IsDoubleColon = true
                                }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), index.Clone());
                                leftIndexerArgs.Add(expr);

                                expr = simpleIndex ? index.Clone() : new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                                {
                                    IsDoubleColon = true
                                }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), index.Clone());
                                rightIndexerArgs.Add(expr);
                            }

                            var leftExpr = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), ie.Target.Clone());
                            var rightExpr = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE)
                            {
                                IsDoubleColon = true
                            }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), ie.Target.Clone());

                            var leftIndexer  = new IndexerExpression(isSimpleTarget ? ie.Target.Clone() : leftExpr, leftIndexerArgs);
                            var rightIndexer = new IndexerExpression(isSimpleTarget ? ie.Target.Clone() : rightExpr, rightIndexerArgs);

                            expression   = leftIndexer;
                            cacheIndexer = rightIndexer;
                        }

                        ae = BuildIndexerReplacement(isStatement, isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, ie, array_rr, cacheIndexer);
                    }
Ejemplo n.º 11
0
 public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
 {
     return(new CodeIndexerExpression((CodeExpression)indexerExpression.TargetObject.AcceptVisitor(this, data), GetExpressionList(indexerExpression.Indexes)));
 }
Ejemplo n.º 12
0
		public virtual void VisitIndexerExpression(IndexerExpression indexerExpression)
		{
			DebugExpression(indexerExpression);
			StartNode(indexerExpression);
			indexerExpression.Target.AcceptVisitor(this);
			Space(policy.SpaceBeforeMethodCallParentheses);
			WriteCommaSeparatedListInBrackets(indexerExpression.Arguments, CodeBracesRangeFlags.SquareBrackets);
			EndNode(indexerExpression);
		}
 public override void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     base.VisitIndexerExpression(indexerExpression);
     Check(ctx.Resolve(indexerExpression), indexerExpression);
 }
Ejemplo n.º 14
0
	void PrimaryExpr(
#line  1862 "cs.ATG" 
out Expression pexpr) {

#line  1864 "cs.ATG" 
		TypeReference type = null;
		Expression expr;
		pexpr = null;
		

#line  1869 "cs.ATG" 
		Location startLocation = la.Location; 
		if (la.kind == 113) {
			lexer.NextToken();

#line  1871 "cs.ATG" 
			pexpr = new PrimitiveExpression(true, "true");  
		} else if (la.kind == 72) {
			lexer.NextToken();

#line  1872 "cs.ATG" 
			pexpr = new PrimitiveExpression(false, "false"); 
		} else if (la.kind == 90) {
			lexer.NextToken();

#line  1873 "cs.ATG" 
			pexpr = new PrimitiveExpression(null, "null");  
		} else if (la.kind == 2) {
			lexer.NextToken();

#line  1874 "cs.ATG" 
			pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
		} else if (
#line  1875 "cs.ATG" 
StartOfQueryExpression()) {
			QueryExpression(
#line  1876 "cs.ATG" 
out pexpr);
		} else if (
#line  1877 "cs.ATG" 
IdentAndDoubleColon()) {
			Identifier();

#line  1878 "cs.ATG" 
			type = new TypeReference(t.val); 
			Expect(10);

#line  1879 "cs.ATG" 
			pexpr = new TypeReferenceExpression(type); 
			Identifier();

#line  1880 "cs.ATG" 
			if (type.Type == "global") { type.IsGlobal = true; type.Type = t.val ?? "?"; } else type.Type += "." + (t.val ?? "?"); 
		} else if (StartOf(19)) {
			Identifier();

#line  1884 "cs.ATG" 
			pexpr = new IdentifierExpression(t.val); 
			if (la.kind == 48 || 
#line  1887 "cs.ATG" 
IsGenericInSimpleNameOrMemberAccess()) {
				if (la.kind == 48) {
					ShortedLambdaExpression(
#line  1886 "cs.ATG" 
(IdentifierExpression)pexpr, out pexpr);
				} else {

#line  1888 "cs.ATG" 
					List<TypeReference> typeList; 
					TypeArgumentList(
#line  1889 "cs.ATG" 
out typeList, false);

#line  1890 "cs.ATG" 
					((IdentifierExpression)pexpr).TypeArguments = typeList; 
				}
			}
		} else if (
#line  1892 "cs.ATG" 
IsLambdaExpression()) {
			LambdaExpression(
#line  1893 "cs.ATG" 
out pexpr);
		} else if (la.kind == 20) {
			lexer.NextToken();
			Expr(
#line  1896 "cs.ATG" 
out expr);
			Expect(21);

#line  1896 "cs.ATG" 
			pexpr = new ParenthesizedExpression(expr); 
		} else if (StartOf(35)) {

#line  1899 "cs.ATG" 
			string val = null; 
			switch (la.kind) {
			case 52: {
				lexer.NextToken();

#line  1900 "cs.ATG" 
				val = "System.Boolean"; 
				break;
			}
			case 54: {
				lexer.NextToken();

#line  1901 "cs.ATG" 
				val = "System.Byte"; 
				break;
			}
			case 57: {
				lexer.NextToken();

#line  1902 "cs.ATG" 
				val = "System.Char"; 
				break;
			}
			case 62: {
				lexer.NextToken();

#line  1903 "cs.ATG" 
				val = "System.Decimal"; 
				break;
			}
			case 66: {
				lexer.NextToken();

#line  1904 "cs.ATG" 
				val = "System.Double"; 
				break;
			}
			case 75: {
				lexer.NextToken();

#line  1905 "cs.ATG" 
				val = "System.Single"; 
				break;
			}
			case 82: {
				lexer.NextToken();

#line  1906 "cs.ATG" 
				val = "System.Int32"; 
				break;
			}
			case 87: {
				lexer.NextToken();

#line  1907 "cs.ATG" 
				val = "System.Int64"; 
				break;
			}
			case 91: {
				lexer.NextToken();

#line  1908 "cs.ATG" 
				val = "System.Object"; 
				break;
			}
			case 102: {
				lexer.NextToken();

#line  1909 "cs.ATG" 
				val = "System.SByte"; 
				break;
			}
			case 104: {
				lexer.NextToken();

#line  1910 "cs.ATG" 
				val = "System.Int16"; 
				break;
			}
			case 108: {
				lexer.NextToken();

#line  1911 "cs.ATG" 
				val = "System.String"; 
				break;
			}
			case 116: {
				lexer.NextToken();

#line  1912 "cs.ATG" 
				val = "System.UInt32"; 
				break;
			}
			case 117: {
				lexer.NextToken();

#line  1913 "cs.ATG" 
				val = "System.UInt64"; 
				break;
			}
			case 120: {
				lexer.NextToken();

#line  1914 "cs.ATG" 
				val = "System.UInt16"; 
				break;
			}
			case 123: {
				lexer.NextToken();

#line  1915 "cs.ATG" 
				val = "System.Void"; 
				break;
			}
			}

#line  1917 "cs.ATG" 
			pexpr = new TypeReferenceExpression(new TypeReference(val, true)) { StartLocation = t.Location, EndLocation = t.EndLocation }; 
		} else if (la.kind == 111) {
			lexer.NextToken();

#line  1920 "cs.ATG" 
			pexpr = new ThisReferenceExpression(); pexpr.StartLocation = t.Location; pexpr.EndLocation = t.EndLocation; 
		} else if (la.kind == 51) {
			lexer.NextToken();

#line  1922 "cs.ATG" 
			pexpr = new BaseReferenceExpression(); pexpr.StartLocation = t.Location; pexpr.EndLocation = t.EndLocation; 
		} else if (la.kind == 89) {
			NewExpression(
#line  1925 "cs.ATG" 
out pexpr);
		} else if (la.kind == 115) {
			lexer.NextToken();
			Expect(20);
			if (
#line  1929 "cs.ATG" 
NotVoidPointer()) {
				Expect(123);

#line  1929 "cs.ATG" 
				type = new TypeReference("System.Void", true); 
			} else if (StartOf(10)) {
				TypeWithRestriction(
#line  1930 "cs.ATG" 
out type, true, true);
			} else SynErr(208);
			Expect(21);

#line  1932 "cs.ATG" 
			pexpr = new TypeOfExpression(type); 
		} else if (la.kind == 63) {
			lexer.NextToken();
			Expect(20);
			Type(
#line  1934 "cs.ATG" 
out type);
			Expect(21);

#line  1934 "cs.ATG" 
			pexpr = new DefaultValueExpression(type); 
		} else if (la.kind == 105) {
			lexer.NextToken();
			Expect(20);
			Type(
#line  1935 "cs.ATG" 
out type);
			Expect(21);

#line  1935 "cs.ATG" 
			pexpr = new SizeOfExpression(type); 
		} else if (la.kind == 58) {
			lexer.NextToken();
			Expect(20);
			Expr(
#line  1936 "cs.ATG" 
out expr);
			Expect(21);

#line  1936 "cs.ATG" 
			pexpr = new CheckedExpression(expr); 
		} else if (la.kind == 118) {
			lexer.NextToken();
			Expect(20);
			Expr(
#line  1937 "cs.ATG" 
out expr);
			Expect(21);

#line  1937 "cs.ATG" 
			pexpr = new UncheckedExpression(expr); 
		} else if (la.kind == 64) {
			lexer.NextToken();
			AnonymousMethodExpr(
#line  1938 "cs.ATG" 
out expr);

#line  1938 "cs.ATG" 
			pexpr = expr; 
		} else SynErr(209);

#line  1940 "cs.ATG" 
		if (pexpr != null) {
		if (pexpr.StartLocation.IsEmpty)
			pexpr.StartLocation = startLocation;
		if (pexpr.EndLocation.IsEmpty)
			pexpr.EndLocation = t.EndLocation;
		}
		
		while (StartOf(36)) {
			if (la.kind == 31 || la.kind == 32) {

#line  1948 "cs.ATG" 
				startLocation = la.Location; 
				if (la.kind == 31) {
					lexer.NextToken();

#line  1950 "cs.ATG" 
					pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostIncrement); 
				} else if (la.kind == 32) {
					lexer.NextToken();

#line  1951 "cs.ATG" 
					pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostDecrement); 
				} else SynErr(210);
			} else if (la.kind == 47) {
				PointerMemberAccess(
#line  1954 "cs.ATG" 
out pexpr, pexpr);
			} else if (la.kind == 15) {
				MemberAccess(
#line  1955 "cs.ATG" 
out pexpr, pexpr);
			} else if (la.kind == 20) {
				lexer.NextToken();

#line  1959 "cs.ATG" 
				List<Expression> parameters = new List<Expression>(); 

#line  1960 "cs.ATG" 
				pexpr = new InvocationExpression(pexpr, parameters); 
				if (StartOf(26)) {
					Argument(
#line  1961 "cs.ATG" 
out expr);

#line  1961 "cs.ATG" 
					SafeAdd(pexpr, parameters, expr); 
					while (la.kind == 14) {
						lexer.NextToken();
						Argument(
#line  1962 "cs.ATG" 
out expr);

#line  1962 "cs.ATG" 
						SafeAdd(pexpr, parameters, expr); 
					}
				}
				Expect(21);
			} else {

#line  1968 "cs.ATG" 
				List<Expression> indices = new List<Expression>();
				pexpr = new IndexerExpression(pexpr, indices);
				
				lexer.NextToken();
				Expr(
#line  1971 "cs.ATG" 
out expr);

#line  1971 "cs.ATG" 
				SafeAdd(pexpr, indices, expr); 
				while (la.kind == 14) {
					lexer.NextToken();
					Expr(
#line  1972 "cs.ATG" 
out expr);

#line  1972 "cs.ATG" 
					SafeAdd(pexpr, indices, expr); 
				}
				Expect(19);

#line  1975 "cs.ATG" 
				if (pexpr != null) {
				pexpr.StartLocation = startLocation;
				pexpr.EndLocation = t.EndLocation;
				}
				
			}
		}
	}
Ejemplo n.º 15
0
				public override void VisitIndexerExpression (IndexerExpression indexerExpression)
				{
					base.VisitIndexerExpression (indexerExpression);

					var tr = GetTypeRef (indexerExpression.Target);

					if (tr != null && (tr.IsArray || tr.FullName == "System.String"))
						return;

					var t = indexerExpression.Target;

					var pa = indexerExpression.Parent as AssignmentExpression;

					if (pa != null && pa.Left == indexerExpression) {

						var s = new InvocationExpression (
							new MemberReferenceExpression (t.Clone(), "set_Item"),
							indexerExpression.Arguments.Concat (new[]{pa.Right.Clone()}).Select (x => x.Clone ()));

						pa.ReplaceWith (s);



					} else {

						var s = new InvocationExpression (
							new MemberReferenceExpression (t.Clone(), "get_Item"),
							indexerExpression.Arguments.Select (x => x.Clone ()));

						indexerExpression.ReplaceWith (s);
					}
					Changed = true;
				}
Ejemplo n.º 16
0
		public virtual object VisitIndexerExpression(IndexerExpression indexerExpression, object data) {
			Debug.Assert((indexerExpression != null));
			Debug.Assert((indexerExpression.TargetObject != null));
			Debug.Assert((indexerExpression.Indexes != null));
			indexerExpression.TargetObject.AcceptVisitor(this, data);
			foreach (Expression o in indexerExpression.Indexes) {
				Debug.Assert(o != null);
				o.AcceptVisitor(this, data);
			}
			return null;
		}
Ejemplo n.º 17
0
 public JsNode VisitIndexerExpression(IndexerExpression node)
 {
     return(Visit(node.Resolve()));
 }
Ejemplo n.º 18
0
 public virtual void VisitIndexerExpression(IndexerExpression expression)
 {
     VisitAbstractExpression(expression);
 }
Ejemplo n.º 19
0
 public StrideReplaceExtern(Variable variable, IndexerExpression expression)
     : base(false, true)
 {
     VariableToReplace  = variable;
     IndexerReplacement = expression;
 }
Ejemplo n.º 20
0
            public override void VisitInvocationExpression(InvocationExpression invocationExpression)
            {
                InvocationExpression outerInvocationExpression = invocationExpression;
                //Note the invocations are in reverse order, so x.Foo().Bar() will have [0] be the Bar() and [1] be the Foo()
                List <InvocationExpression> invocations = new List <InvocationExpression>();
                LinqMethod outerMethod = null;
                Expression target      = null;

                for (;;)
                {
                    var resolveResult = ctx.Resolve(invocationExpression) as MemberResolveResult;
                    if (resolveResult == null || !(resolveResult.Member is IMethod))
                    {
                        break;
                    }

                    var method = LinqMethods.FirstOrDefault(candidate => candidate.FullName == resolveResult.Member.FullName &&
                                                            candidate.ParameterCount == ((IMethod)resolveResult.Member.MemberDefinition).Parameters.Count);
                    if (method == null || (invocations.Any() && method.IsLast))
                    {
                        break;
                    }

                    var mre = invocationExpression.Target as MemberReferenceExpression;
                    if (mre == null)
                    {
                        break;
                    }

                    if (outerMethod == null)
                    {
                        outerMethod = method;
                    }
                    invocations.Add(invocationExpression);

                    target = mre.Target;

                    var newInvocation = target as InvocationExpression;
                    if (newInvocation == null)
                    {
                        break;
                    }

                    invocationExpression = newInvocation;
                }

                if (target == null)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }
                if (!outerMethod.IsPoorStyleAlone && invocations.Count == 1)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                var currentTypeDeclaration   = outerInvocationExpression.GetParent <TypeDeclaration>();
                var currentTypeResolveResult = ctx.Resolve(currentTypeDeclaration) as TypeResolveResult;

                if (currentTypeResolveResult == null)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                var currentTypeDefinition = currentTypeResolveResult.Type.GetDefinition();

                var targetResolveResult = ctx.Resolve(target);

                if (!CanIndex(currentTypeDefinition, targetResolveResult))
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                string countPropertyName = GetCountProperty(currentTypeDefinition, targetResolveResult);

                string lastInvocationName = ((MemberReferenceExpression)invocations[0].Target).MemberName;

                bool endsReversed  = invocations.Count(invocation => ((MemberReferenceExpression)invocation.Target).MemberName == "Reverse") % 2 != 0;
                bool requiresCount = lastInvocationName == "Count" || lastInvocationName == "Any" ||
                                     (endsReversed ? lastInvocationName == "First" || lastInvocationName == "ElementAt" : lastInvocationName == "Last");

                if (countPropertyName == null && requiresCount)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                AddIssue(new CodeIssue(invocations.Last().LParToken.StartLocation,
                                       invocations.First().RParToken.EndLocation,
                                       ctx.TranslateString("Use of Linq method when there's a better alternative"),
                                       ctx.TranslateString("Replace method by simpler version"),
                                       script => {
                    Expression startOffset = null;
                    Expression endOffset   = null;

                    bool reversed = false;
                    foreach (var invocation in invocations.AsEnumerable().Reverse())
                    {
                        string invocationName = ((MemberReferenceExpression)invocation.Target).MemberName;

                        switch (invocationName)
                        {
                        case "Skip":
                            Expression offset = reversed ? endOffset : startOffset;
                            if (offset == null)
                            {
                                offset = invocation.Arguments.Last().Clone();
                            }
                            else
                            {
                                offset = new BinaryOperatorExpression(offset,
                                                                      BinaryOperatorType.Add,
                                                                      invocation.Arguments.Last().Clone());
                            }

                            if (reversed)
                            {
                                endOffset = offset;
                            }
                            else
                            {
                                startOffset = offset;
                            }

                            break;

                        case "Reverse":
                            reversed = !reversed;
                            break;

                        case "First":
                        case "ElementAt":
                        case "Last":
                            {
                                bool fromEnd          = (invocationName == "Last") ^ reversed;
                                Expression index      = invocationName == "ElementAt" ? invocation.Arguments.Last().Clone() : null;
                                Expression baseOffset = fromEnd ? endOffset : startOffset;
                                //Our indexWithOffset is baseOffset + index
                                //A baseOffset/index of null is considered "0".

                                Expression indexWithOffset = baseOffset == null ? index :
                                                             index == null ? baseOffset :
                                                             new BinaryOperatorExpression(baseOffset, BinaryOperatorType.Add, index);

                                Expression indexerExpression = indexWithOffset;
                                if (fromEnd)
                                {
                                    var endExpression = new BinaryOperatorExpression(new MemberReferenceExpression(target.Clone(), countPropertyName),
                                                                                     BinaryOperatorType.Subtract,
                                                                                     new PrimitiveExpression(1));
                                    if (indexerExpression == null)
                                    {
                                        indexerExpression = endExpression;
                                    }
                                    else
                                    {
                                        indexerExpression = new BinaryOperatorExpression(endExpression,
                                                                                         BinaryOperatorType.Subtract,
                                                                                         new ParenthesizedExpression(indexerExpression));
                                    }
                                }

                                indexerExpression = indexerExpression ?? new PrimitiveExpression(0);

                                var newExpression = new IndexerExpression(target.Clone(),
                                                                          indexerExpression);

                                script.Replace(outerInvocationExpression, newExpression);
                                break;
                            }

                        case "Count":
                        case "Any":
                            {
                                Expression takenMembers;
                                if (startOffset == null)
                                {
                                    takenMembers = endOffset;
                                }
                                else if (endOffset == null)
                                {
                                    takenMembers = startOffset;
                                }
                                else
                                {
                                    takenMembers = new BinaryOperatorExpression(startOffset,
                                                                                BinaryOperatorType.Add,
                                                                                endOffset);
                                }

                                var countExpression = new MemberReferenceExpression(target.Clone(), countPropertyName);

                                Expression newExpression;
                                if (invocationName == "Count")
                                {
                                    if (takenMembers == null)
                                    {
                                        newExpression = countExpression;
                                    }
                                    else
                                    {
                                        newExpression = new BinaryOperatorExpression(countExpression,
                                                                                     BinaryOperatorType.Subtract,
                                                                                     new ParenthesizedExpression(takenMembers));
                                    }
                                }
                                else
                                {
                                    newExpression = new BinaryOperatorExpression(countExpression,
                                                                                 BinaryOperatorType.GreaterThan,
                                                                                 new ParenthesizedExpression(takenMembers));
                                }

                                script.Replace(outerInvocationExpression, newExpression);
                                break;
                            }
                        }
                    }
                }));

                base.VisitInvocationExpression(invocationExpression);
            }
 public override StringBuilder VisitIndexerExpression(IndexerExpression indexerExpression, int data)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 22
0
        // Expressions
        bool Expression(out ITTEExpression expr, bool root = true)
        {
            expr = null;

            // Group
            if (Match("("))
            {
                ContainExpression(out expr);
                Match(")");
            }
            // Number
            else if (Number(out expr))
            {
            }
            // String
            else if (WorkshopString(out expr))
            {
            }
            // Enum value
            else if (EnumeratorValue(out expr))
            {
            }
            // Variable
            else if (GlobalVariable(out expr))
            {
            }
            // Legacy
            else if (LegacyExpression(out expr))
            {
            }
            // Function
            else if (Function(false, out FunctionExpression value))
            {
                expr = value;
            }
            // Unary operator
            else if (MatchUnary(out TTEOperator unaryOperator))
            {
                PushOperator(unaryOperator);
                Expression(out expr);
            }
            // No matches
            else
            {
                return(false);
            }

            // Array index
            while (VariableIndex(out ITTEExpression index))
            {
                expr = new IndexerExpression(expr, index);
            }

            // Player variable
            if (MatchPlayerVariable(expr, out ITTEExpression playerVariable))
            {
                expr = playerVariable;
            }

            // Push the expression
            _operands.Push(expr);

            // Binary operator
            while (MatchOperator(out TTEOperator op))
            {
                PushOperator(op);
                Expression(out ITTEExpression right, false);
            }
            while (_operators.Peek().Precedence > 0)
            {
                PopOperator();
            }

            // If this is the root, return the top operand.
            if (root)
            {
                expr = _operands.Pop();
            }

            return(true);
        }
Ejemplo n.º 23
0
 public void VisitIndexerExpression(IndexerExpression expression)
 {
     Formatter.StartNode(expression);
     expression.Target.AcceptVisitor(this);
     Formatter.WriteToken("[");
     WriteCommaSeparatedNodes(expression.Indices);
     Formatter.WriteToken("]");
     Formatter.EndNode();
 }
 public override void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     HandleExpressionNode(indexerExpression);
 }
Ejemplo n.º 25
0
		public override void VisitIndexerExpression(IndexerExpression indexerExpression)
		{
			ParenthesizeIfRequired(indexerExpression.Target, Primary);
			ArrayCreateExpression ace = indexerExpression.Target as ArrayCreateExpression;
			if (ace != null && (InsertParenthesesForReadability || ace.Initializer.IsNull)) {
				// require parentheses for "(new int[1])[0]"
				Parenthesize(indexerExpression.Target);
			}
			base.VisitIndexerExpression(indexerExpression);
		}
Ejemplo n.º 26
0
 IEnumerable <Syntax> IAstVisitor <ILTranslationContext, IEnumerable <Syntax> > .VisitIndexerExpression(IndexerExpression indexerExpression, ILTranslationContext data)
 => OnVisiting(data, indexerExpression, VisitingIndexerExpression)
 ?? OnVisited(data, indexerExpression, VisitedIndexerExpression, TranslateIndexerExpression(indexerExpression, data));
Ejemplo n.º 27
0
        public void VisitIndexerExpression(IndexerExpression indexerExpression)
        {
            JsonObject expression = CreateJsonExpression(indexerExpression);

            expression.AddJsonValue("target", GenExpression(indexerExpression.Target));
            expression.AddJsonValue("arguments", GetCommaSeparatedList(indexerExpression.Arguments));
            Push(expression);
        }
Ejemplo n.º 28
0
        protected void VisitIndexerExpression()
        {
            IndexerExpression indexerExpression = this.IndexerExpression;

            IAttribute inlineAttr          = null;
            var        resolveResult       = this.Emitter.Resolver.ResolveNode(indexerExpression, this.Emitter);
            var        memberResolveResult = resolveResult as MemberResolveResult;

            var arrayAccess = resolveResult as ArrayAccessResolveResult;

            if (arrayAccess != null && arrayAccess.Indexes.Count > 1)
            {
                this.EmitArrayAccess(indexerExpression);
                return;
            }

            var       isIgnore        = true;
            var       ignoreAccessor  = false;
            IProperty member          = null;
            IMethod   method          = null;
            var       oldIsAssignment = this.Emitter.IsAssignment;
            var       oldUnary        = this.Emitter.IsUnaryAccessor;

            if (memberResolveResult != null)
            {
                var resolvedMember = memberResolveResult.Member;
                isIgnore = this.Emitter.Validator.IsIgnoreType(resolvedMember.DeclaringTypeDefinition);

                if (resolvedMember is IProperty)
                {
                    member         = (IProperty)resolvedMember;
                    method         = this.Emitter.IsAssignment ? member.Setter : member.Getter;
                    inlineAttr     = this.Emitter.GetAttribute(method.Attributes, Translator.Bridge_ASSEMBLY + ".TemplateAttribute");
                    ignoreAccessor = this.Emitter.Validator.HasAttribute(method.Attributes, "Bridge.IgnoreAttribute");
                }
            }

            if (inlineAttr != null || isIgnore)
            {
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                indexerExpression.Target.AcceptVisitor(this.Emitter);
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
            }

            if (inlineAttr != null)
            {
                var inlineCode = inlineAttr.PositionalArguments[0];

                if (inlineCode.ConstantValue != null)
                {
                    string code = inlineCode.ConstantValue.ToString();

                    this.WriteDot();
                    this.PushWriter(code);
                    new ExpressionListBlock(this.Emitter, indexerExpression.Arguments, null).Emit();

                    if (!this.Emitter.IsAssignment)
                    {
                        this.PopWriter();
                    }
                    else
                    {
                        this.WriteComma();
                    }
                }
            }
            else if (!(isIgnore || ignoreAccessor))
            {
                string targetVar      = null;
                string valueVar       = null;
                bool   writeTargetVar = false;
                bool   isStatement    = false;

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

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

                    if (memberResolveResult != null && NullableType.IsNullable(memberResolveResult.Type))
                    {
                        isStatement = false;
                    }

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

                if (writeTargetVar)
                {
                    var  targetrr       = this.Emitter.Resolver.ResolveNode(indexerExpression.Target, this.Emitter);
                    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 (this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
                {
                    valueVar = this.GetTempVarName();

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

                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                indexerExpression.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);
                    }
                }

                this.WriteDot();
                var argsInfo        = new ArgumentsInfo(this.Emitter, indexerExpression);
                var argsExpressions = argsInfo.ArgumentsExpressions;
                var paramsArg       = argsInfo.ParamsExpression;
                var name            = Helpers.GetPropertyRef(member, this.Emitter, this.Emitter.IsAssignment);

                if (!this.Emitter.IsAssignment)
                {
                    if (this.Emitter.IsUnaryAccessor)
                    {
                        var oldWriter = this.SaveWriter();
                        this.NewWriter();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        var paramsStr = this.Emitter.Output.ToString();
                        this.RestoreWriter(oldWriter);

                        if (isStatement)
                        {
                            this.Write(Helpers.GetPropertyRef(member, this.Emitter, true));
                            this.WriteOpenParentheses();
                            this.Write(paramsStr);
                            this.WriteComma(false);

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

                            this.WriteDot();

                            this.Write(Helpers.GetPropertyRef(member, this.Emitter, false));
                            this.WriteOpenParentheses();
                            this.Write(paramsStr);
                            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, this.Emitter, false));
                            this.WriteOpenParentheses();
                            this.Write(paramsStr);
                            this.WriteCloseParentheses();
                            this.WriteComma();

                            if (targetVar != null)
                            {
                                this.Write(targetVar);
                            }
                            else
                            {
                                indexerExpression.Target.AcceptVisitor(this.Emitter);
                            }
                            this.WriteDot();
                            this.Write(Helpers.GetPropertyRef(member, this.Emitter, true));
                            this.WriteOpenParentheses();
                            this.Write(paramsStr);
                            this.WriteComma(false);
                            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(name);
                        this.WriteOpenParentheses();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.WriteCloseParentheses();
                    }
                }
                else
                {
                    if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                    {
                        var oldWriter = this.SaveWriter();
                        this.NewWriter();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        var paramsStr = this.Emitter.Output.ToString();
                        this.RestoreWriter(oldWriter);

                        if (targetVar != null)
                        {
                            this.PushWriter(string.Concat(
                                                name,
                                                "(",
                                                paramsStr,
                                                ", ",
                                                targetVar,
                                                ".",
                                                Helpers.GetPropertyRef(member, this.Emitter, false),
                                                "(",
                                                paramsStr,
                                                "){0})"));

                            this.RemoveTempVar(targetVar);
                        }
                        else
                        {
                            oldWriter = this.SaveWriter();
                            this.NewWriter();

                            this.Emitter.IsAssignment    = false;
                            this.Emitter.IsUnaryAccessor = false;
                            indexerExpression.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(
                                                name,
                                                "(",
                                                paramsStr,
                                                ", ",
                                                trg,
                                                ".",
                                                Helpers.GetPropertyRef(member, this.Emitter, false),
                                                "(",
                                                paramsStr,
                                                "){0})"));
                        }
                    }
                    else
                    {
                        this.Write(name);
                        this.WriteOpenParentheses();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.PushWriter(", {0})");
                    }
                }
            }
            else
            {
                if (indexerExpression.Arguments.Count != 1)
                {
                    throw new EmitterException(indexerExpression, "Only one index is supported");
                }

                var index = indexerExpression.Arguments.First();

                var primitive = index as PrimitiveExpression;

                if (primitive != null && primitive.Value != null && Regex.Match(primitive.Value.ToString(), "^[_$a-z][_$a-z0-9]*$", RegexOptions.IgnoreCase).Success)
                {
                    this.WriteDot();
                    this.Write(primitive.Value);
                }
                else
                {
                    this.WriteOpenBracket();
                    index.AcceptVisitor(this.Emitter);
                    this.WriteCloseBracket();
                }
            }
        }
Ejemplo n.º 29
0
		public void VisitIndexerExpression(IndexerExpression indexerExpression)
		{
			StartNode(indexerExpression);
			indexerExpression.Target.AcceptVisitor(this);
			Space(policy.SpaceBeforeMethodCallParentheses);
			WriteCommaSeparatedListInBrackets(indexerExpression.Arguments);
			EndNode(indexerExpression);
		}
Ejemplo n.º 30
0
 public override void Accept(IndexerExpression indexer)
 {
     indexer.Visit(parentVisitor);
 }
Ejemplo n.º 31
0
        protected virtual void EmitInlineIndexer(IndexerExpression indexerExpression, IndexerAccessor current)
        {
            var  oldIsAssignment = this.Emitter.IsAssignment;
            var  oldUnary        = this.Emitter.IsUnaryAccessor;
            var  inlineCode      = current.InlineCode;
            bool hasThis         = inlineCode != null && inlineCode.Contains("{this}");

            if (inlineCode != null && inlineCode.StartsWith("<self>"))
            {
                hasThis    = true;
                inlineCode = inlineCode.Substring(6);
            }

            if (!hasThis && current.InlineAttr != null)
            {
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                indexerExpression.Target.AcceptVisitor(this.Emitter);
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;
            }

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

                this.PushWriter(inlineCode);
                new ExpressionListBlock(this.Emitter, indexerExpression.Arguments, null).Emit();

                if (!this.Emitter.IsAssignment)
                {
                    this.PopWriter();
                }
                else
                {
                    this.WriteComma();
                }

                return;
            }

            if (inlineCode != null)
            {
                this.WriteDot();
                this.PushWriter(inlineCode);
                this.Emitter.IsAssignment    = false;
                this.Emitter.IsUnaryAccessor = false;
                new ExpressionListBlock(this.Emitter, indexerExpression.Arguments, null).Emit();
                this.Emitter.IsAssignment    = oldIsAssignment;
                this.Emitter.IsUnaryAccessor = oldUnary;

                if (!this.Emitter.IsAssignment)
                {
                    this.PopWriter();
                }
                else
                {
                    this.WriteComma();
                }
            }
        }
        // ********************************************************************************************************************************

        /// <summary>
        /// Tries to infer the resource key being referenced from the given expression.
        /// </summary>
        static string GetKeyFromExpression(Expression expr, out bool isPrefixOnly)
        {
            isPrefixOnly = false;
                        #if DEBUG
            LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver trying to get key from expression: " + expr.ToString());
                        #endif

            IndexerExpression indexer = expr as IndexerExpression;
            if (indexer != null)
            {
                foreach (Expression index in indexer.Indexes)
                {
                    PrimitiveExpression p = index as PrimitiveExpression;
                    if (p != null)
                    {
                        string key = p.Value as string;
                        if (key != null)
                        {
                                                        #if DEBUG
                            LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found key: " + key);
                                                        #endif
                            return(key);
                        }
                    }
                }
            }

            InvocationExpression invocation = expr as InvocationExpression;
            if (invocation != null)
            {
                MemberReferenceExpression fre = invocation.TargetObject as MemberReferenceExpression;
                if (fre != null)
                {
                    if (fre.MemberName == "GetString" || fre.MemberName == "GetObject" || fre.MemberName == "GetStream")
                    {
                        if (invocation.Arguments.Count > 0)
                        {
                            PrimitiveExpression p = invocation.Arguments[0] as PrimitiveExpression;
                            if (p != null)
                            {
                                string key = p.Value as string;
                                if (key != null)
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found key: " + key);
                                                                        #endif
                                    return(key);
                                }
                            }
                        }
                    }
                    else if (fre.MemberName == "ApplyResources")
                    {
                        if (invocation.Arguments.Count >= 2)
                        {
                            PrimitiveExpression p = invocation.Arguments[1] as PrimitiveExpression;
                            if (p != null)
                            {
                                string key = p.Value as string;
                                if (key != null)
                                {
                                                                        #if DEBUG
                                    LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found key prefix: " + key);
                                                                        #endif
                                    isPrefixOnly = true;
                                    return(key);
                                }
                            }
                        }
                    }
                }
            }

            return(null);
        }
Ejemplo n.º 33
0
        protected virtual void EmitMultiDimArrayAccess(IndexerExpression indexerExpression)
        {
            string targetVar      = null;
            bool   writeTargetVar = false;
            bool   isStatement    = false;
            string valueVar       = null;
            var    resolveResult  = this.Emitter.Resolver.ResolveNode(indexerExpression, this.Emitter);

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

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

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

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

            if (writeTargetVar)
            {
                var  targetrr       = this.Emitter.Resolver.ResolveNode(indexerExpression.Target, this.Emitter);
                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 (this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
            {
                valueVar = this.GetTempVarName();

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

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

            this.Emitter.IsAssignment    = false;
            this.Emitter.IsUnaryAccessor = false;
            indexerExpression.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);
                }
            }

            if (this.isRefArg)
            {
                this.WriteComma();
            }
            else
            {
                this.WriteDot();
            }


            var argsInfo        = new ArgumentsInfo(this.Emitter, indexerExpression);
            var argsExpressions = argsInfo.ArgumentsExpressions;
            var paramsArg       = argsInfo.ParamsExpression;

            if (!this.Emitter.IsAssignment)
            {
                if (this.Emitter.IsUnaryAccessor)
                {
                    bool isDecimal  = Helpers.IsDecimalType(resolveResult.Type, this.Emitter.Resolver);
                    bool isLong     = Helpers.Is64Type(resolveResult.Type, this.Emitter.Resolver);
                    bool isNullable = NullableType.IsNullable(resolveResult.Type);

                    if (isStatement)
                    {
                        this.Write("set");
                        this.WriteOpenParentheses();
                        this.WriteOpenBracket();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.WriteCloseBracket();
                        this.WriteComma(false);

                        if (isDecimal || isLong)
                        {
                            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
                                {
                                    indexerExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    indexerExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteDot();
                                if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    this.Write("inc");
                                }
                                else
                                {
                                    this.Write("dec");
                                }

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

                            this.WriteDot();

                            this.Write("get");
                            this.WriteOpenParentheses();
                            this.WriteOpenBracket();
                            new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                            this.WriteCloseBracket();
                            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("get");
                        this.WriteOpenParentheses();
                        this.WriteOpenBracket();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.WriteCloseBracket();
                        this.WriteCloseParentheses();
                        this.WriteComma();

                        if (targetVar != null)
                        {
                            this.Write(targetVar);
                        }
                        else
                        {
                            indexerExpression.Target.AcceptVisitor(this.Emitter);
                        }
                        this.WriteDot();
                        this.Write("set");
                        this.WriteOpenParentheses();
                        this.WriteOpenBracket();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.WriteCloseBracket();
                        this.WriteComma(false);

                        if (isDecimal || isLong)
                        {
                            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.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    indexerExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteDot();
                                if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                    this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    this.Write("inc");
                                }
                                else
                                {
                                    this.Write("dec");
                                }

                                this.WriteOpenCloseParentheses();
                            }
                        }
                        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();

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

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

                            this.WriteDot();

                            this.Write("get");
                            this.WriteOpenParentheses();
                            this.WriteOpenBracket();
                            new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                            this.WriteCloseBracket();
                            this.WriteCloseParentheses();
                        }
                        else
                        {
                            this.Write(valueVar);
                        }

                        this.WriteCloseParentheses();

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

                    if (targetVar != null)
                    {
                        this.RemoveTempVar(targetVar);
                    }
                }
                else
                {
                    if (!this.isRefArg)
                    {
                        this.Write("get");
                        this.WriteOpenParentheses();
                    }

                    this.WriteOpenBracket();
                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                    this.WriteCloseBracket();
                    if (!this.isRefArg)
                    {
                        this.WriteCloseParentheses();
                    }
                }
            }
            else
            {
                if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                {
                    var oldWriter = this.SaveWriter();
                    this.NewWriter();
                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                    var paramsStr = this.Emitter.Output.ToString();
                    this.RestoreWriter(oldWriter);

                    if (targetVar != null)
                    {
                        this.PushWriter(string.Concat(
                                            "set([",
                                            paramsStr,
                                            "],",
                                            targetVar,
                                            ".get([",
                                            paramsStr,
                                            "]){0})"), () =>
                        {
                            this.RemoveTempVar(targetVar);
                        });
                    }
                    else
                    {
                        oldWriter = this.SaveWriter();
                        this.NewWriter();

                        this.Emitter.IsAssignment    = false;
                        this.Emitter.IsUnaryAccessor = false;
                        indexerExpression.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(
                                            "set([",
                                            paramsStr,
                                            "],",
                                            trg,
                                            ".get([",
                                            paramsStr,
                                            "]){0})"));
                    }
                }
                else
                {
                    this.Write("set");
                    this.WriteOpenParentheses();
                    this.WriteOpenBracket();
                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                    this.WriteCloseBracket();
                    this.PushWriter(", {0})");
                }
            }
        }
Ejemplo n.º 34
0
            protected Expression VisitIndexer(IndexerExpression node)
            {
                _expressionInProgress.Enqueue(new MemberFragment(_fieldMapper, node.Target.Value.ToString()));

                return(node);
            }
Ejemplo n.º 35
0
 public void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 36
0
 public override StringBuilder VisitIndexerExpression(IndexerExpression indexerExpression, int data)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 37
0
 public override void Accept(IndexerExpression indexer)
 {
     indexer.Visit(functionCompiler);
 }
Ejemplo n.º 38
0
        private VariableInitializer TransformMapDefinitionFromLinqQuerySyntax(string query, out string entityName)
        {
            entityName = null;
            var variableDeclaration = QueryParsingUtils.GetVariableDeclarationForLinqQuery(query, RequiresSelectNewAnonymousType);
            var queryExpression     = ((QueryExpression)variableDeclaration.Initializer);
            var fromClause          = queryExpression.Clauses.OfType <QueryFromClause>().First();
            var expression          = fromClause.Expression;

            if (expression is MemberReferenceExpression)             // collection
            {
                var mre = (MemberReferenceExpression)expression;
                entityName            = mre.MemberName;
                fromClause.Expression = mre.Target;
                //doc["@metadata"]["Raven-Entity-Name"]
                var metadata = new IndexerExpression(
                    new IndexerExpression(new IdentifierExpression(fromClause.Identifier), new List <Expression> {
                    new StringLiteralExpression("@metadata")
                }),
                    new List <Expression> {
                    new StringLiteralExpression(Constants.RavenEntityName)
                }
                    );

                // string.Equals(doc["@metadata"]["Raven-Entity-Name"], "Blogs", StringComparison.InvariantCultureIgnoreCase)
                var binaryOperatorExpression =
                    new InvocationExpression(
                        new MemberReferenceExpression(new TypeReferenceExpression(new PrimitiveType("string")), "Equals"),
                        new List <Expression>
                {
                    metadata,
                    new StringLiteralExpression(mre.MemberName),
                    new MemberReferenceExpression(new TypeReferenceExpression(new SimpleType(typeof(StringComparison).FullName)), "InvariantCultureIgnoreCase")
                });

                queryExpression.Clauses.InsertAfter(fromClause,
                                                    new QueryWhereClause
                {
                    Condition = binaryOperatorExpression
                });
            }
            var projection =
                QueryParsingUtils.GetAnonymousCreateExpression(
                    queryExpression.Clauses.OfType <QuerySelectClause>().First().Expression);

            var anonymousTypeCreateExpression = projection as AnonymousTypeCreateExpression;

            if (anonymousTypeCreateExpression == null)
            {
                return(variableDeclaration);
            }

            var objectInitializer = anonymousTypeCreateExpression.Initializers;

            var identifierExpression = new IdentifierExpression(fromClause.Identifier);

            if (objectInitializer.OfType <NamedExpression>().Any(x => x.Name == Constants.DocumentIdFieldName))
            {
                return(variableDeclaration);
            }

            objectInitializer.Add(
                new NamedExpression
            {
                Name       = Constants.DocumentIdFieldName,
                Expression = new MemberReferenceExpression(identifierExpression, Constants.DocumentIdFieldName)
            });
            return(variableDeclaration);
        }
Ejemplo n.º 39
0
 public virtual object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
 {
     throw new global::System.NotImplementedException("IndexerExpression");
 }
 public override void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     base.VisitIndexerExpression(indexerExpression);
     CheckParameters(ctx.Resolve(indexerExpression), indexerExpression.Arguments);
 }
Ejemplo n.º 41
0
 public override void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     new IndexerBlock(this, indexerExpression).Emit();
 }
Ejemplo n.º 42
0
 public virtual void Accept(IndexerExpression indexer)
 {
 }
Ejemplo n.º 43
0
        public override object Visit(IndexerExpression indexerExpression, object data)
        {
            IReturnType type = (IReturnType)indexerExpression.TargetObject.AcceptVisitor(this, data);
            if (type == null) {
                return null;
            }
            if (type.ArrayDimensions == null || type.ArrayDimensions.Length == 0) {
                // check if ther is an indexer
                if (indexerExpression.TargetObject is ThisReferenceExpression) {
                    if (resolver.CallingClass == null) {
                        return null;
                    }
                    type = new ReturnType(resolver.CallingClass.FullyQualifiedName);
                }
                ArrayList indexer = resolver.SearchIndexer(type);
                if (indexer.Count == 0) {
                    return null;
                }
                // TODO: get the right indexer
                return ((IIndexer)indexer[0]).ReturnType;
            }

            // TODO: what is a[0] if a is pointer to array or array of pointer ?
            if (type.ArrayDimensions[type.ArrayDimensions.Length - 1] != indexerExpression.Indices.Count) {
                return null;
            }
            int[] newArray = new int[type.ArrayDimensions.Length - 1];
            Array.Copy(type.ArrayDimensions, 0, newArray, 0, type.ArrayDimensions.Length - 1);
            return new ReturnType(type.Name, newArray, type.PointerNestingLevel);
        }
Ejemplo n.º 44
0
 public abstract StringBuilder VisitIndexerExpression(IndexerExpression indexerExpression, int data);
Ejemplo n.º 45
0
 public void VisitIndexerExpression(IndexerExpression indexExpr)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 46
0
 public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
 {
     return(base.VisitIndexerExpression(indexerExpression, data));
 }
Ejemplo n.º 47
0
		public override void VisitIndexerExpression(IndexerExpression indexerExpression)
		{
			ForceSpacesBefore(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets);
			ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets);
			ForceSpacesBefore(indexerExpression.RBracketToken, policy.SpacesWithinBrackets);
			FormatCommas(indexerExpression, policy.SpaceBeforeBracketComma, policy.SpaceAfterBracketComma);

			base.VisitIndexerExpression(indexerExpression);
		}
Ejemplo n.º 48
0
 public IndexerBlock(IEmitter emitter, IndexerExpression indexerExpression)
     : base(emitter, indexerExpression)
 {
     this.Emitter = emitter;
     this.IndexerExpression = indexerExpression;
 }
 public virtual void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     if (this.ThrowException)
     {
         throw (Exception)this.CreateException(indexerExpression);
     }
 }
Ejemplo n.º 50
0
        // IMPORTANT NOTE:
        // The grammar consists of a few LALR(1) conflicts. These issues are, however, correctly handled, due to the fact that the grammar 
        // is defined in a specific order making the already added parser actions have precedence over the other.
        //
        // Known conflicts that are correctly handled:
        //
        // - ELSE:          Shift/Reduce conflict Dangling ELSE problem.  Lots of articles are around on the internet. 
        //                  The shift action is taken here.
        //
        // - CLOSE_PARENS:  Shift/Reduce conflict. This is due to the fact that the explicit cast expression is like the parenthesized 
        //                  expression. The shift action is taken here.
        //
        // - STAR:          Reduce/Reduce conflict, between VariableType -> TypeNameExpression and PrimaryExpression -> TypeNameExpression, 
        //                  due to the fact variable types can have '*', and look therefore like a binary operator expression. 
        //                  The first reduce action is taken here.

        public CSharpGrammar()
        {
            // Please let me know if there is a better way of tidying this :s

            TokenMapping.Add((int)ERROR, Error);

            #region Definitions to use later

            var statementList = new GrammarDefinition("StatementList");
            var statementListOptional = new GrammarDefinition("StatementListOptional",
                rule: null
                      | statementList);

            var blockStatement = new GrammarDefinition("BlockStatement");

            var variableDeclarator = new GrammarDefinition("VariableDeclarator");
            var variableDeclaratorList = new GrammarDefinition("VariableDeclaratorList");
            variableDeclaratorList.Rule = variableDeclarator
                                          | variableDeclaratorList
                                          + ToElement(COMMA)
                                          + variableDeclarator;
            var variableDeclaration = new GrammarDefinition("VariableDeclaration");
            var variableInitializer = new GrammarDefinition("VariableInitializer");
            var arrayInitializer = new GrammarDefinition("ArrayInitializer");
            var arrayInitializerOptional = new GrammarDefinition("ArrayInitializerOptional",
                rule: null | arrayInitializer);
            var identifierInsideBody = new GrammarDefinition("IdentifierInsideBody",
                rule: ToElement(IDENTIFIER),
                createNode: node => ToIdentifier(node.Children[0].Result));
            var identifierInsideBodyOptional = new GrammarDefinition("IdentifierInsideBodyOptional",
                rule: null | identifierInsideBody);

            variableDeclarator.Rule = identifierInsideBody
                                      | identifierInsideBody
                                      + ToElement(EQUALS)
                                      + variableInitializer;
            variableDeclarator.ComputeResult = node =>
            {
                var result = new VariableDeclarator((Identifier) node.Children[0].Result);
                if (node.Children.Count > 1)
                {
                    result.OperatorToken = (AstToken) node.Children[1].Result;
                    result.Value = (Expression) node.Children[2].Result;
                }
                return result;
            };

            var typeReference = new GrammarDefinition("TypeReference");

            var identifierExpression = new GrammarDefinition("IdentifierExpression",
                rule: identifierInsideBody,
                createNode: node => new IdentifierExpression((Identifier) node.Children[0].Result));

            var usingDirectiveListOptional = new GrammarDefinition("UsingDirectiveListOptional");

            #endregion

            #region Type References

            var namespaceOrTypeExpression = new GrammarDefinition("NamespaceOrTypeExpression");

            namespaceOrTypeExpression.Rule = identifierExpression |
                                             namespaceOrTypeExpression
                                             + ToElement(DOT)
                                             + ToElement(IDENTIFIER);

            namespaceOrTypeExpression.ComputeResult = node =>
            {
                if (node.Children.Count == 1)
                    return ToTypeReference((IConvertibleToType) node.Children[0].Result);
                var result = new MemberTypeReference();
                result.Target = (TypeReference) node.Children[0].Result;
                result.AddChild(AstNodeTitles.Accessor, node.Children[1].Result);
                result.Identifier = ToIdentifier(node.Children[2].Result);
                return result;
            };

            ComputeResultDelegate createPrimitiveTypeExpression = node =>
            {
                if (node.Children[0].Result is PrimitiveTypeReference)
                    return node.Children[0].Result;
                return new PrimitiveTypeReference
                {
                    Identifier = ToIdentifier(node.Children[0].Result),
                    PrimitiveType = CSharpLanguage.PrimitiveTypeFromString(((AstToken) node.Children[0].Result).Value)
                };
            };

            var integralType = new GrammarDefinition("IntegralType",
                rule: ToElement(SBYTE)
                      | ToElement(BYTE)
                      | ToElement(SHORT)
                      | ToElement(USHORT)
                      | ToElement(INT)
                      | ToElement(UINT)
                      | ToElement(LONG)
                      | ToElement(ULONG)
                      | ToElement(CHAR),
                createNode: createPrimitiveTypeExpression);

            var primitiveType = new GrammarDefinition("PrimitiveTypeExpression",
                rule: ToElement(OBJECT)
                      | ToElement(STRING)
                      | ToElement(BOOL)
                      | ToElement(DECIMAL)
                      | ToElement(FLOAT)
                      | ToElement(DOUBLE)
                      | ToElement(VOID)
                      | integralType,
                createNode: createPrimitiveTypeExpression);

            var dimensionSeparators = new GrammarDefinition("DimensionSeparators");
            dimensionSeparators.Rule = ToElement(COMMA)
                                       | dimensionSeparators + ToElement(COMMA);

            var rankSpecifier = new GrammarDefinition("RankSpecifier",
                rule: ToElement(OPEN_BRACKET) + ToElement(CLOSE_BRACKET)
                      | ToElement(OPEN_BRACKET) + dimensionSeparators
                      + ToElement(CLOSE_BRACKET),
                createNode: node =>
                {
                    var result = new ArrayTypeRankSpecifier();
                    result.LeftBracket = (AstToken) node.Children[0].Result;
                    if (node.Children.Count == 3)
                    {
                        foreach (var dimensionSeparator in node.Children[1].GetAllNodesFromListDefinition()
                            .Select(x => x.Result))
                        {
                            result.Dimensions++;
                            result.AddChild(AstNodeTitles.ElementSeparator, dimensionSeparator);
                        }
                    }
                    result.RightBracket = (AstToken) node.Children[node.Children.Count - 1].Result;
                    return result;
                });

            var arrayType = new GrammarDefinition("ArrayType",
                rule: typeReference
                      + rankSpecifier,
                createNode: node => new ArrayTypeReference()
                {
                    BaseType = (TypeReference) node.Children[0].Result,
                    RankSpecifier = (ArrayTypeRankSpecifier) node.Children[1].Result
                });

            var pointerType = new GrammarDefinition("PointerType",
                rule: typeReference
                      + ToElement(STAR),
                createNode: node => new PointerTypeReference()
                {
                    BaseType = (TypeReference) node.Children[0].Result,
                    PointerToken = (AstToken) node.Children[1].Result
                });

            var typeExpression = new GrammarDefinition("TypeExpression",
                rule: namespaceOrTypeExpression
                      | primitiveType);

            typeReference.Rule = typeExpression
                                 | arrayType
                                 | pointerType
                ;

            #endregion

            #region Expressions

            ComputeResultDelegate createBinaryOperatorExpression = node =>
            {
                if (node.Children.Count == 1)
                    return node.Children[0].Result;

                var result = new BinaryOperatorExpression();
                result.Left = (Expression) node.Children[0].Result;
                var operatorToken = (AstToken) (node.Children[1].Result ?? node.Children[1].Children[0].Result);
                result.Operator = CSharpLanguage.BinaryOperatorFromString(operatorToken.Value);
                result.OperatorToken = (AstToken) operatorToken;
                result.Right = (Expression) node.Children[2].Result;
                return result;
            };

            var expression = new GrammarDefinition("Expression");
            var expressionOptional = new GrammarDefinition("ExpressionOptional",
                rule: null
                      | expression);

            var primaryExpression = new GrammarDefinition("PrimaryExpression");

            var primitiveExpression = new GrammarDefinition("PrimitiveExpression",
                rule: ToElement(LITERAL)
                      | ToElement(TRUE)
                      | ToElement(FALSE)
                      | ToElement(NULL),
                createNode: node =>
                {
                    object interpretedValue;
                    node.Children[0].Result.UserData.TryGetValue("InterpretedValue", out interpretedValue);
                    var result = new PrimitiveExpression(interpretedValue, ((AstToken) node.Children[0].Result).Value, node.Children[0].Range);
                    return result;
                });

            var parenthesizedExpression = new GrammarDefinition("ParenthesizedExpression",
                rule: ToElement(OPEN_PARENS)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      | ToElement(OPEN_PARENS)
                      + Error
                      + ToElement(CLOSE_PARENS),
                createNode: node => new ParenthesizedExpression
                {
                    LeftParenthese = (AstToken) node.Children[0].Result,
                    Expression = (Expression) node.Children[1].Result,
                    RightParenthese = (AstToken) node.Children[2].Result,
                });

            var memberAccessorOperator = new GrammarDefinition("MemberAccessorOperator",
                rule: ToElement(DOT)
                      | ToElement(OP_PTR)
                      | ToElement(INTERR_OPERATOR));

            var memberReferenceExpression = new GrammarDefinition("MemberReferenceExpression",
                rule: primaryExpression + memberAccessorOperator + identifierInsideBody
                | primaryExpression + memberAccessorOperator + Error,
                createNode: node => new MemberReferenceExpression
                {
                    Target =
                        (Expression)
                            ((IConvertibleToExpression) node.Children[0].Result).ToExpression().Remove(),
                    Accessor = CSharpLanguage.AccessorFromString(((AstToken) node.Children[1].Children[0].Result).Value),
                    AccessorToken = (AstToken) node.Children[1].Children[0].Result,
                    Identifier = (Identifier) node.Children[2].Result
                });

            var argument = new GrammarDefinition("Argument",
                rule: expression
                      | ToElement(REF) + expression
                      | ToElement(OUT) + expression,
                createNode: node =>
                {
                    if (node.Children.Count > 1)
                    {
                        return new DirectionExpression()
                        {
                            DirectionToken = (AstToken) node.Children[0].Result,
                            Direction = CSharpLanguage.DirectionFromString(((AstToken) node.Children[0].Result).Value),
                            Expression = (Expression) node.Children[1].Result
                        };
                    }
                    return node.Children[0].Result;
                });

            var argumentList = new GrammarDefinition("ArgumentList");
            argumentList.Rule = argument
                                | argumentList + ToElement(COMMA) + argument;
            var argumentListOptional = new GrammarDefinition("ArgumentListOptional",
                rule: null | argumentList);

            var invocationExpression = new GrammarDefinition("InvocationExpression",
                rule: primaryExpression
                      + ToElement(OPEN_PARENS)
                      + argumentListOptional
                      + ToElement(CLOSE_PARENS),
                createNode: node =>
                {
                    var result = new InvocationExpression()
                    {
                        Target = (Expression) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                    };

                    if (node.Children[2].HasChildren)
                    {
                        foreach (var subNode in node.Children[2].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Arguments.Add((Expression) subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[3].Result;
                    return result;
                });

            var indexerExpression = new GrammarDefinition("IndexerExpression",
                rule: primaryExpression
                      + ToElement(OPEN_BRACKET_EXPR)
                      + argumentList
                      + ToElement(CLOSE_BRACKET),
                createNode: node =>
                {
                    var result = new IndexerExpression()
                    {
                        Target = (Expression) node.Children[0].Result,
                        LeftBracket = (AstToken) node.Children[1].Result,
                    };

                    foreach (var subNode in node.Children[2].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Indices.Add((Expression) subNode);
                    }

                    result.RightBracket = (AstToken) node.Children[3].Result;
                    return result;
                });

            var createObjectExpression = new GrammarDefinition("CreateObjectExpression",
                rule: ToElement(NEW)
                      + typeReference
                      + ToElement(OPEN_PARENS)
                      + argumentListOptional
                      + ToElement(CLOSE_PARENS)
                      + arrayInitializerOptional
                      | ToElement(NEW)
                      + namespaceOrTypeExpression
                      + arrayInitializer,
                createNode: node =>
                {
                    var result = new CreateObjectExpression();
                    result.NewKeyword = (AstToken) node.Children[0].Result;
                    result.Type = (TypeReference) node.Children[1].Result;

                    if (node.Children.Count == 6)
                    {
                        result.LeftParenthese = (AstToken) node.Children[2].Result;

                        if (node.Children[3].HasChildren)
                        {
                            foreach (var subNode in node.Children[3].Children[0].GetAllListAstNodes())
                            {
                                if (subNode is AstToken)
                                    result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                                else
                                    result.Arguments.Add((Expression) subNode);
                            }
                        }

                        result.RightParenthese = (AstToken) node.Children[4].Result;
                    }

                    var initializerNode = node.Children[node.Children.Count - 1];
                    if (initializerNode.HasChildren)
                        result.Initializer = (ArrayInitializer) initializerNode.Result;
                    return result;
                });

            var createArrayExpression = new GrammarDefinition("CreateArrayExpression",
                rule: ToElement(NEW)
                      + rankSpecifier
                      + arrayInitializer
                      | ToElement(NEW)
                      + typeReference
                      + rankSpecifier
                      + arrayInitializer
                      | ToElement(NEW)
                      + typeReference
                      + ToElement(OPEN_BRACKET_EXPR)
                      + argumentList
                      + ToElement(CLOSE_BRACKET)
                      + arrayInitializerOptional
                ,
                createNode: node =>
                {
                    var result = new CreateArrayExpression();
                    result.NewKeyword = (AstToken) node.Children[0].Result;

                    switch (node.Children.Count)
                    {
                        case 3:
                            {
                                var rankSpecifierNode = (ArrayTypeRankSpecifier) node.Children[1].Result;
                                result.LeftBracket = (AstToken) rankSpecifierNode.LeftBracket.Remove();
                                result.RightBracket = (AstToken) rankSpecifierNode.RightBracket.Remove();
                                break;
                            }
                        case 4:
                            {
                                result.Type = (TypeReference) node.Children[1].Result;
                                var rankSpecifierNode = (ArrayTypeRankSpecifier) node.Children[2].Result;
                                result.LeftBracket = (AstToken) rankSpecifierNode.LeftBracket.Remove();
                                result.RightBracket = (AstToken) rankSpecifierNode.RightBracket.Remove();
                                break;
                            }
                        case 6:
                            {
                                result.Type = (TypeReference) node.Children[1].Result;
                                result.LeftBracket = (AstToken) node.Children[2].Result;
                                if (node.Children[3].HasChildren)
                                {
                                    foreach (var subNode in node.Children[3].Children[0].GetAllListAstNodes())
                                    {
                                        if (subNode is AstToken)
                                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                                        else
                                            result.Arguments.Add((Expression) subNode);
                                    }
                                }
                                result.RightBracket = (AstToken) node.Children[4].Result;
                                break;
                            }
                    }
                    var initializerNode = node.Children[node.Children.Count - 1];
                    if (initializerNode.HasChildren)
                        result.Initializer = (ArrayInitializer) initializerNode.Result;
                    return result;
                });

            var primitiveTypeExpression = new GrammarDefinition("PrimitiveTypeExpression",
                rule: primitiveType,
                createNode: node => ((IConvertibleToExpression) node.Children[0].Result).ToExpression());

            var typeNameExpression = new GrammarDefinition("TypeNameExpression",
                rule: identifierExpression
                      | memberReferenceExpression
                      | primitiveTypeExpression);

            var thisExpression = new GrammarDefinition("ThisExpression",
                rule: ToElement(THIS),
                createNode: node => new ThisReferenceExpression()
                {
                    ThisKeywordToken = (AstToken) node.Children[0].Result,
                });

            var baseExpression = new GrammarDefinition("BaseExpression",
                rule: ToElement(BASE),
                createNode: node => new BaseReferenceExpression()
                {
                    BaseKeywordToken = (AstToken) node.Children[0].Result,
                });

            var typeofExpression = new GrammarDefinition("TypeOfExpression",
                rule: ToElement(TYPEOF) + ToElement(OPEN_PARENS) + typeReference
                      + ToElement(CLOSE_PARENS),
                createNode: node => new GetTypeExpression()
                {
                    GetTypeKeywordToken = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetType = (TypeReference) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var defaultExpression = new GrammarDefinition("DefaultExpression",
                rule: ToElement(DEFAULT)
                      + ToElement(OPEN_PARENS)
                      + typeReference
                      + ToElement(CLOSE_PARENS),
                createNode: node => new DefaultExpression()
                {
                    KeywordToken = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetType = (TypeReference) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var sizeofExpression = new GrammarDefinition("SizeOfExpression",
                rule: ToElement(SIZEOF) + ToElement(OPEN_PARENS) + typeReference
                      + ToElement(CLOSE_PARENS),
                createNode: node => new SizeOfExpression()
                {
                    SizeofKeyword = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetType = (TypeReference) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var checkedExpression = new GrammarDefinition("CheckedExpression",
                rule:
                    ToElement(CHECKED) + ToElement(OPEN_PARENS) + expression +
                    ToElement(CLOSE_PARENS),
                createNode: node => new CheckedExpression()
                {
                    CheckedKeyword = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetExpression = (Expression) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var uncheckedExpression = new GrammarDefinition("UncheckedExpression",
                rule:
                    ToElement(UNCHECKED) + ToElement(OPEN_PARENS) + expression +
                    ToElement(CLOSE_PARENS),
                createNode: node => new UncheckedExpression()
                {
                    UncheckedKeyword = (AstToken) node.Children[0].Result,
                    LeftParenthese = (AstToken) node.Children[1].Result,
                    TargetExpression = (Expression) node.Children[2].Result,
                    RightParenthese = (AstToken) node.Children[3].Result,
                });

            var stackAllocExpression = new GrammarDefinition("StackAllocExpression",
                rule:
                    ToElement(STACKALLOC)
                    + typeReference
                    + ToElement(OPEN_BRACKET_EXPR)
                    + expression
                    + ToElement(CLOSE_BRACKET),
                createNode: node => new StackAllocExpression()
                {
                    StackAllocKeyword = (AstToken) node.Children[0].Result,
                    Type = (TypeReference) node.Children[1].Result,
                    LeftBracket = (AstToken) node.Children[2].Result,
                    Counter = (Expression) node.Children[3].Result,
                    RightBracket = (AstToken) node.Children[4].Result,
                });

            var explicitAnonymousMethodParameter = new GrammarDefinition("ExplicitAnonymousMethodParameter",
                rule: typeReference + ToElement(IDENTIFIER),
                createNode: node => new ParameterDeclaration
                {
                    ParameterType = (TypeReference)node.Children[0].Result,
                    Declarator = new VariableDeclarator(ToIdentifier(node.Children[1].Result))
                });

            var explicitAnonymousMethodParameterList = new GrammarDefinition("ExplicitAnonymousMethodParameterList");
            explicitAnonymousMethodParameterList.Rule = explicitAnonymousMethodParameter
                                                        | explicitAnonymousMethodParameterList
                                                        + ToElement(COMMA)
                                                        + explicitAnonymousMethodParameter;

            var explicitAnonymousMethodParameterListOptional = new GrammarDefinition("ExplicitAnonymousMethodParameterListOptional",
                rule: null | explicitAnonymousMethodParameterList);

            var explicitAnonymousMethodSignature = new GrammarDefinition("ExplicitAnonymousMethodSignature",
                rule: ToElement(OPEN_PARENS) + explicitAnonymousMethodParameterListOptional + ToElement(CLOSE_PARENS));

            var explicitAnonymousMethodSignatureOptional =
                new GrammarDefinition("ExplicitAnonymousMethodSignatureOptional",
                    rule: null | explicitAnonymousMethodSignature);

            var anonymousMethodExpression = new GrammarDefinition("AnonymousMethodExpression",
                rule: ToElement(DELEGATE) + explicitAnonymousMethodSignatureOptional + blockStatement,
                createNode: node =>
                {
                    var result = new AnonymousMethodExpression();
                    result.DelegateKeyword = (AstToken) node.Children[0].Result;

                    if (node.Children[1].HasChildren)
                    {
                        var signature = node.Children[1].Children[0];
                        result.LeftParenthese = (AstToken) signature.Children[0].Result;

                        if (signature.Children[1].HasChildren)
                        {
                            foreach (var child in signature.Children[1].Children[0].GetAllListAstNodes())
                            {
                                if (child is AstToken)
                                    result.AddChild(AstNodeTitles.ElementSeparator, child);
                                else
                                    result.Parameters.Add((ParameterDeclaration) child);
                            }
                        }

                        result.RightParenthese = (AstToken)signature.Children[2].Result;
                    }

                    result.Body = (BlockStatement) node.Children[2].Result;
                    return result;
                });


            var implicitAnonymousMethodParameter = new GrammarDefinition("ImplicitAnonymousMethodParameter",
                rule: ToElement(IDENTIFIER),
                createNode: node => new ParameterDeclaration
                {
                    Declarator = new VariableDeclarator(ToIdentifier(node.Children[0].Result))
                });

            var implicitAnonymousMethodParameterList = new GrammarDefinition("ImplicitAnonymousMethodParameterList");
            implicitAnonymousMethodParameterList.Rule = implicitAnonymousMethodParameter
                                                        | implicitAnonymousMethodParameterList
                                                        + ToElement(COMMA)
                                                        + implicitAnonymousMethodParameter;

            var implicitAnonymousMethodParameterListOptional = new GrammarDefinition("ImplicitAnonymousMethodParameterListOptional",
                rule: null | implicitAnonymousMethodParameterList);

            var implicitAnonymousMethodSignature = new GrammarDefinition("implicitAnonymousMethodSignature",
                rule: implicitAnonymousMethodParameter | ToElement(OPEN_PARENS_LAMBDA) + implicitAnonymousMethodParameterList + ToElement(CLOSE_PARENS));

            var anonymousMethodSignature = new GrammarDefinition("AnonymousMethodSignature",
                rule: implicitAnonymousMethodSignature);

            var anonymousFunctionBody = new GrammarDefinition("AnonymousFunctionBody",
                rule: expression | blockStatement);

            var lambdaExpression = new GrammarDefinition("LambdaExpression",
                rule: anonymousMethodSignature + ToElement(ARROW) + anonymousFunctionBody,
                createNode: node =>
                {
                    var result = new LambdaExpression();
                    result.Arrow = (AstToken)node.Children[1].Result;
                    result.Body = node.Children[2].Result;
                    return result;

                });

            primaryExpression.Rule =
                typeNameExpression
                | primitiveExpression
                | parenthesizedExpression
                | invocationExpression
                | indexerExpression
                | thisExpression
                | baseExpression
                | createObjectExpression
                | createArrayExpression
                | typeofExpression
                | defaultExpression
                | sizeofExpression
                | checkedExpression
                | uncheckedExpression
                | stackAllocExpression
                | anonymousMethodExpression
                ;

            var preFixUnaryOperator = new GrammarDefinition("PreFixUnaryOperator",
                rule: ToElement(PLUS)
                      | ToElement(MINUS)
                      | ToElement(STAR)
                      | ToElement(BANG)
                      | ToElement(OP_INC)
                      | ToElement(OP_DEC)
                      | ToElement(BITWISE_AND)
                      | ToElement(TILDE)
                      | ToElement(AWAIT));
            var postFixUnaryOperator = new GrammarDefinition("PostFixUnaryOperator",
                rule: ToElement(OP_INC)
                      | ToElement(OP_DEC));


            var castExpression = new GrammarDefinition("CastExpression");

            var unaryOperatorExpression = new GrammarDefinition("UnaryOperatorExpression",
                rule: primaryExpression
                      | castExpression
                      | (preFixUnaryOperator + primaryExpression)
                      | (primaryExpression + postFixUnaryOperator),
                createNode: node =>
                {
                    if (node.Children.Count == 1)
                        return node.Children[0].Result;

                    var result = new UnaryOperatorExpression();
                    var isPrefix = node.Children[0].GrammarElement == preFixUnaryOperator;
                    if (isPrefix)
                    {
                        var operatorToken = ((AstToken) node.Children[0].Children[0].Result);
                        result.Operator = CSharpLanguage.UnaryOperatorFromString(operatorToken.Value);
                        result.OperatorToken = operatorToken;
                    }

                    result.Expression = (Expression) node.Children[isPrefix ? 1 : 0].Result;
                    if (!isPrefix)
                    {
                        var operatorToken = (AstToken) node.Children[1].Children[0].Result;
                        result.Operator = CSharpLanguage.UnaryOperatorFromString(operatorToken.Value, false);
                        result.OperatorToken = operatorToken;
                    }
                    return result;
                });

            castExpression.Rule = ToElement(OPEN_PARENS)
                                  + typeNameExpression
                                  + ToElement(CLOSE_PARENS)
                                  + unaryOperatorExpression;
            castExpression.ComputeResult = node => new ExplicitCastExpression
            {
                LeftParenthese = (AstToken) node.Children[0].Result,
                TargetType = ToTypeReference((IConvertibleToType) node.Children[1].Result),
                RightParenthese = (AstToken) node.Children[2].Result,
                TargetExpression = (Expression) node.Children[3].Result
            };

            var multiplicativeOperator = new GrammarDefinition("MultiplicativeOperator",
                rule: ToElement(STAR)
                      | ToElement(DIV)
                      | ToElement(PERCENT));

            var multiplicativeExpression = new GrammarDefinition("MultiplicativeExpression");
            multiplicativeExpression.Rule = unaryOperatorExpression
                                            | multiplicativeExpression
                                            + multiplicativeOperator
                                            + unaryOperatorExpression;
            multiplicativeExpression.ComputeResult = createBinaryOperatorExpression;

            var additiveOperator = new GrammarDefinition("AdditiveOperator",
                rule: ToElement(PLUS)
                      | ToElement(MINUS));
            var additiveExpression = new GrammarDefinition("AdditiveExpression");
            additiveExpression.Rule = multiplicativeExpression
                                      | additiveExpression
                                      + additiveOperator
                                      + multiplicativeExpression;
            additiveExpression.ComputeResult = createBinaryOperatorExpression;

            var shiftOperator = new GrammarDefinition("ShiftOperator",
                rule: ToElement(OP_SHIFT_LEFT)
                      | ToElement(OP_SHIFT_RIGHT));
            var shiftExpression = new GrammarDefinition("ShiftExpression");
            shiftExpression.Rule = additiveExpression
                                   | shiftExpression
                                   + shiftOperator
                                   + additiveExpression;
            shiftExpression.ComputeResult = createBinaryOperatorExpression;

            var relationalOperator = new GrammarDefinition("RelationalOperator",
                rule: ToElement(OP_GT)
                      | ToElement(OP_GE)
                      | ToElement(OP_LT)
                      | ToElement(OP_LE)
                      | ToElement(IS)
                      | ToElement(AS));
            var relationalExpression = new GrammarDefinition("RelationalExpression");
            relationalExpression.Rule = shiftExpression
                                        | relationalExpression
                                        + relationalOperator
                                        + shiftExpression;
            relationalExpression.ComputeResult = node =>
            {
                if (node.Children.Count == 1)
                    return node.Children[0].Result;
                var operatorToken = (CSharpAstToken) node.Children[1].Children[0].Result;
                switch (operatorToken.Code)
                {
                    case IS:
                        return new TypeCheckExpression()
                        {
                            TargetExpression = (Expression) node.Children[0].Result,
                            IsKeyword = operatorToken,
                            TargetType = ToTypeReference((IConvertibleToType) node.Children[2].Result)
                        };
                    case AS:
                        return new SafeCastExpression()
                        {
                            TargetExpression = (Expression) node.Children[0].Result,
                            CastKeyword = operatorToken,
                            TargetType = ToTypeReference((IConvertibleToType) node.Children[2].Result)
                        };
                    default:
                        return createBinaryOperatorExpression(node);
                }
            };

            var equalityOperator = new GrammarDefinition("equalityOperator",
                rule: ToElement(OP_EQUALS)
                      | ToElement(OP_NOTEQUALS));
            var equalityExpression = new GrammarDefinition("EqualityExpression");
            equalityExpression.Rule = relationalExpression
                                      | equalityExpression
                                      + equalityOperator
                                      + relationalExpression;
            equalityExpression.ComputeResult = createBinaryOperatorExpression;

            var logicalAndExpression = new GrammarDefinition("LogicalAndExpression");
            logicalAndExpression.Rule = equalityExpression
                                      | logicalAndExpression
                                      + ToElement(BITWISE_AND)
                                      + equalityExpression;
            logicalAndExpression.ComputeResult = createBinaryOperatorExpression;

            var logicalXorExpression = new GrammarDefinition("LogicalOrExpression");
            logicalXorExpression.Rule = logicalAndExpression
                                      | logicalXorExpression
                                      + ToElement(CARRET)
                                      + logicalAndExpression;
            logicalXorExpression.ComputeResult = createBinaryOperatorExpression;

            var logicalOrExpression = new GrammarDefinition("LogicalOrExpression");
            logicalOrExpression.Rule = logicalXorExpression
                                      | logicalOrExpression
                                      + ToElement(BITWISE_OR)
                                      + logicalXorExpression;
            logicalOrExpression.ComputeResult = createBinaryOperatorExpression;

            var conditionalAndExpression = new GrammarDefinition("ConditionalAndExpression");
            conditionalAndExpression.Rule = logicalOrExpression
                                      | conditionalAndExpression
                                      + ToElement(OP_AND)
                                      + logicalOrExpression;
            conditionalAndExpression.ComputeResult = createBinaryOperatorExpression;

            var conditionalOrExpression = new GrammarDefinition("ConditionalOrExpression");
            conditionalOrExpression.Rule = conditionalAndExpression
                                      | conditionalOrExpression
                                      + ToElement(OP_OR)
                                      + conditionalAndExpression;
            conditionalOrExpression.ComputeResult = createBinaryOperatorExpression;

            var nullCoalescingExpression = new GrammarDefinition("NullCoalescingExpression");
            nullCoalescingExpression.Rule = conditionalOrExpression
                                      | nullCoalescingExpression
                                      + ToElement(OP_COALESCING)
                                      + conditionalOrExpression;
            nullCoalescingExpression.ComputeResult = createBinaryOperatorExpression;

            var conditionalExpression = new GrammarDefinition("ConditionalExpression",
                rule: nullCoalescingExpression
                      | nullCoalescingExpression
                      + ToElement(INTERR)
                      + expression + ToElement(COLON) + expression,
                createNode: node => node.Children.Count == 1
                    ? node.Children[0].Result
                    : new ConditionalExpression
                    {
                        Condition = (Expression) node.Children[0].Result,
                        OperatorToken = (AstToken) node.Children[1].Result,
                        TrueExpression = (Expression) node.Children[2].Result,
                        ColonToken = (AstToken) node.Children[3].Result,
                        FalseExpression = (Expression) node.Children[4].Result
                    });

            var assignmentOperator = new GrammarDefinition("AssignmentOperator",
                rule: ToElement(EQUALS)
                      | ToElement(OP_ADD_ASSIGN)
                      | ToElement(OP_SUB_ASSIGN)
                      | ToElement(OP_MULT_ASSIGN)
                      | ToElement(OP_DIV_ASSIGN)
                      | ToElement(OP_AND_ASSIGN)
                      | ToElement(OP_OR_ASSIGN)
                      | ToElement(OP_XOR_ASSIGN)
                      | ToElement(OP_SHIFT_LEFT_ASSIGN)
                      | ToElement(OP_SHIFT_RIGHT_ASSIGN));
            var assignmentExpression = new GrammarDefinition("AssignmentExpression",
                rule: unaryOperatorExpression
                      + assignmentOperator
                      + expression,
                createNode: node => new AssignmentExpression
                {
                    Target = (Expression) node.Children[0].Result,
                    Operator = CSharpLanguage.AssignmentOperatorFromString(((AstToken) node.Children[1].Children[0].Result).Value),
                    OperatorToken = (AstToken) node.Children[1].Children[0].Result,
                    Value = (Expression) node.Children[2].Result,
                });

            var fromClause = new GrammarDefinition("FromClause",
                rule: ToElement(FROM) + identifierInsideBody + ToElement(IN) + expression,
                createNode: node => new LinqFromClause
                {
                    FromKeyword = (AstToken) node.Children[0].Result,
                    VariableName = (Identifier) node.Children[1].Result,
                    InKeyword = (AstToken) node.Children[2].Result,
                    DataSource = (Expression) node.Children[3].Result
                });

            var letClause = new GrammarDefinition("LetClause",
                rule: ToElement(LET) + variableDeclarator,
                createNode: node => new LinqLetClause()
                {
                    LetKeyword = (AstToken) node.Children[0].Result,
                    Variable = (VariableDeclarator) node.Children[1].Result
                });

            var whereClause = new GrammarDefinition("WhereClause",
                rule: ToElement(WHERE) + expression,
                createNode: node => new LinqWhereClause()
                {
                    WhereKeyword = (AstToken) node.Children[0].Result,
                    Condition = (Expression) node.Children[1].Result
                });

            var orderingDirection = new GrammarDefinition("OrderingDirection",
                rule: null | ToElement(ASCENDING) | ToElement(DESCENDING));

            var ordering = new GrammarDefinition("Ordering",
                rule: expression + orderingDirection,
                createNode: node =>
                {
                    var result = new LinqOrdering();
                    result.Expression = (Expression) node.Children[0].Result;

                    if (node.Children[1].HasChildren)
                    {
                        var directionNode = node.Children[1].Children[0];
                        result.DirectionKeyword = (AstToken) directionNode.Result;
                        result.Direction = directionNode.Result != null
                            ? CSharpLanguage.OrderningDirectionFromString(result.DirectionKeyword.Value)
                            : LinqOrderingDirection.None;
                    }

                    return result;
                });

            var orderings = new GrammarDefinition("Orderings");
            orderings.Rule = ordering | orderings + ToElement(COMMA) + ordering;

            var orderByClause = new GrammarDefinition("OrderByClause",
                rule: ToElement(ORDERBY) + orderings,
                createNode: node =>
                {
                    var result = new LinqOrderByClause();
                    result.OrderByKeyword = (AstToken) node.Children[0].Result;
                    foreach (var subNode in node.Children[1].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Ordernings.Add((LinqOrdering) subNode);
                    }
                    return result;
                });

            var groupByClause = new GrammarDefinition("GroupByClause",
                rule: ToElement(GROUP) + expression + ToElement(BY) + expression,
                createNode: node => new LinqGroupByClause()
                {
                    GroupKeyword = (AstToken) node.Children[0].Result,
                    Expression = (Expression) node.Children[1].Result,
                    ByKeyword = (AstToken) node.Children[2].Result,
                    KeyExpression = (Expression) node.Children[3].Result
                });

            var selectClause = new GrammarDefinition("SelectClause",
                rule: ToElement(SELECT) + expression,
                createNode: node => new LinqSelectClause()
                {
                    SelectKeyword = (AstToken) node.Children[0].Result,
                    Target = (Expression) node.Children[1].Result
                });

            var queryBodyClause = new GrammarDefinition("QueryBodyClause",
                rule:
                fromClause
                | letClause
                | groupByClause
                | whereClause
                | orderByClause
                 );

            var queryBodyClauses = new GrammarDefinition("QueryBodyClauses");
            queryBodyClauses.Rule = queryBodyClause | queryBodyClauses + queryBodyClause;

            var queryBodyClausesOptional = new GrammarDefinition("QueryBodyClausesOptional",
                rule: null | queryBodyClauses);

            var linqExpression = new GrammarDefinition("LinqExpression",
                rule: fromClause + queryBodyClausesOptional + selectClause,
                createNode: node =>
                {
                    var result = new LinqExpression();
                    result.Clauses.Add((LinqClause) node.Children[0].Result);

                    if (node.Children[1].HasChildren)
                    {
                        result.Clauses.AddRange(node.Children[1].Children[0].GetAllListAstNodes().Cast<LinqClause>());
                    }

                    result.Clauses.Add((LinqClause) node.Children[2].Result);
                    return result;
                });

            expression.Rule = conditionalExpression
                              | linqExpression
                              | lambdaExpression
                              | assignmentExpression;

            #endregion

            #region Statements
            var statement = new GrammarDefinition("Statement");
            var embeddedStatement = new GrammarDefinition("EmbeddedStatement");

            var emptyStatement = new GrammarDefinition("EmptyStatement",
                rule: ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new EmptyStatement();
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[0].Result);
                    return result;
                });

            var labelStatement = new GrammarDefinition("LabelStatement",
                rule: identifierInsideBody + ToElement(COLON),
                createNode: node => new LabelStatement((Identifier) node.Children[0].Result)
                {
                    Colon = (AstToken) node.Children[1].Result
                });

            var expressionStatement = new GrammarDefinition("ExpressionStatement",
                rule: expression + ToElement(SEMICOLON)
                      | Error + ToElement(SEMICOLON)
                      | Error + ToElement(CLOSE_BRACE)
                      | expression + ToElement(CLOSE_BRACE), // Common mistake in C# is to forget the semicolon at the end of a statement.
                createNode: node =>
                {
                    var result = new ExpressionStatement(node.Children[0].Result as Expression);

                    var endingToken = (AstToken) node.Children[1].Result;
                    if (endingToken.GetTokenCode() == (int) SEMICOLON)
                    {
                        result.AddChild(AstNodeTitles.Semicolon, node.Children[1].Result);
                    }
                    else
                    {
                        node.Context.SyntaxErrors.Add(new SyntaxError(
                            node.Children[1].Range.End, 
                            "';' expected.", 
                            MessageSeverity.Error));
                        
                        node.Context.Lexer.PutBack((AstToken) endingToken);
                    }

                    return result;
                });

            blockStatement.Rule = ToElement(OPEN_BRACE)
                                  + statementListOptional
                                  + ToElement(CLOSE_BRACE);
            blockStatement.ComputeResult = node =>
            {
                var result = new BlockStatement();
                result.StartScope = node.Children[0].Result;
                if (node.Children[1].HasChildren)
                {
                    result.Statements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<Statement>());
                }
                result.EndScope = node.Children[2].Result;
                return result;
            };

            var variableDeclarationStatement = new GrammarDefinition("VariableDeclarationStatement",
                rule: variableDeclaration
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = node.Children[0].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[1].Result);
                    return result;
                });

            var ifElseStatement = new GrammarDefinition("IfElseStatement",
                rule: ToElement(IF) + parenthesizedExpression + embeddedStatement
                | ToElement(IF) + parenthesizedExpression + embeddedStatement + ToElement(ELSE) + embeddedStatement
                ,
                createNode: node =>
                {
                    var result = new IfElseStatement();
                    result.IfKeyword = (AstToken) node.Children[0].Result;

                    var parenthesized = (ParenthesizedExpression) node.Children[1].Result;
                    result.LeftParenthese = (AstToken) parenthesized.LeftParenthese.Remove();
                    result.Condition = (Expression) parenthesized.Expression?.Remove();
                    result.RightParenthese = (AstToken) parenthesized.RightParenthese.Remove();

                    result.TrueBlock = (Statement) node.Children[2].Result;

                    if (node.Children.Count > 3)
                    {
                        result.ElseKeyword = (AstToken) node.Children[3].Result;
                        result.FalseBlock = (Statement) node.Children[4].Result;
                        CheckForPossibleMistakenEmptyStatement(node.Children[4]);
                    }
                    else
                    {
                        CheckForPossibleMistakenEmptyStatement(node.Children[2]);
                    }

                    return result;
                });

            var switchLabel = new GrammarDefinition("SwitchLabel",
                rule: ToElement(CASE) + expression + ToElement(COLON)
                      | ToElement(DEFAULT_COLON) + ToElement(COLON),
                createNode: node =>
                {
                    var result = new SwitchCaseLabel();
                    result.CaseKeyword = (AstToken) node.Children[0].Result;
                    if (node.Children.Count > 2)
                        result.Condition = (Expression) node.Children[1].Result;
                    result.Colon = (AstToken) node.Children[node.Children.Count - 1].Result;
                    return result;
                });

            var switchLabels = new GrammarDefinition("SwitchLabels");
            switchLabels.Rule = switchLabel | switchLabels + switchLabel;

            var switchSection = new GrammarDefinition("SwitchSection",
                rule: switchLabels + statementList,
                createNode: node =>
                {
                    var result = new SwitchSection();
                    result.Labels.AddRange(node.Children[0].GetAllListAstNodes<SwitchCaseLabel>());

                    result.Statements.AddRange(node.Children[1].GetAllListAstNodes<Statement>());

                    return result;
                });

            var switchSections = new GrammarDefinition("SwitchSections");
            switchSections.Rule = switchSection
                                  | switchSections + switchSection;

            var switchBlock = new GrammarDefinition("SwitchBlock",
                rule: ToElement(OPEN_BRACE)
                      + switchSections
                      + ToElement(CLOSE_BRACE));

            var switchStatement = new GrammarDefinition("SwitchStatement",
                rule: ToElement(SWITCH)
                      + ToElement(OPEN_PARENS)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      + switchBlock,
                createNode: node =>
                {
                    var result = new SwitchStatement();
                    result.SwitchKeyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;
                    result.Condition = (Expression) node.Children[2].Result;
                    result.RightParenthese = (AstToken) node.Children[3].Result;
                    var switchBlockNode = node.Children[4];
                    result.StartScope = switchBlockNode.Children[0].Result;
                    result.Sections.AddRange(switchBlockNode.Children[1].GetAllListAstNodes<SwitchSection>());
                    result.EndScope = switchBlockNode.Children[2].Result;
                    return result;
                });

            var selectionStatement = new GrammarDefinition("SelectionStatement",
                rule: ifElseStatement
                      | switchStatement);

            var whileLoopStatement = new GrammarDefinition("WhileLoopStatement",
                rule: ToElement(WHILE)
                      + parenthesizedExpression
                      + embeddedStatement,
                createNode: node =>
                {
                    var bodyNode = node.Children[2];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    var conditionExpr = (ParenthesizedExpression) node.Children[1].Result;
                    return new WhileLoopStatement
                    {
                        WhileKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) conditionExpr.LeftParenthese.Remove(),
                        Condition = (Expression) conditionExpr.Expression.Remove(),
                        RightParenthese = (AstToken) conditionExpr.RightParenthese.Remove(),
                        Body = (Statement) bodyNode.Result
                    };
                });

            var doLoopStatement = new GrammarDefinition("DoLoopStatement",
                rule: ToElement(DO)
                      + embeddedStatement
                      + ToElement(WHILE)
                      + parenthesizedExpression
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var conditionExpr = (ParenthesizedExpression) node.Children[3].Result;
                    return new DoLoopStatement
                    {
                        DoKeyword = (AstToken) node.Children[0].Result,
                        Body = (Statement) node.Children[1].Result,
                        WhileKeyword = (AstToken) node.Children[2].Result,
                        LeftParenthese = (AstToken) conditionExpr.LeftParenthese.Remove(),
                        Condition = (Expression) conditionExpr.Expression.Remove(),
                        RightParenthese = (AstToken) conditionExpr.RightParenthese.Remove(),
                        Semicolon = (AstToken) node.Children[4].Result
                    };
                });

            var forLoopInitializer = new GrammarDefinition("ForLoopInitializer",
                rule: variableDeclaration
                     | null
                     // TODO: statement-expression-list
                     );

            var forLoopCondition = new GrammarDefinition("ForLoopCondition",
                rule: expression
                | null);

            var forLoopStatement = new GrammarDefinition("ForLoopStatement",
                rule: ToElement(FOR)
                + ToElement(OPEN_PARENS)
                + forLoopInitializer
                + ToElement(SEMICOLON)
                + expressionOptional
                + ToElement(SEMICOLON)
                + expressionOptional // TODO: statement-expression-list
                + ToElement(CLOSE_PARENS)
                + embeddedStatement,
                createNode: node =>
                {
                    var result = new ForLoopStatement();
                    result.ForKeyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;

                    if (node.Children[2].HasChildren)
                    {
                        var declaration = node.Children[2].Children[0].Result as VariableDeclarationStatement;
                        if (declaration != null)
                        {
                            result.Initializers.Add(declaration);
                        }
                        else
                        {
                            result.Initializers.AddRange(node.Children[2].GetAllListAstNodes<Expression>()
                                .Select(x => new ExpressionStatement(x)));
                        }
                    }

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[3].Result);

                    if (node.Children[4].HasChildren)
                        result.Condition = (Expression) node.Children[4].Result;

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[5].Result);

                    if (node.Children[6].HasChildren)
                    {
                        result.Iterators.AddRange(node.Children[6].Children[0].GetAllListAstNodes<Expression>()
                            .Select(x => new ExpressionStatement(x)));
                    }

                    result.RightParenthese = (AstToken) node.Children[7].Result;

                    var bodyNode = node.Children[8];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);
                    result.Body = (Statement) bodyNode.Result;

                    return result;
                });

            var foreachLoopStatement = new GrammarDefinition("ForEachLoopStatement",
                rule: ToElement(FOREACH)
                      + ToElement(OPEN_PARENS)
                      + typeReference
                      + identifierInsideBody
                      + ToElement(IN)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      + embeddedStatement,
                createNode: node =>
                {
                    var bodyNode = node.Children[7];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return new ForeachLoopStatement
                    {
                        ForeachKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                        Type = (TypeReference) node.Children[2].Result,
                        Identifier = (Identifier) node.Children[3].Result,
                        InKeyword = (AstToken) node.Children[4].Result,
                        Target = (Expression) node.Children[5].Result,
                        RightParenthese = (AstToken) node.Children[6].Result,
                        Body = (Statement) bodyNode.Result
                    };
                });

            var loopStatement = new GrammarDefinition("LoopStatement",
                rule: whileLoopStatement
                      | doLoopStatement
                      | forLoopStatement
                      | foreachLoopStatement);

            var lockStatement = new GrammarDefinition("LockStatement",
                rule: ToElement(LOCK)
                      + ToElement(OPEN_PARENS)
                      + expression
                      + ToElement(CLOSE_PARENS)
                      + statement,
                createNode: node =>
                {
                    var bodyNode = node.Children[4];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return new LockStatement
                    {
                        LockKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                        LockObject = (Expression) node.Children[2].Result,
                        RightParenthese = (AstToken) node.Children[3].Result,
                        Body = (Statement) bodyNode.Result
                    };
                });

            var resourceAcquisition = new GrammarDefinition("ResourceAcquisition",
                rule: variableDeclaration | expression);

            var usingStatement = new GrammarDefinition("UsingStatement",
                rule: ToElement(USING)
                      + ToElement(OPEN_PARENS)
                      + resourceAcquisition
                      + ToElement(CLOSE_PARENS)
                      + statement,
                createNode: node =>
                {
                    var bodyNode = node.Children[4];
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return new UsingStatement()
                    {
                        UsingKeyword = (AstToken) node.Children[0].Result,
                        LeftParenthese = (AstToken) node.Children[1].Result,
                        DisposableObject = node.Children[2].Result,
                        RightParenthese = (AstToken) node.Children[3].Result,
                        Body = (Statement) bodyNode.Result
                    };
                });

            var breakStatement = new GrammarDefinition("BreakStatement",
                rule: ToElement(BREAK)
                      + ToElement(SEMICOLON),
                createNode: node => new BreakStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    Semicolon = (AstToken) node.Children[1].Result
                });

            var continueStatement = new GrammarDefinition("ContinueStatement",
                rule: ToElement(CONTINUE)
                      + ToElement(SEMICOLON),
                createNode: node => new BreakStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    Semicolon = (AstToken) node.Children[1].Result
                });

            var returnStatement = new GrammarDefinition("ReturnStatement",
                rule: ToElement(RETURN)
                      + expressionOptional
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new ReturnStatement();
                    result.ReturnKeyword = (AstToken) node.Children[0].Result;
                    if (node.Children[1].HasChildren)
                        result.Value = (Expression) node.Children[1].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);
                    return result;
                });

            var throwStatement = new GrammarDefinition("ThrowStatement",
                rule: ToElement(THROW)
                      + expressionOptional
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new ThrowStatement();
                    result.ThrowKeyword = (AstToken) node.Children[0].Result;
                    if (node.Children[1].HasChildren)
                        result.Expression = (Expression) node.Children[1].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);
                    return result;
                });

            var gotoStatement = new GrammarDefinition("GotoStatement",
                rule: ToElement(GOTO)
                      + identifierInsideBody
                      + ToElement(SEMICOLON),
                // TODO: goto case and goto default statements.
                createNode: node =>
                {
                    var result = new GotoStatement();
                    result.GotoKeyword = (AstToken) node.Children[0].Result;
                    result.LabelIdentifier = (Identifier) node.Children[1].Result;
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);
                    return result;
                });

            var jumpStatement = new GrammarDefinition("JumpStatement",
                rule: breakStatement
                      | continueStatement
                      | gotoStatement
                      | returnStatement
                      | throwStatement);

            var yieldStatement = new GrammarDefinition("YieldStatement",
                rule: ToElement(YIELD)
                      + ToElement(RETURN)
                      + expression
                      + ToElement(SEMICOLON),
                createNode: node => new YieldStatement()
                {
                    YieldKeyword = (AstToken) node.Children[0].Result,
                    ReturnKeyword = (AstToken) node.Children[1].Result,
                    Value = (Expression) node.Children[2].Result
                });

            var yieldBreakStatement = new GrammarDefinition("YieldBreakStatement",
                rule: ToElement(YIELD)
                      + ToElement(BREAK)
                      + ToElement(SEMICOLON),
                createNode: node => new YieldBreakStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    BreakKeyword = (AstToken) node.Children[1].Result
                });

            var specificCatchClause = new GrammarDefinition("SpecificCatchClause",
                rule: ToElement(CATCH) + ToElement(OPEN_PARENS)
                    + namespaceOrTypeExpression + identifierInsideBodyOptional + ToElement(CLOSE_PARENS)
                    + blockStatement,
                createNode: node =>
                {
                    var result = new CatchClause();
                    result.CatchKeyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;
                    result.ExceptionType = (TypeReference) node.Children[2].Result;

                    if (node.Children[3].HasChildren)
                        result.ExceptionIdentifier = (Identifier) node.Children[3].Result;

                    result.RightParenthese = (AstToken) node.Children[4].Result;
                    result.Body = (BlockStatement) node.Children[5].Result;
                    return result;
                });

            var generalCatchClause = new GrammarDefinition("GeneralCatchClause",
                rule: ToElement(CATCH) + blockStatement,
                createNode: node => new CatchClause
                {
                    CatchKeyword = (AstToken) node.Children[0].Result,
                    Body = (BlockStatement) node.Children[1].Result
                });

            var catchClause = new GrammarDefinition("CatchClause",
                rule: specificCatchClause | generalCatchClause);

            var catchClauses = new GrammarDefinition("CatchClauses");
            catchClauses.Rule = catchClause | catchClauses + catchClause;

            var finallyClause = new GrammarDefinition("FinallyClause",
                rule: ToElement(FINALLY) + blockStatement);

            var tryCatchStatement = new GrammarDefinition("TryCatchStatement",
                rule: ToElement(TRY) + blockStatement + catchClauses
                      | ToElement(TRY) + blockStatement + finallyClause
                      | ToElement(TRY) + blockStatement + catchClauses + finallyClause,
                createNode: node =>
                {
                    var result = new TryCatchStatement();
                    result.TryKeyword = (AstToken) node.Children[0].Result;
                    result.TryBlock = (BlockStatement) node.Children[1].Result;

                    ParserNode finallyClauseNode = null;
                    if (node.Children[2].GrammarElement == finallyClause)
                    {
                        finallyClauseNode = node.Children[2];
                    }
                    else
                    {
                        result.CatchClauses.AddRange(node.Children[2].GetAllListAstNodes<CatchClause>());
                    }

                    if (node.Children.Count == 4)
                        finallyClauseNode = node.Children[3];

                    if (finallyClauseNode != null)
                    {
                        result.FinallyKeyword = (AstToken) finallyClauseNode.Children[0].Result;
                        result.FinallyBlock = (BlockStatement) finallyClauseNode.Children[1].Result;
                    }

                    return result;
                });

            var unsafeStatement = new GrammarDefinition("UnsafeStatement",
                rule: ToElement(UNSAFE) + blockStatement,
                createNode: node => new UnsafeStatement()
                {
                    Keyword = (AstToken) node.Children[0].Result,
                    Body = (BlockStatement) node.Children[1].Result
                });

            var fixedStatement = new GrammarDefinition("FixedStatement",
                rule: ToElement(FIXED) + ToElement(OPEN_PARENS)
                + variableDeclaration + ToElement(CLOSE_PARENS) + embeddedStatement,
                createNode: node =>
                {
                    var result = new FixedStatement();
                    result.Keyword = (AstToken) node.Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;

                    result.VariableDeclaration = (VariableDeclarationStatement) node.Children[2].Result;

                    result.RightParenthese = (AstToken) node.Children[3].Result;

                    var bodyNode = node.Children[4];
                    result.Body = (Statement) bodyNode.Result;
                    CheckForPossibleMistakenEmptyStatement(bodyNode);

                    return result;
                });

            embeddedStatement.Rule = emptyStatement
                                     | expressionStatement
                                     | blockStatement
                                     | selectionStatement
                                     | loopStatement
                                     | jumpStatement
                                     | lockStatement
                                     | usingStatement
                                     | yieldStatement
                                     | yieldBreakStatement
                                     | tryCatchStatement
                                     | unsafeStatement
                                     | fixedStatement
                ;


            statement.Rule = variableDeclarationStatement
                             | labelStatement
                             | embeddedStatement;
            ;
            #endregion

            #region Members

            var customAttribute = new GrammarDefinition("CustomAttribute",
                rule: namespaceOrTypeExpression
                | namespaceOrTypeExpression + ToElement(OPEN_PARENS) + argumentListOptional + ToElement(CLOSE_PARENS),
                createNode: node =>
                {
                    var result = new CustomAttribute();
                    result.Type = ((IConvertibleToType) node.Children[0].Result).ToTypeReference();

                    if (node.Children.Count > 1)
                    {
                        result.LeftParenthese = (AstToken) node.Children[1].Result;

                        if (node.Children[2].HasChildren)
                        {
                            foreach (var child in node.Children[2].Children[0].GetAllListAstNodes())
                            {
                                if (child is AstToken)
                                    result.AddChild(AstNodeTitles.ElementSeparator, child);
                                else
                                    result.Arguments.Add((Expression) child);
                            }
                        }

                        result.RightParenthese = (AstToken) node.Children[3].Result;

                    }
                    return result;
                });

            var customAttributeList = new GrammarDefinition("CustomAttributeList");
            customAttributeList.Rule = customAttribute | customAttributeList + ToElement(COMMA) + customAttribute;

            var customAttributePrefix = new GrammarDefinition("CustomAttributePrefix",
                rule: ToElement(ASSEMBLY) | ToElement(MODULE));

            var customAttributePrefixOptional = new GrammarDefinition("CustomAttributePrefixOptional",
                rule: null | customAttributePrefix + ToElement(COLON));

            var customAttributeSection = new GrammarDefinition("CustomAttributeSection",
                rule: ToElement(OPEN_BRACKET_EXPR) // HACK: use expression brackets instead to avoid conflicts.
                + customAttributePrefixOptional
                + customAttributeList 
                + ToElement(CLOSE_BRACKET),
                createNode: node =>
                {
                    var result = new CustomAttributeSection();
                    result.LeftBracket = (AstToken) node.Children[0].Result;

                    if (node.Children[1].Result != null)
                    {
                        result.VariantKeyword = (AstToken) node.Children[1].Result;
                        result.Variant = CSharpLanguage.SectionVariantFromString(result.VariantKeyword.Value);
                    }

                    foreach (var child in node.Children[2].GetAllListAstNodes())
                    {
                        if (child is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, child);
                        else
                            result.Attributes.Add((CustomAttribute) child);
                    }

                    result.RightBracket = (AstToken) node.Children[3].Result;
                    return result;
                });

            var customAttributeSectionList = new GrammarDefinition("CustomAttributeSectionList");
            customAttributeSectionList.Rule = customAttributeSection | customAttributeSectionList + customAttributeSection;

            var customAttributeSectionListOptional = new GrammarDefinition("CustomAttributeSectionListOptional",
                rule: null | customAttributeSectionList);

            var modifier = new GrammarDefinition("Modifier",
                rule: ToElement(PRIVATE)
                      | ToElement(PROTECTED)
                      | ToElement(INTERNAL)
                      | ToElement(PUBLIC)
                      | ToElement(STATIC)
                      | ToElement(ABSTRACT)
                      | ToElement(OVERRIDE)
                      | ToElement(PARTIAL)
                      | ToElement(CONST)
                      | ToElement(READONLY)
                      | ToElement(VIRTUAL)
                      | ToElement(SEALED)
                      | ToElement(UNSAFE)
                      | ToElement(FIXED)
                      | ToElement(ASYNC)
                      | ToElement(EXTERN),
                createNode: node => new ModifierElement(((AstToken) node.Children[0].Result).Value, node.Children[0].Range)
                {
                    Modifier = CSharpLanguage.ModifierFromString(((AstToken) node.Children[0].Result).Value)
                });

            var modifierList = new GrammarDefinition("ModifierList");
            modifierList.Rule = modifier | modifierList + modifier;
            var modifierListOptional = new GrammarDefinition("ModifierListOptional",
                rule: null | modifierList);

            var fieldDeclaration = new GrammarDefinition("FieldDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + variableDeclaratorList
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new FieldDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.FieldType = (TypeReference) node.Children[2].Result;

                    foreach (var subNode in node.Children[3].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Declarators.Add((VariableDeclarator) subNode);
                    }

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[4].Result);
                    return result;
                });

            var parameterModifier = new GrammarDefinition("ParameterModifier",
                rule: null
                      | ToElement(THIS)
                      | ToElement(REF)
                      | ToElement(OUT)
                      | ToElement(PARAMS));
            var parameterDeclaration = new GrammarDefinition("ParameterDeclaration",
                rule: customAttributeSectionListOptional
                      + parameterModifier
                      + typeReference
                      + variableDeclarator,
                createNode: node =>
                {
                    var result = new ParameterDeclaration();

                    if (node.Children[0].HasChildren)
                    {
                        result.CustomAttributeSections.AddRange(
                            node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());
                    }

                    result.ParameterModifierToken = (AstToken) (node.Children[1].HasChildren ? node.Children[1].Children[0].Result : null);
                    result.ParameterType = (TypeReference) node.Children[2].Result;
                    result.Declarator = (VariableDeclarator) node.Children[3].Result;
                    return result;
                });

            var parameterDeclarationList = new GrammarDefinition("ParameterDeclarationList");
            parameterDeclarationList.Rule = parameterDeclaration | parameterDeclarationList + ToElement(COMMA) + parameterDeclaration;
            var optionalParameterDeclarationList = new GrammarDefinition("OptionalParameterDeclarationList",
                rule: null | parameterDeclarationList);

            var constructorInitializerVariant = new GrammarDefinition("ConstructorInitializerVariant",
                rule: ToElement(THIS) | ToElement(BASE));
            var constructorInitializer = new GrammarDefinition("ConstructorInitializer",
                rule: constructorInitializerVariant
                      + ToElement(OPEN_PARENS)
                      + argumentListOptional
                      + ToElement(CLOSE_PARENS),
                createNode: node =>
                {
                    var result = new Members.ConstructorInitializer();
                    result.VariantToken = (AstToken) node.Children[0].Children[0].Result;
                    result.LeftParenthese = (AstToken) node.Children[1].Result;
                    if (node.Children[2].HasChildren)
                    {
                        foreach (var subNode in node.Children[2].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Arguments.Add((Expression) subNode);
                        }
                    }
                    result.RightParenthese = (AstToken) node.Children[3].Result;
                    return result;
                });

            var optionalConstructorInitializerList = new GrammarDefinition("OptionalConstructorInitializer",
                rule: null | ToElement(COLON) + constructorInitializer);

            var constructorDeclaration = new GrammarDefinition("ConstructorDeclaration",
                rule: customAttributeSectionListOptional
                        + modifierListOptional
                        + ToElement(IDENTIFIER)
                        + ToElement(OPEN_PARENS)
                        + optionalParameterDeclarationList
                        + ToElement(CLOSE_PARENS)
                        + optionalConstructorInitializerList
                        + blockStatement,
                createNode: node =>
                {
                    var result = new Members.ConstructorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.Identifier = ToIdentifier(node.Children[2].Result);
                    result.LeftParenthese = (AstToken) node.Children[3].Result;

                    if (node.Children[4].HasChildren)
                    {
                        foreach (var subNode in node.Children[4].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration) subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        result.Colon = (AstToken) node.Children[6].Children[0].Result;
                        result.Initializer = (Members.ConstructorInitializer) node.Children[6].Children[1].Result;
                    }

                    result.Body = (BlockStatement) node.Children[7].Result;
                    return result;
                });

            var conversionOperator = new GrammarDefinition("ConversionOperator",
                rule: ToElement(IMPLICIT)
                      | ToElement(EXPLICIT));

            var conversionOperatorDeclaration = new GrammarDefinition("ConversionOperatorDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + conversionOperator
                      + ToElement(OPERATOR)
                      + ToElement(IDENTIFIER)
                      + ToElement(OPEN_PARENS)
                      + optionalParameterDeclarationList
                      + ToElement(CLOSE_PARENS)
                      + blockStatement,
                createNode: node =>
                {
                    var result = new OperatorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.Identifier = ToIdentifier(node.Children[2].Result);
                    result.OperatorType = CSharpLanguage.OperatorDeclarationTypeFromString(result.Identifier.Name);
                    result.OperatorKeyword = (AstToken) node.Children[3].Result;
                    result.ReturnType = ToTypeReference(ToIdentifier(node.Children[4].Result));
                    result.LeftParenthese = (AstToken)node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        foreach (var subNode in node.Children[6].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration)subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[7].Result;
                    result.Body = (BlockStatement) node.Children[8].Result;

                    return result;
                });

            var overloadableOperator = new GrammarDefinition("OverloadableOperator",
                rule: ToElement(PLUS)
                      | ToElement(MINUS)
                      | ToElement(STAR)
                      | ToElement(DIV)
                      | ToElement(PERCENT)
                      | ToElement(BITWISE_AND)
                      | ToElement(BITWISE_OR)
                      | ToElement(CARRET)
                      | ToElement(OP_EQUALS)
                      | ToElement(OP_NOTEQUALS)
                      | ToElement(OP_GT)
                      | ToElement(OP_GE)
                      | ToElement(OP_LT)
                      | ToElement(OP_LE)
                      | ToElement(OP_SHIFT_LEFT)
                      | ToElement(OP_SHIFT_RIGHT)
                      | ToElement(TRUE)
                      | ToElement(FALSE)
                      | ToElement(BANG)
                      | ToElement(TILDE)
                      | ToElement(OP_INC)
                      | ToElement(OP_DEC));

            var arithmeticOperatorDeclaration = new GrammarDefinition("ArithmeticOperatorDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + ToElement(OPERATOR)
                      + overloadableOperator
                      + ToElement(OPEN_PARENS)
                      + optionalParameterDeclarationList
                      + ToElement(CLOSE_PARENS)
                      + blockStatement,
                createNode: node =>
                {
                    var result = new OperatorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.ReturnType = (TypeReference) node.Children[2].Result;
                    result.OperatorKeyword = (AstToken)node.Children[3].Result;
                    result.Identifier = ToIdentifier(node.Children[4].Result);

                    result.LeftParenthese = (AstToken)node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        foreach (var subNode in node.Children[6].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration)subNode);
                        }
                    }

                    result.RightParenthese = (AstToken)node.Children[7].Result;

                    result.OperatorType = CSharpLanguage.OperatorDeclarationTypeFromString(result.Identifier.Name);
                    if (result.Parameters.Count == 2)
                    {
                        if (result.OperatorType == OperatorDeclarationType.Positive)
                            result.OperatorType = OperatorDeclarationType.Add;
                        else if (result.OperatorType == OperatorDeclarationType.Negative)
                            result.OperatorType = OperatorDeclarationType.Subtract;
                    }

                    result.Body = (BlockStatement)node.Children[8].Result;

                    return result;
                });

            var operatorDeclaration = new GrammarDefinition("OperatorDeclaration",
                rule: conversionOperatorDeclaration | arithmeticOperatorDeclaration);

            var methodDeclarationBody = new GrammarDefinition("MethodDeclarationBody",
                rule: ToElement(SEMICOLON) | blockStatement);

            var methodDeclaration = new GrammarDefinition("MethodDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + ToElement(IDENTIFIER)
                      + ToElement(OPEN_PARENS)
                      + optionalParameterDeclarationList
                      + ToElement(CLOSE_PARENS)
                      + methodDeclarationBody,
                createNode: node =>
                {
                    var result = new MethodDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.ReturnType = (TypeReference) node.Children[2].Result;
                    result.Identifier = ToIdentifier(node.Children[3].Result);
                    result.LeftParenthese = (AstToken) node.Children[4].Result;

                    if (node.Children[5].HasChildren)
                    {
                        foreach (var subNode in node.Children[5].Children[0].GetAllListAstNodes())
                        {
                            if (subNode is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                            else
                                result.Parameters.Add((ParameterDeclaration) subNode);
                        }
                    }

                    result.RightParenthese = (AstToken) node.Children[6].Result;

                    var body = node.Children[7].Result;
                    if (body is AstToken)
                        result.AddChild(AstNodeTitles.Semicolon, (AstToken) body);
                    else
                        result.Body = (BlockStatement) body;
                    return result;
                });

            var eventDeclaration = new GrammarDefinition("EventDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + ToElement(EVENT)
                      + typeReference
                      + variableDeclaratorList
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new EventDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.EventKeyword = (AstToken) node.Children[2].Result;
                    result.EventType = (TypeReference) node.Children[3].Result;

                    foreach (var subNode in node.Children[4].GetAllListAstNodes())
                    {
                        if (subNode is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                        else
                            result.Declarators.Add((VariableDeclarator) subNode);
                    }

                    result.AddChild(AstNodeTitles.Semicolon, node.Children[5].Result);
                    return result;
                });

            var accessorKeyword = new GrammarDefinition("AccessorKeyword",
                rule: ToElement(GET)
                | ToElement(SET));
            var accessorBody = new GrammarDefinition("AccessorBody",
                rule: ToElement(SEMICOLON)
                      | blockStatement);

            var accessorDeclaration = new GrammarDefinition("AccessorDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + accessorKeyword
                      + accessorBody,
                createNode: node =>
                {
                    var result = new AccessorDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.AccessorKeyword = (AstToken) node.Children[2].Children[0].Result;

                    var bodyNode = node.Children[3].Children[0].Result;
                    if (bodyNode is AstToken)
                        result.AddChild(AstNodeTitles.Semicolon, bodyNode);
                    else
                        result.Body = (BlockStatement) bodyNode;

                    return result;
                });

            var accessorDeclarationList = new GrammarDefinition("AccessorDeclarationList");
            accessorDeclarationList.Rule = accessorDeclaration | accessorDeclaration + accessorDeclaration;

            var propertyDeclaration = new GrammarDefinition("PropertyDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeReference
                      + ToElement(IDENTIFIER)
                      + ToElement(OPEN_BRACE)
                      + accessorDeclarationList
                      + ToElement(CLOSE_BRACE),
                createNode: node =>
                {
                    var result = new PropertyDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    result.PropertyType = (TypeReference) node.Children[2].Result;
                    result.Identifier = ToIdentifier(node.Children[3].Result);
                    result.StartScope = node.Children[4].Result;

                    foreach (var accessor in node.Children[5].Children)
                    {
                        var declaration = (AccessorDeclaration) accessor.Result;
                        // TODO: detect duplicate accessor declarations.
                        switch (declaration.AccessorKeyword.Value)
                        {
                            case "get":
                                result.Getter = declaration;
                                break;
                            case "set":
                                result.Setter = declaration;
                                break;
                        }
                    }

                    result.EndScope = node.Children[6].Result;
                    return result;
                });

            var memberDeclaration = new GrammarDefinition("MemberDeclaration");
            var memberDeclarationList = new GrammarDefinition("MemberDeclarationList");
            memberDeclarationList.Rule = memberDeclaration | memberDeclarationList + memberDeclaration;
            var memberDeclarationListOptional = new GrammarDefinition("MemberDeclarationListOptional");
            memberDeclarationListOptional.Rule = null | memberDeclarationList;

            var baseTypeList = new GrammarDefinition("BaseTypeList");
            baseTypeList.Rule = typeReference | baseTypeList + ToElement(COMMA) + typeReference;

            var optionalBaseTypeList = new GrammarDefinition("OptionalBaseTypeList");
            optionalBaseTypeList.Rule = null | ToElement(COLON) + baseTypeList;

            var typeVariantKeyword = new GrammarDefinition("TypeVariantKeyword",
                rule: ToElement(CLASS)
                      | ToElement(STRUCT)
                      | ToElement(INTERFACE)
                      | ToElement(ENUM));
            var typeDeclaration = new GrammarDefinition("TypeDeclaration",
                rule: customAttributeSectionListOptional
                      + modifierListOptional
                      + typeVariantKeyword
                      + ToElement(IDENTIFIER)
                      + optionalBaseTypeList
                      + ToElement(OPEN_BRACE)
                      + memberDeclarationListOptional
                      + ToElement(CLOSE_BRACE),
                createNode: node =>
                {
                    var result = new TypeDeclaration();

                    if (node.Children[0].HasChildren)
                        result.CustomAttributeSections.AddRange(node.Children[0].Children[0].GetAllListAstNodes<CustomAttributeSection>());

                    if (node.Children[1].HasChildren)
                        result.ModifierElements.AddRange(node.Children[1].Children[0].GetAllListAstNodes<ModifierElement>());

                    var variantToken = (AstToken) node.Children[2].Children[0].Result;
                    result.TypeVariant = CSharpLanguage.TypeVariantFromString(variantToken.Value);
                    result.TypeVariantToken = variantToken;
                    result.Identifier = ToIdentifier(node.Children[3].Result);

                    if (node.Children[4].HasChildren)
                    {
                        result.AddChild(AstNodeTitles.Colon, node.Children[4].Children[0].Result);

                        foreach (var child in node.Children[4].Children[1].GetAllListAstNodes())
                        {
                            if (child is AstToken)
                                result.AddChild(AstNodeTitles.ElementSeparator, child);
                            else
                                result.BaseTypes.Add((TypeReference) child);
                        }
                    }

                    result.StartScope = node.Children[5].Result;

                    if (node.Children[6].HasChildren)
                    {
                        result.Members.AddRange(node.Children[6].Children[0].GetAllListAstNodes<MemberDeclaration>());
                    }

                    result.EndScope = node.Children[7].Result;
                    return result;
                });

            memberDeclaration.Rule = methodDeclaration
                                     | constructorDeclaration
                                     | operatorDeclaration
                                     | propertyDeclaration
                                     | eventDeclaration
                                     | fieldDeclaration
                                     | typeDeclaration
                                    ;

            var typeOrNamespaceDeclarationList = new GrammarDefinition("TypeOrNamespaceDeclarationList");
            var typeOrNamespaceDeclarationListOptional = new GrammarDefinition("TypeOrNamespaceDeclarationListOptional",
                rule: null | typeOrNamespaceDeclarationList);

            var namespaceDeclaration = new GrammarDefinition("NamespaceDeclaration",
                rule: ToElement(NAMESPACE)
                      + typeNameExpression
                      + ToElement(OPEN_BRACE)
                      + usingDirectiveListOptional
                      + typeOrNamespaceDeclarationListOptional
                      + ToElement(CLOSE_BRACE),
                createNode: node =>
                {
                    var result = new NamespaceDeclaration();
                    result.Keyword = (AstToken) node.Children[0].Result;
                    result.Identifier = ((IConvertibleToIdentifier) node.Children[1].Result).ToIdentifier();
                    result.StartScope = node.Children[2].Result;

                    if (node.Children[3].HasChildren)
                    {
                        result.UsingDirectives.AddRange(node.Children[3].Children[0].GetAllListAstNodes<UsingDirective>());
                    }

                    if (node.Children[4].HasChildren)
                    {
                        foreach (var subNode in node.Children[4].Children[0].GetAllListAstNodes())
                        {
                            var type = subNode as TypeDeclaration;
                            if (type != null)
                                result.Types.Add(type);
                            else
                                result.Namespaces.Add((NamespaceDeclaration) subNode);
                        }
                    }

                    result.EndScope = node.Children[5].Result;

                    return result;
                });

            var typeOrNamespaceDeclaration = new GrammarDefinition("TypeOrNamespaceDeclaration",
                rule: namespaceDeclaration
                      | typeDeclaration);
            typeOrNamespaceDeclarationList.Rule = typeOrNamespaceDeclaration
                                                  | typeOrNamespaceDeclarationList
                                                  + typeOrNamespaceDeclaration;

            #endregion

            #region Initialize definitions

            var variableInitializerList = new GrammarDefinition("VariableInitializerList");
            variableInitializerList.Rule = variableInitializer
                                           | variableInitializerList
                                           + ToElement(COMMA)
                                           + variableInitializer;
            var variableInitializerListOptional = new GrammarDefinition("VariableInitializerListOptional",
                rule: null | variableInitializerList);

            arrayInitializer.Rule = ToElement(OPEN_BRACE)
                                    + variableInitializerListOptional
                                    + ToElement(CLOSE_BRACE)
                                    | ToElement(OPEN_BRACE)
                                    + variableInitializerList
                                    + ToElement(COMMA)
                                    + ToElement(CLOSE_BRACE);

            arrayInitializer.ComputeResult = node =>
            {
                var result = new ArrayInitializer();
                result.OpeningBrace = node.Children[0].Result;

                ParserNode initializersNode = null;
                if (node.Children.Count == 4)
                {
                    initializersNode = node.Children[1];
                }
                else
                {
                    if (node.Children[1].HasChildren)
                        initializersNode = node.Children[1].Children[0];
                }

                if (initializersNode != null)
                {
                    foreach (var element in initializersNode.GetAllListAstNodes())
                    {
                        if (element is AstToken)
                            result.AddChild(AstNodeTitles.ElementSeparator, element);
                        else
                            result.Elements.Add((Expression) element);
                    }
                }

                if (node.Children.Count == 4)
                    result.AddChild(AstNodeTitles.ElementSeparator, node.Children[2].Result);
                result.ClosingBrace = node.Children[node.Children.Count - 1].Result;
                return result;
            };

            variableInitializer.Rule = expression
                                       | arrayInitializer
                ;

            var variableType = new GrammarDefinition("VariableType");
            variableType.Rule = typeNameExpression | variableType + rankSpecifier | variableType + ToElement(STAR);
            variableType.ComputeResult = node =>
            {
                var type = ToTypeReference((IConvertibleToType) node.Children[0].Result);
                if (node.Children.Count > 1)
                {
                    var specifier = node.Children[1].Result as ArrayTypeRankSpecifier;
                    if (specifier != null)
                    {
                        type = new ArrayTypeReference(type, specifier);
                    }
                    else
                    {
                        type = new PointerTypeReference(type)
                        {
                            PointerToken = (AstToken) node.Children[1].Result
                        };
                    }
                }
                return type;
            };

            // Types are recognized as expressions to prevent a conflict in the grammar.
            // TODO: also support array and pointer types.

            variableDeclaration.Rule =
                variableType
                + variableDeclaratorList;
            
            variableDeclaration.ComputeResult = node =>
            {
                var result = new VariableDeclarationStatement();
                result.VariableType = ToTypeReference((IConvertibleToType)node.Children[0].Result);

                foreach (var subNode in node.Children[1].GetAllListAstNodes())
                {
                    if (subNode is AstToken)
                        result.AddChild(AstNodeTitles.ElementSeparator, subNode);
                    else
                        result.Declarators.Add((VariableDeclarator) subNode);
                }

                return result;
            };

            statementList.Rule = statement | statementList + statement;

            #endregion

            #region Root compilation unit

            var usingNamespaceDirective = new GrammarDefinition("UsingNamespaceDirective",
                rule: ToElement(USING)
                      + namespaceOrTypeExpression
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new UsingNamespaceDirective();

                    result.UsingKeyword = (AstToken) node.Children[0].Result;
                    result.NamespaceIdentifier = ((IConvertibleToIdentifier) node.Children[1].Result).ToIdentifier();
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[2].Result);

                    return result;
                });

            var usingAliasDirective = new GrammarDefinition("UsingAliasDirective",
                rule: ToElement(USING)
                      + ToElement(IDENTIFIER)
                      + ToElement(EQUALS)
                      + typeReference
                      + ToElement(SEMICOLON),
                createNode: node =>
                {
                    var result = new UsingAliasDirective
                    {
                        UsingKeyword = (AstToken) node.Children[0].Result,
                        AliasIdentifier = ToIdentifier(node.Children[1].Result),
                        OperatorToken = (AstToken) node.Children[2].Result,
                        TypeImport = (TypeReference) node.Children[3].Result
                    };
                    result.AddChild(AstNodeTitles.Semicolon, node.Children[4].Result);
                    return result;
                });

            var usingDirective = new GrammarDefinition("UsingNamespaceDirective",
                rule: usingNamespaceDirective | usingAliasDirective);

            var usingDirectiveList = new GrammarDefinition("UsingDirectiveList");
            usingDirectiveList.Rule = usingDirective | usingDirectiveList + usingDirective;
            usingDirectiveListOptional.Rule = null | usingDirectiveList;

            var compilationUnit = new GrammarDefinition("CompilationUnit",
                rule: usingDirectiveListOptional
                + typeOrNamespaceDeclarationListOptional,
                createNode: node =>
                {
                    var result = new CompilationUnit();

                    if (node.Children[0].HasChildren)
                    {
                        result.UsingDirectives.AddRange(node.Children[0].Children[0].GetAllListAstNodes<UsingDirective>());
                    }

                    if (node.Children[1].HasChildren)
                    {
                        foreach (var subNode in node.Children[1].Children[0].GetAllListAstNodes())
                        {
                            var typeDecl = subNode as TypeDeclaration;
                            if (typeDecl == null)
                                result.Namespaces.Add((NamespaceDeclaration) subNode);
                            else
                                result.Types.Add(typeDecl);
                        }
                    }

                    return result;
                });

            #endregion

            RootDefinitions.Add(DefaultRoot = compilationUnit);
            RootDefinitions.Add(MemberDeclarationRule = memberDeclaration);
            RootDefinitions.Add(StatementRule = statement);
        }
Ejemplo n.º 51
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;

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

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

            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));
                }
            }
        }
Ejemplo n.º 52
0
			public override void VisitMethodDeclaration (MethodDeclaration methodDeclaration)
			{
				base.VisitMethodDeclaration (methodDeclaration);

				var hasRefs = methodDeclaration.Parameters.Any (IsRefParam);

				if (!hasRefs)
					return;

				var sub = new Substitute ();

				foreach (var p in methodDeclaration.Parameters.Where (IsRefParam).ToList ()) {

					var pty =  ((ComposedType)p.Type).BaseType;


					var access = new IndexerExpression (new IdentifierExpression (p.Name), new PrimitiveExpression (0));
					var ptd = GetTypeDef (pty);
					if (ptd != null)
						access.AddAnnotation (ptd);
					sub.Subs [p.Name] = access;
					p.ParameterModifier = ParameterModifier.None;
					var c = new ComposedType {
						BaseType = p.Type.Clone (),
					};
					c.ArraySpecifiers.Add (new ArraySpecifier (1));
					p.Type = c;
				}

				methodDeclaration.Body.AcceptVisitor (sub);
			}
Ejemplo n.º 53
0
        protected virtual void EmitArrayAccess(IndexerExpression indexerExpression)
        {
            string targetVar = null;
            bool writeTargetVar = false;
            bool isStatement = false;
            string valueVar = null;
            var resolveResult = this.Emitter.Resolver.ResolveNode(indexerExpression, this.Emitter);

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

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

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

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

            if (writeTargetVar)
            {
                var targetrr = this.Emitter.Resolver.ResolveNode(indexerExpression.Target, this.Emitter);
                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 (this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null)
            {
                valueVar = this.GetTempVarName();

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

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

            this.Emitter.IsAssignment = false;
            this.Emitter.IsUnaryAccessor = false;
            indexerExpression.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);
                }
            }

            this.WriteDot();

            var argsInfo = new ArgumentsInfo(this.Emitter, indexerExpression);
            var argsExpressions = argsInfo.ArgumentsExpressions;
            var paramsArg = argsInfo.ParamsExpression;

            if (!this.Emitter.IsAssignment)
            {
                if (this.Emitter.IsUnaryAccessor)
                {
                    bool isDecimal = Helpers.IsDecimalType(resolveResult.Type, this.Emitter.Resolver);
                    bool isNullable = NullableType.IsNullable(resolveResult.Type);

                    if (isStatement)
                    {
                        this.Write("set");
                        this.WriteOpenParentheses();
                        this.WriteOpenBracket();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.WriteCloseBracket();
                        this.WriteComma(false);

                        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
                                {
                                    indexerExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    indexerExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteDot();
                                if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment || this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    this.Write("inc");
                                }
                                else
                                {
                                    this.Write("dec");
                                }

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

                            this.WriteDot();

                            this.Write("get");
                            this.WriteOpenParentheses();
                            this.WriteOpenBracket();
                            new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                            this.WriteCloseBracket();
                            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("get");
                        this.WriteOpenParentheses();
                        this.WriteOpenBracket();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.WriteCloseBracket();
                        this.WriteCloseParentheses();
                        this.WriteComma();

                        if (targetVar != null)
                        {
                            this.Write(targetVar);
                        }
                        else
                        {
                            indexerExpression.Target.AcceptVisitor(this.Emitter);
                        }
                        this.WriteDot();
                        this.Write("set");
                        this.WriteOpenParentheses();
                        this.WriteOpenBracket();
                        new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                        this.WriteCloseBracket();
                        this.WriteComma(false);

                        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.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteCloseParentheses();
                            }
                            else
                            {
                                if (targetVar != null)
                                {
                                    this.Write(targetVar);
                                }
                                else
                                {
                                    indexerExpression.Target.AcceptVisitor(this.Emitter);
                                }

                                this.WriteDot();

                                this.Write("get");
                                this.WriteOpenParentheses();
                                this.WriteOpenBracket();
                                new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                                this.WriteCloseBracket();
                                this.WriteCloseParentheses();
                                this.WriteDot();
                                if (this.Emitter.UnaryOperatorType == UnaryOperatorType.Increment ||
                                    this.Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement)
                                {
                                    this.Write("inc");
                                }
                                else
                                {
                                    this.Write("dec");
                                }

                                this.WriteOpenCloseParentheses();
                            }
                        }
                        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();

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

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

                            this.WriteDot();

                            this.Write("get");
                            this.WriteOpenParentheses();
                            this.WriteOpenBracket();
                            new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                            this.WriteCloseBracket();
                            this.WriteCloseParentheses();
                        }
                        else
                        {
                            this.Write(valueVar);
                        }

                        this.WriteCloseParentheses();

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

                    if (targetVar != null)
                    {
                        this.RemoveTempVar(targetVar);
                    }
                }
                else
                {
                    this.Write("get");
                    this.WriteOpenParentheses();
                    this.WriteOpenBracket();
                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                    this.WriteCloseBracket();
                    this.WriteCloseParentheses();
                }
            }
            else
            {
                if (this.Emitter.AssignmentType != AssignmentOperatorType.Assign)
                {
                    var oldWriter = this.SaveWriter();
                    this.NewWriter();
                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                    var paramsStr = this.Emitter.Output.ToString();
                    this.RestoreWriter(oldWriter);

                    if (targetVar != null)
                    {
                        this.PushWriter(string.Concat(
                            "set([",
                            paramsStr,
                            "],",
                            targetVar,
                            ".get([",
                            paramsStr,
                            "]){0})"), () => { this.RemoveTempVar(targetVar); });
                    }
                    else
                    {
                        oldWriter = this.SaveWriter();
                        this.NewWriter();

                        this.Emitter.IsAssignment = false;
                        this.Emitter.IsUnaryAccessor = false;
                        indexerExpression.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(
                            "set([",
                            paramsStr,
                            "],",
                            trg,
                            ".get([",
                            paramsStr,
                            "]){0})"));
                    }
                }
                else
                {
                    this.Write("set");
                    this.WriteOpenParentheses();
                    this.WriteOpenBracket();
                    new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg).Emit();
                    this.WriteCloseBracket();
                    this.PushWriter(", {0})");
                }
            }
        }
Ejemplo n.º 54
0
 public virtual T Visit(IndexerExpression indexerExpression)
 {
     return(VisitChildren(indexerExpression));
 }
		public virtual void VisitIndexerExpression (IndexerExpression indexerExpression)
		{
			VisitChildren (indexerExpression);
		}
Ejemplo n.º 56
0
 public virtual IndexerExpression RewriteIndexerExpression(IndexerExpression expression)
 {
     return(expression);
 }
Ejemplo n.º 57
0
			public override object Visit (ElementAccess elementAccessExpression)
			{
				IndexerExpression result = new IndexerExpression ();
				var location = LocationsBag.GetLocations (elementAccessExpression);
				 
				result.AddChild ((INode)elementAccessExpression.Expr.Accept (this), IndexerExpression.Roles.TargetExpression);
				result.AddChild (new CSharpTokenNode (Convert (elementAccessExpression.Location), 1), TypeOfExpression.Roles.LBracket);
				AddArguments (result, location, elementAccessExpression.Arguments);
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), TypeOfExpression.Roles.RBracket);
				return result;
			}
 public override void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     // nothing
 }
Ejemplo n.º 59
0
 public override void VisitIndexerExpression(IndexerExpression indexerExpression)
 {
     // nothing
 }
Ejemplo n.º 60
0
			public override void VisitIndexerExpression (IndexerExpression indexerExpression)
			{
				base.VisitIndexerExpression (indexerExpression);

				var t = GetTypeRef (indexerExpression.Target);

				if (t != null && t.FullName == "System.String") {


					var targ = indexerExpression.Target;
					targ.Remove ();
					var index = indexerExpression.Arguments.FirstOrNullObject ();
					index.Remove ();

					var i = new InvocationExpression (
						        new MemberReferenceExpression (targ, "charCodeAt"),
						        index);

					indexerExpression.ReplaceWith (i);
				}
			}