예제 #1
0
		public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
		{
			Push();
			object result = base.VisitPropertyDeclaration(propertyDeclaration, data);
			Pop();
			return result;
		}
예제 #2
0
        protected virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, bool setter)
        {
            var memberResult = this.Emitter.Resolver.ResolveNode(propertyDeclaration, this.Emitter) as MemberResolveResult;

            if (memberResult != null &&
                (memberResult.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.FieldPropertyAttribute") ||
                (propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull)))
            {
                return;
            }

            if (!accessor.IsNull && this.Emitter.GetInline(accessor) == null)
            {
                this.EnsureComma();

                this.ResetLocals();

                var prevMap = this.BuildLocalsMap();
                var prevNamesMap = this.BuildLocalsNamesMap();

                if (setter)
                {
                    this.AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body);
                }

                XmlToJsDoc.EmitComment(this, this.PropertyDeclaration);
                var overloads = OverloadsCollection.Create(this.Emitter, propertyDeclaration, setter);
                string name = overloads.GetOverloadName();
                this.Write((setter ? "set" : "get") + name);
                this.WriteColon();
                this.WriteFunction();
                this.WriteOpenParentheses();
                this.Write(setter ? "value" : "");
                this.WriteCloseParentheses();
                this.WriteSpace();

                var script = this.Emitter.GetScript(accessor);

                if (script == null)
                {
                    accessor.Body.AcceptVisitor(this.Emitter);
                }
                else
                {
                    this.BeginBlock();

                    foreach (var line in script)
                    {
                        this.Write(line);
                        this.WriteNewLine();
                    }

                    this.EndBlock();
                }

                this.ClearLocalsMap(prevMap);
                this.ClearLocalsNamesMap(prevNamesMap);
                this.Emitter.Comma = true;
            }
        }
예제 #3
0
		void HandleVisitorPropertyDeclarationVisited (PropertyDeclaration node, InspectionData data)
		{
			foreach (var rule in policy.Rules) {
				if (rule.CheckProperty (node, data))
					return;
			}
		}
		/// <summary>
		/// Adds the elements of an array to the end of this PropertyDeclarationCollection.
		/// </summary>
		/// <param name="items">
		/// The array whose elements are to be added to the end of this PropertyDeclarationCollection.
		/// </param>
		public virtual void AddRange(PropertyDeclaration[] items)
		{
			foreach (PropertyDeclaration item in items)
			{
				this.List.Add(item);
			}
		}
            public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
            {
                if (propertyDeclaration.Getter.Body.IsNull && propertyDeclaration.Setter.Body.IsNull)
                    UnlockWith(propertyDeclaration);

                return base.VisitPropertyDeclaration(propertyDeclaration, data);
            }
예제 #6
0
            public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
            {
                if (propertyDeclaration.Setter.Modifiers.HasFlag(Modifiers.Private))
                {
                    UnlockWith(propertyDeclaration.Setter);
                }

                return base.VisitPropertyDeclaration(propertyDeclaration, data);
            }
예제 #7
0
        public PropertyReferenceExpression(Expression target,PropertyDeclaration property)
        {
            if (target==null)
                throw new ArgumentNullException("target");
            if (property==null)
                throw new ArgumentNullException("property");

            this.target = target;
            this.property = property;
        }
예제 #8
0
		bool ContainsGetter (PropertyDeclaration property, VariableInitializer initializer)
		{
			if (property.Getter.IsNull || property.Getter.Body.Statements.Count () != 1)
				return false;
			var ret = property.Getter.Body.Statements.Single () as ReturnStatement;
			if (ret == null)
				return false;
			return ret.Expression.IsMatch (new IdentifierExpression (initializer.Name)) || 
				ret.Expression.IsMatch (new MemberReferenceExpression (new ThisReferenceExpression (), initializer.Name));
		}
예제 #9
0
        public static OverloadsCollection Create(IEmitter emitter, PropertyDeclaration propDeclaration, bool isSetter = false)
        {
            string key = propDeclaration.GetHashCode().ToString() + isSetter.GetHashCode().ToString();
            if (emitter.OverloadsCache.ContainsKey(key))
            {
                return emitter.OverloadsCache[key];
            }

            return new OverloadsCollection(emitter, propDeclaration, isSetter);
        }
예제 #10
0
 public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
 {
     if (propertyDeclaration.HasModifier(Modifiers.Static))
     {
         this.CheckDependency(propertyDeclaration.ReturnType);
         if (!propertyDeclaration.Getter.IsNull)
         {
             propertyDeclaration.Getter.AcceptVisitor(this);
         }
     }
 }
예제 #11
0
		EventDeclaration CreateChangedEventDeclaration (RefactoringContext context, PropertyDeclaration propertyDeclaration)
		{
			return new EventDeclaration {
				Modifiers = propertyDeclaration.HasModifier (Modifiers.Static) ? Modifiers.Public | Modifiers.Static : Modifiers.Public,
				ReturnType = context.CreateShortType("System", "EventHandler"),
				Variables = {
					new VariableInitializer {
						Name = propertyDeclaration.Name + "Changed"
					}
				}
			};
		}
        public static void AddPropertyGuard(PropertyDeclaration property, MethodBodyTransformationContext context, InstructionBlock block, InstructionWriter writer)
        {
            var propertyType = property.PropertyType;
            var methodBody = block.MethodBody;

            var sequence = block.AddInstructionSequence(null, NodePosition.After, null);
            if (sequence == null) return;

            var oldValueVariable =
                block.DefineLocalVariable(propertyType, string.Format("old{0}Value", property.Name));
            var assets = GetTransformationAssets(property.Module);

            writer.AttachInstructionSequence(sequence);
            var isLocationBinding = CheckIfIsLocationBinding(methodBody,assets);
            if (isLocationBinding) {
                writer.AssignValue_LocalVariable(oldValueVariable
                    , () => writer.Call_MethodOnTarget(property.GetGetter()
                        ,
                        () => {
                            //Load the instance parameter of the SetValue method
                            //and convert it to the type
                            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                            //writer.EmitInstructionLoadIndirect(Assets.ObjectTypeSignature);
                            writer.EmitInstructionType(OpCodeNumber.Ldobj, assets.ObjectTypeSignature);
                            writer.EmitConvertFromObject(property.Parent);
                        }
                    )
                );
                //On the location binding the value parameter is at psotion 3
                writer.EmitInstruction(OpCodeNumber.Ldarg_3);
            } else {
                writer.AssignValue_LocalVariable(oldValueVariable,
                                                    () => writer.Get_PropertyValue(property));
                //For a normal property the value parameter is at position 1
                writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            }
            if (propertyType.IsStruct()) {
                writer.EmitInstructionType(OpCodeNumber.Box, propertyType);
            }
            writer.Box_LocalVariableIfNeeded(oldValueVariable);
            var isPrimitive = propertyType.IsPrimitive();
            if (isPrimitive) {
                writer.Compare_Primitives();
            } else {
                //TODO: Try and use the equality operator when present
                writer.Compare_Objects(assets.ObjectEqualsMethod);
            }
            //writer.Leave_IfTrue(_context.LeaveBranchTarget);
            writer.Leave_IfTrue(context.LeaveBranchTarget);
            writer.DetachInstructionSequence();
        }
		static Statement BuildAccessorStatement (RefactoringContext context, PropertyDeclaration pdecl)
		{
			if (pdecl.Setter.IsNull && !pdecl.Getter.IsNull) {
				var field = RemoveBackingStore.ScanGetter (context, pdecl);
				if (field != null) 
					return new ExpressionStatement (new AssignmentExpression (new IdentifierExpression (field.Name), AssignmentOperatorType.Assign, new IdentifierExpression ("value")));
			}
			
			if (!pdecl.Setter.IsNull && pdecl.Getter.IsNull) {
				var field = RemoveBackingStore.ScanSetter (context, pdecl);
				if (field != null) 
					return new ReturnStatement (new IdentifierExpression (field.Name));
			}
			
			return new ThrowStatement (new ObjectCreateExpression (context.CreateShortType ("System", "NotImplementedException")));
		}
		internal static IField GetBackingField (BaseRefactoringContext context, PropertyDeclaration propertyDeclaration)
		{
			// automatic properties always need getter & setter
			if (propertyDeclaration == null || propertyDeclaration.Getter.IsNull || propertyDeclaration.Setter.IsNull || propertyDeclaration.Getter.Body.IsNull || propertyDeclaration.Setter.Body.IsNull)
				return null;
			if (!context.Supports(csharp3) || propertyDeclaration.HasModifier (ICSharpCode.NRefactory.CSharp.Modifiers.Abstract) || ((TypeDeclaration)propertyDeclaration.Parent).ClassType == ClassType.Interface)
				return null;
			var getterField = ScanGetter (context, propertyDeclaration);
			if (getterField == null)
				return null;
			var setterField = ScanSetter (context, propertyDeclaration);
			if (setterField == null)
				return null;
			if (!getterField.Equals(setterField))
				return null;
			return getterField;
		}
예제 #15
0
        protected virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, bool setter)
        {
            var memberResult = this.Emitter.Resolver.ResolveNode(propertyDeclaration, this.Emitter) as MemberResolveResult;

            if (memberResult != null &&
                (memberResult.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.FieldPropertyAttribute") ||
                (propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull)))
            {
                return;
            }

            if (!accessor.IsNull && this.Emitter.GetInline(accessor) == null)
            {
                var p = (PropertyDeclaration)accessor.Parent;
                var overloads = OverloadsCollection.Create(this.Emitter, propertyDeclaration, setter);
                string name = overloads.GetOverloadName();
                this.Write((setter ? "set" : "get") + name);
                this.WriteOpenParentheses();
                if (setter)
                {
                    this.Write("value");
                    this.WriteColon();
                    name = BridgeTypes.ToJsName(p.ReturnType, this.Emitter);
                    name = EmitBlock.HandleType(name);
                    this.Write(name);
                }

                this.WriteCloseParentheses();
                this.WriteColon();

                if (setter)
                {
                    this.Write("void");
                }
                else
                {
                    name = BridgeTypes.ToJsName(p.ReturnType, this.Emitter);
                    name = EmitBlock.HandleType(name);
                    this.Write(name);
                }

                this.WriteSemiColon();
                this.WriteNewLine();
            }
        }
예제 #16
0
        public void Generate(System.Extensions.CodeDom.NamespaceDeclaration ns)
        {
            if (this.Name == null)
            {
                throw new InvalidOperationException("name not set");
            }

            // create class
            ClassDeclaration c = ns.AddClass(DecorateName(this.Name));

            this.Properties = new Hashtable();
            // add fields and properties
            foreach (DictionaryEntry de in this.Fields)
            {
                FieldDeclaration f = c.AddField(de.Value.ToString(), de.Key.ToString());

                PropertyDeclaration p = c.AddProperty(f, true, !ReadOnly, false);
                this.Properties.Add(de, p);
            }
        }
        bool IsInSetter(PropertyDeclaration property)
        {
            if (!property.HasSetRegion)
            {
                return(false);
            }

            int startOffset = textEditor.Document.PositionToOffset(property.SetRegion.StartLocation.Line,
                                                                   property.SetRegion.StartLocation.Column);

            int endOffset = textEditor.Document.PositionToOffset(property.SetRegion.EndLocation.Line,
                                                                 property.SetRegion.EndLocation.Column);

            int selectionEnd = textEditor.SelectionStart + textEditor.SelectionLength;

            return(textEditor.SelectionStart >= startOffset &&
                   textEditor.SelectionStart <= endOffset &&
                   selectionEnd >= startOffset &&
                   selectionEnd <= endOffset);
        }
예제 #18
0
        private OverloadsCollection(IEmitter emitter, PropertyDeclaration propDeclaration, bool isSetter)
        {
            this.Emitter          = emitter;
            this.Name             = propDeclaration.Name;
            this.JsName           = Helpers.GetPropertyRef(propDeclaration, emitter, isSetter, true, true);
            this.AltJsName        = Helpers.GetPropertyRef(propDeclaration, emitter, !isSetter, true, true);
            this.FieldJsName      = propDeclaration.Getter != null && propDeclaration.Getter.Body.IsNull ? emitter.GetEntityName(propDeclaration) : null;
            this.Inherit          = !propDeclaration.HasModifier(Modifiers.Static);
            this.Static           = propDeclaration.HasModifier(Modifiers.Static);
            this.CancelChangeCase = !Helpers.IsFieldProperty(propDeclaration, emitter);
            this.IsSetter         = isSetter;
            this.Member           = this.FindMember(propDeclaration);
            var p = (IProperty)this.Member;

            this.FieldJsName    = Helpers.IsAutoProperty(p) ? (Helpers.IsFieldProperty(p, this.Emitter) ? this.Emitter.GetEntityName(p) : Helpers.GetPropertyRef(p, this.Emitter, true, true, true, false, true)) : null;
            this.TypeDefinition = this.Member.DeclaringTypeDefinition;
            this.Type           = this.Member.DeclaringType;
            this.InitMembers();
            this.Emitter.OverloadsCacheNodes[new Tuple <AstNode, bool>(propDeclaration, isSetter)] = this;
        }
예제 #19
0
        public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
        {
            if (this.Found)
            {
                return;
            }

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

            if (rr != null)
            {
                this.Rules = Contract.Rules.Get(this.Emitter, rr.Member);
            }
            else
            {
                this.Rules = Contract.Rules.Default;
            }

            base.VisitPropertyDeclaration(propertyDeclaration);
        }
예제 #20
0
        internal static IField ScanGetter(RefactoringContext context, PropertyDeclaration propertyDeclaration)
        {
            if (propertyDeclaration.Getter.Body.Statements.Count != 1)
            {
                return(null);
            }
            var returnStatement = propertyDeclaration.Getter.Body.Statements.First() as ReturnStatement;

            if (returnStatement == null)
            {
                return(null);
            }
            var result = context.Resolve(returnStatement.Expression);

            if (result == null || !(result is MemberResolveResult))
            {
                return(null);
            }
            return(((MemberResolveResult)result).Member as IField);
        }
예제 #21
0
        void CSharpPropertyRegionTest(bool parseMethodBodies)
        {
            const string code     = "class T {\n\tint Prop {\n\t\tget { return f; }\n\t\tset { f = value; }\n\t}\n}\n";
            int          line2Pos = code.IndexOf("\tint Prop");
            int          line3Pos = code.IndexOf("\t\tget");
            int          line4Pos = code.IndexOf("\t\tset");

            IParser p = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(code));

            p.ParseMethodBodies = parseMethodBodies;
            p.Parse();
            PropertyDeclaration pd = (PropertyDeclaration)p.CompilationUnit.Children[0].Children[0];

            Assert.AreEqual(new Location(code.IndexOf("{\n\t\tget") - line2Pos + 1, 2), pd.BodyStart);
            Assert.AreEqual(new Location(3, 5), pd.BodyEnd);
            Assert.AreEqual(new Location(code.IndexOf("{ return") - line3Pos + 1, 3), pd.GetRegion.Block.StartLocation);
            Assert.AreEqual(new Location(code.IndexOf("}\n\t\tset") + 1 - line3Pos + 1, 3), pd.GetRegion.Block.EndLocation);
            Assert.AreEqual(new Location(code.IndexOf("{ f =") - line4Pos + 1, 4), pd.SetRegion.Block.StartLocation);
            Assert.AreEqual(new Location(code.IndexOf("}\n\t}") + 1 - line4Pos + 1, 4), pd.SetRegion.Block.EndLocation);
        }
예제 #22
0
파일: Helpers.cs 프로젝트: dmitsov/Bridge
        public static string GetPropertyRef(PropertyDeclaration property, IEmitter emitter, bool isSetter = false, bool noOverload = false, bool ignoreInterface = false, bool withoutTypeParams = false, bool skipPrefix = true)
        {
            ResolveResult resolveResult = emitter.Resolver.ResolveNode(property, emitter) as MemberResolveResult;

            if (resolveResult != null && ((MemberResolveResult)resolveResult).Member != null)
            {
                return(GetPropertyRef(((MemberResolveResult)resolveResult).Member, emitter, isSetter, noOverload, ignoreInterface, withoutTypeParams, skipPrefix));
            }

            string name;

            if (!noOverload)
            {
                var overloads = OverloadsCollection.Create(emitter, property, isSetter);
                return(overloads.GetOverloadName(ignoreInterface, skipPrefix ? null : GetSetOrGet(isSetter), withoutTypeParams));
            }

            name = emitter.GetEntityName(property, true, ignoreInterface);
            return(GetSetOrGet(isSetter, name));
        }
예제 #23
0
        private OverloadsCollection(IEmitter emitter, PropertyDeclaration propDeclaration, bool isSetter, bool isField)
        {
            this.Emitter     = emitter;
            this.IsField     = isField;
            this.Name        = propDeclaration.Name;
            this.JsName      = Helpers.GetPropertyRef(propDeclaration, emitter, isSetter, true, true);
            this.AltJsName   = Helpers.GetPropertyRef(propDeclaration, emitter, !isSetter, true, true);
            this.FieldJsName = propDeclaration.Getter != null && propDeclaration.Getter.Body.IsNull ? emitter.GetEntityName(propDeclaration) : null;
            this.Inherit     = !propDeclaration.HasModifier(Modifiers.Static);
            this.Static      = propDeclaration.HasModifier(Modifiers.Static);
            this.IsSetter    = isSetter;
            this.Member      = this.FindMember(propDeclaration);
            var p = (IProperty)this.Member;

            this.FieldJsName    = this.Emitter.GetEntityName(p);
            this.TypeDefinition = this.Member.DeclaringTypeDefinition;
            this.Type           = this.Member.DeclaringType;
            this.InitMembers();
            this.Emitter.Cache.AddNode(propDeclaration, isSetter, this);
        }
예제 #24
0
        public virtual AttributedNode GetOverridingMethod(IMember baseMember, ClassFinder targetContext)
        {
            AttributedNode node = ConvertMember(baseMember, targetContext);

            node.Modifier &= ~(Modifiers.Virtual | Modifiers.Abstract);
            node.Modifier |= Modifiers.Override;

            if (!baseMember.IsAbstract)
            {
                // replace the method/property body with a call to the base method/property
                MethodDeclaration method = node as MethodDeclaration;
                if (method != null)
                {
                    method.Body.Children.Clear();
                    if (method.TypeReference.Type == "System.Void")
                    {
                        method.Body.AddChild(new ExpressionStatement(CreateForwardingMethodCall(method)));
                    }
                    else
                    {
                        method.Body.AddChild(new ReturnStatement(CreateForwardingMethodCall(method)));
                    }
                }
                PropertyDeclaration property = node as PropertyDeclaration;
                if (property != null)
                {
                    Expression field = new BaseReferenceExpression().Member(property.Name);
                    if (!property.GetRegion.Block.IsNull)
                    {
                        property.GetRegion.Block.Children.Clear();
                        property.GetRegion.Block.Return(field);
                    }
                    if (!property.SetRegion.Block.IsNull)
                    {
                        property.SetRegion.Block.Children.Clear();
                        property.SetRegion.Block.Assign(field, new IdentifierExpression("value"));
                    }
                }
            }
            return(node);
        }
 public static AttributedNode ConvertMember(IProperty p, ClassFinder targetContext)
 {
     if (p.IsIndexer)
     {
         IndexerDeclaration md;
         md = new IndexerDeclaration(ConvertType(p.ReturnType, targetContext),
                                     ConvertParameters(p.Parameters, targetContext),
                                     ConvertModifier(p.Modifiers, targetContext),
                                     ConvertAttributes(p.Attributes, targetContext));
         md.Parameters = ConvertParameters(p.Parameters, targetContext);
         if (p.CanGet)
         {
             md.GetRegion = new PropertyGetRegion(CreateNotImplementedBlock(), null);
         }
         if (p.CanSet)
         {
             md.SetRegion = new PropertySetRegion(CreateNotImplementedBlock(), null);
         }
         return(md);
     }
     else
     {
         PropertyDeclaration md;
         md = new PropertyDeclaration(ConvertModifier(p.Modifiers, targetContext),
                                      ConvertAttributes(p.Attributes, targetContext),
                                      p.Name,
                                      ConvertParameters(p.Parameters, targetContext));
         md.TypeReference = ConvertType(p.ReturnType, targetContext);
         if (p.CanGet)
         {
             md.GetRegion          = new PropertyGetRegion(CreateNotImplementedBlock(), null);
             md.GetRegion.Modifier = ConvertModifier(p.GetterModifiers, null);
         }
         if (p.CanSet)
         {
             md.SetRegion          = new PropertySetRegion(CreateNotImplementedBlock(), null);
             md.SetRegion.Modifier = ConvertModifier(p.SetterModifiers, null);
         }
         return(md);
     }
 }
 public object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
 {
     B.Property m = new B.Property(GetLexicalInfo(propertyDeclaration));
     m.Name      = propertyDeclaration.Name;
     m.Modifiers = ConvertModifier(propertyDeclaration, B.TypeMemberModifiers.Private);
     ConvertAttributes(propertyDeclaration.Attributes, m.Attributes);
     if (currentType != null)
     {
         currentType.Members.Add(m);
     }
     ConvertParameters(propertyDeclaration.Parameters, m.Parameters);
     if (propertyDeclaration.IsIndexer)
     {
         m.Name = "self";
     }
     m.EndSourceLocation = GetLocation(propertyDeclaration.EndLocation);
     m.Type         = ConvertTypeReference(propertyDeclaration.TypeReference);
     m.ExplicitInfo = ConvertInterfaceImplementations(propertyDeclaration.InterfaceImplementations, propertyDeclaration, m);
     if (!propertyDeclaration.IsWriteOnly)
     {
         m.Getter = new B.Method(GetLexicalInfo(propertyDeclaration.GetRegion));
         if (propertyDeclaration.GetRegion != null)
         {
             ConvertAttributes(propertyDeclaration.GetRegion.Attributes, m.Getter.Attributes);
             m.Getter.Modifiers  = ConvertModifier(propertyDeclaration.GetRegion, B.TypeMemberModifiers.None);
             m.Getter.Body       = ConvertMethodBlock(propertyDeclaration.GetRegion.Block);
             m.Getter.ReturnType = m.Type;
         }
     }
     if (!propertyDeclaration.IsReadOnly)
     {
         m.Setter = new B.Method(GetLexicalInfo(propertyDeclaration.SetRegion));
         if (propertyDeclaration.SetRegion != null)
         {
             ConvertAttributes(propertyDeclaration.SetRegion.Attributes, m.Setter.Attributes);
             m.Setter.Modifiers = ConvertModifier(propertyDeclaration.SetRegion, B.TypeMemberModifiers.None);
             m.Setter.Body      = ConvertMethodBlock(propertyDeclaration.SetRegion.Block);
         }
     }
     return(m);
 }
예제 #27
0
            public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
            {
                if (propertyDeclaration.HasModifier(Modifiers.Static) ||
                    propertyDeclaration.HasModifier(Modifiers.Virtual) ||
                    propertyDeclaration.HasModifier(Modifiers.Override) ||
                    propertyDeclaration.HasModifier(Modifiers.New) ||
                    propertyDeclaration.Attributes.Any())
                {
                    return;
                }

                if (IsEmpty(propertyDeclaration.Setter) && IsEmpty(propertyDeclaration.Getter))
                {
                    return;
                }


                var resolved = ctx.Resolve(propertyDeclaration) as MemberResolveResult;

                if (resolved == null || SkipMember(resolved.Member))
                {
                    return;
                }
                var isImplementingInterface = resolved.Member.ImplementedInterfaceMembers.Any();

                if (isImplementingInterface)
                {
                    return;
                }

                if (!propertyDeclaration.Getter.IsNull && StaticVisitor.UsesNotStaticMember(ctx, propertyDeclaration.Getter.Body) ||
                    !propertyDeclaration.Setter.IsNull && StaticVisitor.UsesNotStaticMember(ctx, propertyDeclaration.Setter.Body))
                {
                    return;
                }

                AddIssue(propertyDeclaration.NameToken.StartLocation, propertyDeclaration.NameToken.EndLocation,
                         string.Format(ctx.TranslateString("Property '{0}' can be made static."), propertyDeclaration.Name),
                         string.Format(ctx.TranslateString("Make '{0}' static"), propertyDeclaration.Name),
                         script => script.ChangeModifier(propertyDeclaration, propertyDeclaration.Modifiers | Modifiers.Static));
            }
        public override void Generate()
        {
            if (this.Name == null)
            {
                throw new InvalidOperationException("name not set");
            }

            // create class
            ClassDeclaration c = this.NamespaceDeclaration.AddClass(this.DataName);

            this.Properties = new Hashtable();
            // add fields and properties
            foreach (DictionaryEntry de in this.Fields)
            {
                FieldDeclaration f = c.AddField(de.Value.ToString(), de.Key.ToString());

                PropertyDeclaration p = c.AddProperty(f, true, !ReadOnly, false);
                this.Properties.Add(de, p);
            }
            this.Compile();
        }
예제 #29
0
        internal static IField ScanSetter(RefactoringContext context, PropertyDeclaration propertyDeclaration)
        {
            if (propertyDeclaration.Setter.Body.Statements.Count != 1)
            {
                return(null);
            }
            var setAssignment = propertyDeclaration.Setter.Body.Statements.First() as ExpressionStatement;
            var assignment    = setAssignment != null ? setAssignment.Expression as AssignmentExpression : null;

            if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign)
            {
                return(null);
            }
            var result = context.Resolve(assignment.Left);

            if (result == null || !(result is MemberResolveResult))
            {
                return(null);
            }
            return(((MemberResolveResult)result).Member as IField);
        }
예제 #30
0
        public static PropertyDeclaration ConvertMember(IProperty p, ClassFinder targetContext)
        {
            PropertyDeclaration md = new PropertyDeclaration(ConvertModifier(p.Modifiers, targetContext),
                                                             ConvertAttributes(p.Attributes, targetContext),
                                                             p.Name,
                                                             ConvertParameters(p.Parameters, targetContext));

            md.TypeReference            = ConvertType(p.ReturnType, targetContext);
            md.InterfaceImplementations = ConvertInterfaceImplementations(p.InterfaceImplementations, targetContext);
            if (p.CanGet)
            {
                md.GetRegion          = new PropertyGetRegion(p.Modifiers.HasFlag(ModifierEnum.Extern) ? null : CreateNotImplementedBlock(), null);
                md.GetRegion.Modifier = ConvertModifier(p.GetterModifiers, null);
            }
            if (p.CanSet)
            {
                md.SetRegion          = new PropertySetRegion(p.Modifiers.HasFlag(ModifierEnum.Extern) ? null : CreateNotImplementedBlock(), null);
                md.SetRegion.Modifier = ConvertModifier(p.SetterModifiers, null);
            }
            return(md);
        }
        public override object TrackedVisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
        {
            if (this.memberToFind is IProperty)
            {
                // If we are looking for a specified property:
                // find out if this is the one by comparing the location.
                if (propertyDeclaration.StartLocation.X == this.memberToFind.Region.BeginColumn &&
                    propertyDeclaration.StartLocation.Y == this.memberToFind.Region.BeginLine)
                {
                    data = true;
                }
            }
            else if (this.memberToFind is IField)
            {
                // If we are looking for a specifield field:
                // store the property info for future reference.
                data = propertyDeclaration;
            }

            return(base.TrackedVisitPropertyDeclaration(propertyDeclaration, data));
        }
예제 #32
0
        public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
        {
            if (!IsClassType(ClassType.Interface) && (propertyDeclaration.Modifier & Modifiers.Visibility) == 0)
            {
                propertyDeclaration.Modifier |= Modifiers.Public;
            }

            if (propertyDeclaration.HasSetRegion)
            {
                string from = "Value";
                if (propertyDeclaration.SetRegion.Parameters.Count > 0)
                {
                    ParameterDeclarationExpression p = propertyDeclaration.SetRegion.Parameters[0];
                    from            = p.ParameterName;
                    p.ParameterName = "Value";
                }
                propertyDeclaration.SetRegion.AcceptVisitor(new RenameIdentifierVisitor(from, "value", StringComparer.InvariantCultureIgnoreCase), null);
            }

            return(base.VisitPropertyDeclaration(propertyDeclaration, data));
        }
예제 #33
0
        public PropertyTreeNode( PropertyDeclaration property )
            : base( property, TreeViewImage.Property, property.Visibility )
        {
            this.property = property;


            StringBuilder name = new StringBuilder( 255 );
            this.property = property;
            name.Append( property.Name );

            bool first = true;
            if ( property.Parameters.Count > 0 )
            {
                name.Append( "(" );
                foreach ( ITypeSignature parameter in property.Parameters )
                {
                    if ( !first )
                    {
                        name.Append( ", " );
                    }
                    else
                    {
                        name.Append( ' ' );
                        first = false;
                    }

                    name.Append( ' ' );
                    name.Append( parameter.ToString() );
                }
                name.Append( " )" );
            }

            name.Append( " : " );

            name.Append( property.PropertyType.ToString() );

            this.Text = name.ToString();

            this.EnableLatePopulate();
        }
예제 #34
0
        public override bool TryParse(TokenStack tokens, out GraphNode node)
        {
            var typeDeclarationSyntax = new TypeDeclarationSyntax();

            if (typeDeclarationSyntax.TryParse(tokens, out GraphNode typeDeclaration))
            {
                if (tokens.Expect(TokenType.Identifier))
                {
                    var identifier = tokens.Pop();

                    if (tokens.Expect(TokenType.AsKeyword))
                    {
                        var asKeyword = tokens.Pop();

                        if (typeDeclarationSyntax.TryParse(tokens, out GraphNode asTypeDeclaration))
                        {
                            node = new PropertyDeclaration(new[] { identifier }, identifier.Value, (TypeDeclaration)typeDeclaration, (TypeDeclaration)asTypeDeclaration);
                            return(true);
                        }
                        else
                        {
                            // TODO: syntax error
                        }
                    }
                    else
                    {
                        node = new PropertyDeclaration(new[] { identifier }, identifier.Value, (TypeDeclaration)typeDeclaration);
                        return(true);
                    }
                }
                else
                {
                    // TODO: syntax error
                }
            }

            // TODO: syntax error
            node = null;
            return(false);
        }
예제 #35
0
        private CSharpSyntaxNode ToGetSet(PropertyDeclaration node)
        {
            List <Node> modifiers = node.Modifiers.FindAll(n => n.Kind != NodeKind.ReadonlyKeyword);

            PropertyDeclarationSyntax csProperty = SyntaxFactory
                                                   .PropertyDeclaration(node.Type.ToCsNode <TypeSyntax>(), node.Name.Text)
                                                   .AddModifiers(modifiers.ToCsNodes <SyntaxToken>());

            if (node.JsDoc.Count > 0)
            {
                csProperty = csProperty.WithLeadingTrivia(SyntaxFactory.Trivia(node.JsDoc[0].ToCsNode <DocumentationCommentTriviaSyntax>()));
            }

            //GetAccess
            AccessorDeclarationSyntax csGetAccess = SyntaxFactory
                                                    .AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                                                    .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));

            //    if (node.Initializer != null)
            //    {
            //        csGetAccess = csGetAccess.WithBody(SyntaxFactory.Block(SyntaxFactory.ReturnStatement(node.Initializer.ToCsNode<ExpressionSyntax>())));
            //    }
            csProperty = csProperty.AddAccessorListAccessors(csGetAccess);

            //SetsAccess
            if ((node.IsReadonly && !node.IsAbstract) || (!node.IsReadonly))
            {
                AccessorDeclarationSyntax csSetAccess = SyntaxFactory
                                                        .AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                                                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));

                if (node.IsReadonly)
                {
                    csSetAccess = csSetAccess.AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword));
                }
                csProperty = csProperty.AddAccessorListAccessors(csSetAccess);
            }

            return(csProperty);
        }
예제 #36
0
        /// <summary>
        /// 向viewModel添加属性
        /// </summary>
        /// <param name="type"></param>
        /// <param name="source"></param>
        /// <param name="beforeNode"></param>
        /// <param name="classNode"></param>
        /// <returns></returns>
        private static AstNode InsertPropertyToClassNode(Type type, string source, AstNode beforeNode, TypeDeclaration classNode)
        {
            var propertyNode = classNode.Descendants.OfType <PropertyDeclaration>().Where(x => x.Name == source).FirstOrDefault();

            if (propertyNode != null)
            {
                classNode.Members.Remove(propertyNode);
            }

            var typeName = TypeStringName(type);

            propertyNode            = new PropertyDeclaration();
            propertyNode.Modifiers  = Modifiers.Protected;
            propertyNode.ReturnType = new PrimitiveType(string.Format("{0}.{1}", type.Namespace, typeName));
            propertyNode.Name       = source;

            #region Getter
            var accessor      = propertyNode.Getter = new Accessor();
            var body          = accessor.Body = new BlockStatement();
            var expression    = new IdentifierExpression("GetValue");
            var typeArguement = new MemberType(new SimpleType(type.Namespace), typeName);
            expression.TypeArguments.Add(typeArguement);
            Statement statement = new ReturnStatement(new InvocationExpression(expression, new IdentifierExpression(GetSourceKeyWord(source))));
            body.Add(statement);
            #endregion

            #region Setter
            accessor      = propertyNode.Setter = new Accessor();
            body          = accessor.Body = new BlockStatement();
            expression    = new IdentifierExpression("SetValue");
            typeArguement = new MemberType(new SimpleType(type.Namespace), typeName);
            expression.TypeArguments.Add(typeArguement);
            statement = new ExpressionStatement(new InvocationExpression(expression, new IdentifierExpression(GetSourceKeyWord(source)), new IdentifierExpression("value")));
            body.Add(statement);
            #endregion

            classNode.InsertChildBefore(beforeNode, propertyNode, Roles.TypeMemberRole);
            return(propertyNode);
        }
        public void PropertyDeclaration_WithOnlySetterBody()
        {
            var sst = new PropertyDeclaration
            {
                Name = Names.Property("get set [PropertyType,P] [DeclaringType,P].P()"),
                Set  =
                {
                    new BreakStatement()
                }
            };

            AssertPrint(
                sst,
                "PropertyType P",
                "{",
                "    get;",
                "    set",
                "    {",
                "        break;",
                "    }",
                "}");
        }
예제 #38
0
		public override IUnresolvedEntity VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
		{
			DefaultUnresolvedProperty p = new DefaultUnresolvedProperty(currentTypeDefinition, propertyDeclaration.Name);
			p.Region = MakeRegion(propertyDeclaration);
			p.BodyRegion = MakeBraceRegion(propertyDeclaration);
			ApplyModifiers(p, propertyDeclaration.Modifiers);
			p.ReturnType = propertyDeclaration.ReturnType.ToTypeReference();
			ConvertAttributes(p.Attributes, propertyDeclaration.Attributes);
			if (!propertyDeclaration.PrivateImplementationType.IsNull) {
				p.Accessibility = Accessibility.None;
				p.IsExplicitInterfaceImplementation = true;
				p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
					p.EntityType, propertyDeclaration.PrivateImplementationType.ToTypeReference(), p.Name));
			}
			p.Getter = ConvertAccessor(propertyDeclaration.Getter, p, "get_");
			p.Setter = ConvertAccessor(propertyDeclaration.Setter, p, "set_");
			currentTypeDefinition.Members.Add(p);
			if (interningProvider != null) {
				p.ApplyInterningProvider(interningProvider);
			}
			return p;
		}
        PropertyDeclaration CreateProperty(IField field, bool createGetter, bool createSetter)
        {
            IProject project = field.Compilation.GetProject();

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

            CodeGenerator          codeGenerator = project.LanguageBinding.CodeGenerator;
            string                 name          = codeGenerator.GetPropertyName(field.Name);
            AlFullParseInformation tempParseInformation;
            PropertyDeclaration    property = new PropertyDeclaration()
            {
                Modifiers = ConvertModifier(field.GetDeclaration(out tempParseInformation).Modifiers, field.DeclaringTypeDefinition),
                Name      = name
            };

            property.ReturnType = ConvertType(field.ReturnType);
            if (createGetter)
            {
                property.Getter = new Accessor()
                {
                    Body = new BlockStatement()
                };
                property.Getter.Body.Add(new ReturnStatement(new IdentifierExpression(field.Name)));
            }
            if (createSetter)
            {
                property.Setter = new Accessor()
                {
                    Body = new BlockStatement()
                };
                property.Setter.Body.Add(new AssignmentExpression(new IdentifierExpression(field.Name), new IdentifierExpression("value")));
            }

            property.Modifiers = Modifiers.Public | (property.Modifiers & Modifiers.Static);
            return(property);
        }
예제 #40
0
        public static bool HasFieldAttribute(PropertyDeclaration property, IEmitter emitter)
        {
            foreach (var attributeSection in property.Attributes)
            {
                foreach (var attribute in attributeSection.Attributes)
                {
                    if (CheckName(attribute.Type, ATTRIBUTE_FIELD_ALL_NAMES))
                    {
                        return(true);
                    }

                    var resolveResult = emitter.Resolver.ResolveNode(attribute, emitter);

                    if (CheckName(resolveResult, ATTRIBUTE_FIELD_LONG_NAMES))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #41
0
        private static void GetPropertyAccessorDefinitions(PropertyDeclaration propertyDeclaration, out MethodDefDeclaration getMethodDef, out MethodDefDeclaration setMethodDef)
        {
            getMethodDef = null;
            setMethodDef = null;
            foreach (MethodSemanticDeclaration methodSemanticDef in propertyDeclaration.Members)
            {
                MethodDefDeclaration methodDef = methodSemanticDef.Method;

                if (methodDef.Name.StartsWith("get_"))
                {
                    getMethodDef = methodDef;
                }
                else if (methodDef.Name.StartsWith("set_"))
                {
                    setMethodDef = methodDef;
                }
                else
                {
                    throw new InvalidOperationException("Found a NotifyPropertyChanged attribute on something other than a property");
                }
            }
        }
예제 #42
0
        static Statement BuildAccessorStatement(RefactoringContext context, PropertyDeclaration pdecl)
        {
            if (pdecl.Setter.IsNull && !pdecl.Getter.IsNull)
            {
                var field = RemoveBackingStoreAction.ScanGetter(context, pdecl);
                if (field != null)
                {
                    return(new ExpressionStatement(new AssignmentExpression(new IdentifierExpression(field.Name), AssignmentOperatorType.Assign, new IdentifierExpression("value"))));
                }
            }

            if (!pdecl.Setter.IsNull && pdecl.Getter.IsNull)
            {
                var field = RemoveBackingStoreAction.ScanSetter(context, pdecl);
                if (field != null)
                {
                    return(new ReturnStatement(new IdentifierExpression(field.Name)));
                }
            }

            return(new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException"))));
        }
예제 #43
0
        public static CSProperty Parse(PropertyDeclaration propertyNode)
        {
            CSProperty returnValue = new CSProperty();

            returnValue.ProtectionLevel = EnumProtectionLevel.Private;
            if ((propertyNode.Modifiers & Modifiers.Public) == Modifiers.Public)
            {
                returnValue.ProtectionLevel = EnumProtectionLevel.Public;
            }
            else if ((propertyNode.Modifiers & Modifiers.Private) == Modifiers.Private)
            {
                returnValue.ProtectionLevel = EnumProtectionLevel.Private;
            }
            else if ((propertyNode.Modifiers & Modifiers.Protected) == Modifiers.Protected)
            {
                returnValue.ProtectionLevel = EnumProtectionLevel.Protected;
            }
            else if ((propertyNode.Modifiers & Modifiers.Internal) == Modifiers.Internal)
            {
                returnValue.ProtectionLevel = EnumProtectionLevel.Internal;
            }
            string typeName;
            string typeNamespace;

            DotNetParserHelper.SplitType(propertyNode.ReturnType.ToString(), out typeName, out typeNamespace);
            returnValue.TypeName      = typeName;
            returnValue.TypeNamespace = typeNamespace;
            returnValue.PropertyName  = propertyNode.Name;
            foreach (var attributeSectionNode in propertyNode.Attributes)
            {
                foreach (var attributeNode in attributeSectionNode.Attributes)
                {
                    var attribute = CSAttribute.Parse(attributeNode);
                    returnValue.AttributeList.Add(attribute);
                }
            }
            return(returnValue);
        }
예제 #44
0
        public Declaration(TypeDeclaration typeDeclaration, string classifier)
        {
            name            = typeDeclaration.Name;
            this.classifier = classifier;
            this.startLine  = typeDeclaration.StartLocation.Line;
            this.endLine    = typeDeclaration.EndLocation.Line;

            extractAttributes(typeDeclaration.Attributes);


            foreach (AstNode node in typeDeclaration.Children)
            {
                ConstructorDeclaration c = node as ConstructorDeclaration;
                if (c != null)
                {
                    countMethods(c.Name);

                    extractAttributes(c.Attributes);
                    methods.Add(new Method(c.Name, methodCnt[c.Name], c.StartLocation.Line, c.EndLocation.Line));
                }
                MethodDeclaration d = node as MethodDeclaration;
                if (d != null)
                {
                    countMethods(d.Name);

                    extractAttributes(d.Attributes);
                    methods.Add(new Method(d.Name, methodCnt[d.Name], d.StartLocation.Line, d.EndLocation.Line));
                }
                PropertyDeclaration p = node as PropertyDeclaration;
                if (p != null)
                {
                    countMethods(p.Name);

                    extractAttributes(p.Attributes);
                    methods.Add(new Method(p.Name, methodCnt[p.Name], p.StartLocation.Line, p.EndLocation.Line));
                }
            }
        }
예제 #45
0
        public static bool IsFieldProperty(PropertyDeclaration property, IEmitter emitter)
        {
            ResolveResult resolveResult = emitter.Resolver.ResolveNode(property, emitter) as MemberResolveResult;

            if (resolveResult != null && ((MemberResolveResult)resolveResult).Member != null)
            {
                return(IsFieldProperty(((MemberResolveResult)resolveResult).Member, emitter));
            }

            string name  = "Bridge.FieldProperty";
            string name1 = name + "Attribute";

            foreach (var i in property.Attributes)
            {
                foreach (var j in i.Attributes)
                {
                    if (j.Type.ToString() == name || j.Type.ToString() == name1)
                    {
                        return(true);
                    }
                    resolveResult = emitter.Resolver.ResolveNode(j, emitter);
                    if (resolveResult != null && resolveResult.Type != null && resolveResult.Type.FullName == name1)
                    {
                        return(true);
                    }
                }
            }

            if (!emitter.AssemblyInfo.AutoPropertyToField)
            {
                return(false);
            }

            var typeDef = emitter.GetTypeDefinition();
            var propDef = typeDef.Properties.FirstOrDefault(p => p.Name == property.Name);

            return(Helpers.IsAutoPropertyOfDefinition(propDef));
        }
예제 #46
0
        public void CallInternalMethod()
        {
            string program  = TestUtil.GetInput();
            string expected = TestUtil.GetExpected();

            CompilationUnit      cu = TestUtil.ParseProgram(program);
            NamespaceDeclaration ns = (NamespaceDeclaration)cu.Children[0];
            TypeDeclaration      ty = (TypeDeclaration)ns.Children[0];

            PropertyDeclaration property = new PropertyDeclaration(Modifiers.Public, null, "Name", null);

            property.TypeReference = new TypeReference("String");
            property.SetRegion     = new PropertySetRegion(new BlockStatement(), null);
            ty.AddChild(property);

            TypesVisitor typesVisitor = new TypesVisitor();

            typesVisitor.CodeBase = CodeBase;
            typesVisitor.VisitCompilationUnit(cu, null);

            VisitCompilationUnit(cu, null);
            TestUtil.CodeEqual(expected, TestUtil.GenerateCode(cu));
        }
예제 #47
0
		public static CSProperty Parse(PropertyDeclaration propertyNode)
		{
			CSProperty returnValue = new CSProperty();
			returnValue.ProtectionLevel = EnumProtectionLevel.Private;
			if ((propertyNode.Modifiers & Modifiers.Public) == Modifiers.Public)
			{
				returnValue.ProtectionLevel = EnumProtectionLevel.Public;
			}
			else if ((propertyNode.Modifiers & Modifiers.Private) == Modifiers.Private)
			{
				returnValue.ProtectionLevel = EnumProtectionLevel.Private;
			}
			else if ((propertyNode.Modifiers & Modifiers.Protected) == Modifiers.Protected)
			{
				returnValue.ProtectionLevel = EnumProtectionLevel.Protected;
			}
			else if ((propertyNode.Modifiers & Modifiers.Internal) == Modifiers.Internal)
			{
				returnValue.ProtectionLevel = EnumProtectionLevel.Internal;
			}
			string typeName;
			string typeNamespace;
			DotNetParserHelper.SplitType(propertyNode.ReturnType.ToString(), out typeName, out typeNamespace);
			returnValue.TypeName = typeName;
			returnValue.TypeNamespace = typeNamespace;
			returnValue.PropertyName = propertyNode.Name;
			foreach (var attributeSectionNode in propertyNode.Attributes)
			{
				foreach (var attributeNode in attributeSectionNode.Attributes)
				{
					var attribute = CSAttribute.Parse(attributeNode);
					returnValue.AttributeList.Add(attribute);
				}
			}
			return returnValue;
		}
예제 #48
0
 public void AddProperties()
 {
     NamespaceDeclaration nsdecl = new NamespaceDeclaration("Test");
     ClassDeclaration cdecl = nsdecl.AddClass("Customer");
     FieldDeclaration lastName = new FieldDeclaration("_lastName", "System.String");
     PropertyDeclaration propdecl = new PropertyDeclaration("LastName", lastName, typeof(string));
     cdecl.AddProperty(propdecl);
     PropertyDeclaration firstName = cdecl.AddProperty("FirstName", "_firstName", typeof(string));
     PropertyDeclaration duplicateFirstName = cdecl.AddProperty("FirstName", "_firstName", typeof(string));
     Assert.AreEqual(firstName, duplicateFirstName);
     cdecl.AddProperty("DateOfBirth", "_dateOfBirth", typeof(DateTime), true);
     cdecl.AddProperty("Age", "_age", new CodeDomTypeReference(typeof(int)));
     cdecl.AddProperty("Items", "_items", "System.Collections.Generic.List", "System.String");
     using (DomTester dom = new DomTester(nsdecl))
     {
         Assert.IsTrue(dom.ContainsType("Test.Customer"));
         Assert.IsTrue(dom.ContainsProperty("Test.Customer", "FirstName"));
         Assert.IsTrue(dom.ContainsProperty("Test.Customer", "LastName"));
         Assert.IsTrue(dom.ContainsProperty("Test.Customer", "DateOfBirth"));
         Assert.IsTrue(dom.ContainsProperty("Test.Customer", "Age"));
         Assert.IsTrue(dom.ContainsProperty("Test.Customer", "Items"));
     }
     new CodeBuilder().GenerateCode(Console.Out, nsdecl);
 }
예제 #49
0
		public override void VisitPropertyDeclaration (PropertyDeclaration propertyDeclaration)
		{
			if (!propertyDeclaration.LBraceToken.IsNull)
				AddFolding (GetEndOfPrev(propertyDeclaration.LBraceToken),
				            propertyDeclaration.RBraceToken.EndLocation, true);
			base.VisitPropertyDeclaration (propertyDeclaration);
		}
예제 #50
0
		public void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
		{
			StartNode(propertyDeclaration);
			WriteAttributes(propertyDeclaration.Attributes);
			WriteModifiers(propertyDeclaration.ModifierTokens);
			propertyDeclaration.ReturnType.AcceptVisitor(this);
			Space();
			WritePrivateImplementationType(propertyDeclaration.PrivateImplementationType);
			propertyDeclaration.NameToken.AcceptVisitor(this);
			OpenBrace(policy.PropertyBraceStyle);
			// output get/set in their original order
			foreach (AstNode node in propertyDeclaration.Children) {
				if (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole) {
					node.AcceptVisitor(this);
				}
			}
			CloseBrace(policy.PropertyBraceStyle);
			NewLine();
			EndNode(propertyDeclaration);
		}
예제 #51
0
			public override void Visit (Property p)
			{
				PropertyDeclaration newProperty = new PropertyDeclaration ();
				
				var location = LocationsBag.GetMemberLocation (p);
				AddModifiers (newProperty, location);
				
				newProperty.AddChild ((INode)p.TypeName.Accept (this), AbstractNode.Roles.ReturnType);
				newProperty.AddChild (new Identifier (p.MemberName.Name, Convert (p.MemberName.Location)), AbstractNode.Roles.Identifier);
				if (location != null)
					newProperty.AddChild (new CSharpTokenNode (Convert (location[0]), 1), MethodDeclaration.Roles.LBrace);
				
				if (p.Get != null) {
					MonoDevelop.CSharp.Dom.Accessor getAccessor = new MonoDevelop.CSharp.Dom.Accessor ();
					var getLocation = LocationsBag.GetMemberLocation (p.Get);
					AddModifiers (getAccessor, getLocation);
					getAccessor.AddChild (new CSharpTokenNode (Convert (p.Get.Location), "get".Length), PropertyDeclaration.Roles.Keyword);
					
					if (p.Get.Block != null) {
						getAccessor.AddChild ((INode)p.Get.Block.Accept (this), MethodDeclaration.Roles.Body);
					} else {
						if (getLocation != null && getLocation.Count > 0)
							newProperty.AddChild (new CSharpTokenNode (Convert (getLocation[0]), 1), MethodDeclaration.Roles.Semicolon);
					}
					newProperty.AddChild (getAccessor, PropertyDeclaration.PropertyGetRole);
				}
				
				if (p.Set != null) {
					MonoDevelop.CSharp.Dom.Accessor setAccessor = new MonoDevelop.CSharp.Dom.Accessor ();
					var setLocation = LocationsBag.GetMemberLocation (p.Set);
					AddModifiers (setAccessor, setLocation);
					setAccessor.AddChild (new CSharpTokenNode (Convert (p.Set.Location), "set".Length), PropertyDeclaration.Roles.Keyword);
					
					if (p.Set.Block != null) {
						setAccessor.AddChild ((INode)p.Set.Block.Accept (this), MethodDeclaration.Roles.Body);
					} else {
						if (setLocation != null && setLocation.Count > 0)
							newProperty.AddChild (new CSharpTokenNode (Convert (setLocation[0]), 1), MethodDeclaration.Roles.Semicolon);
					}
					newProperty.AddChild (setAccessor, PropertyDeclaration.PropertySetRole);
				}
				if (location != null)
					newProperty.AddChild (new CSharpTokenNode (Convert (location[1]), 1), MethodDeclaration.Roles.RBrace);
				
				typeStack.Peek ().AddChild (newProperty, TypeDeclaration.Roles.Member);
			}
		public virtual void VisitPropertyDeclaration (PropertyDeclaration propertyDeclaration)
		{
			VisitChildren (propertyDeclaration);
		}
예제 #53
0
			public override void Visit(Property p)
			{
				var newProperty = new PropertyDeclaration();
				AddAttributeSection(newProperty, p);
				var location = LocationsBag.GetMemberLocation(p);
				AddModifiers(newProperty, location);
				newProperty.AddChild(ConvertToType(p.TypeExpression), Roles.Type);
				AddExplicitInterface(newProperty, p.MemberName);
				newProperty.AddChild(Identifier.Create(p.MemberName.Name, Convert(p.Location)), Roles.Identifier);
				
				if (location != null && location.Count > 0)
					newProperty.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBrace), Roles.LBrace);
				
				Accessor getAccessor = null;
				if (p.Get != null) {
					getAccessor = new Accessor();
					AddAttributeSection(getAccessor, p.Get);
					var getLocation = LocationsBag.GetMemberLocation(p.Get);
					AddModifiers(getAccessor, getLocation);
					getAccessor.AddChild(new CSharpTokenNode(Convert(p.Get.Location), PropertyDeclaration.GetKeywordRole), PropertyDeclaration.GetKeywordRole);
					
					if (p.Get.Block != null) {
						getAccessor.AddChild((BlockStatement)p.Get.Block.Accept(this), Roles.Body);
					} else {
						if (getLocation != null && getLocation.Count > 0)
							getAccessor.AddChild(new CSharpTokenNode(Convert(getLocation [0]), Roles.Semicolon), Roles.Semicolon);
					}
				}
				
				Accessor setAccessor = null;
				if (p.Set != null) {
					setAccessor = new Accessor();
					AddAttributeSection(setAccessor, p.Set);
					var setLocation = LocationsBag.GetMemberLocation(p.Set);
					AddModifiers(setAccessor, setLocation);
					setAccessor.AddChild(new CSharpTokenNode(Convert(p.Set.Location), PropertyDeclaration.SetKeywordRole), PropertyDeclaration.SetKeywordRole);
					
					if (p.Set.Block != null) {
						setAccessor.AddChild((BlockStatement)p.Set.Block.Accept(this), Roles.Body);
					} else {
						if (setLocation != null && setLocation.Count > 0)
							setAccessor.AddChild(new CSharpTokenNode(Convert(setLocation [0]), Roles.Semicolon), Roles.Semicolon);
					}
				}
				if (getAccessor != null && setAccessor != null) {
					if (getAccessor.StartLocation < setAccessor.StartLocation) {
						newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole);
						newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole);
					} else {
						newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole);
						newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole);
					}
				} else {
					if (getAccessor != null)
						newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole);
					if (setAccessor != null)
						newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole);
				}
				
				if (location != null && location.Count > 1) {
					newProperty.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBrace), Roles.RBrace);
				} else {
					// parser error, set end node to max value.
					newProperty.AddChild(new ErrorNode(), Roles.Error);
				}
				
				typeStack.Peek().AddChild(newProperty, Roles.TypeMemberRole);
			}
예제 #54
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);
        }
		PropertyDeclaration CreateProperty(IField field, bool createGetter, bool createSetter)
		{
			IProject project = field.Compilation.GetProject();
			if (project == null)
				return null;
			
			CodeGenerator codeGenerator = project.LanguageBinding.CodeGenerator;
			string name = codeGenerator.GetPropertyName(field.Name);
			CSharpFullParseInformation tempParseInformation;
			PropertyDeclaration property = new PropertyDeclaration()
			{
				Modifiers = ConvertModifier(field.GetDeclaration(out tempParseInformation).Modifiers, field.DeclaringTypeDefinition),
				Name = name
			};
			property.ReturnType = ConvertType(field.ReturnType);
			if (createGetter) {
				property.Getter = new Accessor()
				{
					Body = new BlockStatement()
				};
				property.Getter.Body.Add(new ReturnStatement(new IdentifierExpression(field.Name)));
			}
			if (createSetter) {
				property.Setter = new Accessor()
				{
					Body = new BlockStatement()
				};
				property.Setter.Body.Add(new AssignmentExpression(new IdentifierExpression(field.Name), new IdentifierExpression("value")));
			}
			
			property.Modifiers = Modifiers.Public | (property.Modifiers & Modifiers.Static);
			return property;
		}
예제 #56
0
		internal static IField ScanGetter (RefactoringContext context, PropertyDeclaration propertyDeclaration)
		{
			if (propertyDeclaration.Getter.Body.Statements.Count != 1)
				return null;
			var returnStatement = propertyDeclaration.Getter.Body.Statements.First () as ReturnStatement;
			if (returnStatement == null)
				return null;
			var result = context.Resolve (returnStatement.Expression);
			if (result == null || !(result is MemberResolveResult))
				return null;
			return ((MemberResolveResult)result).Member as IField;
		}
예제 #57
0
		internal static IField ScanSetter (RefactoringContext context, PropertyDeclaration propertyDeclaration)
		{
			if (propertyDeclaration.Setter.Body.Statements.Count != 1)
				return null;
			var setAssignment = propertyDeclaration.Setter.Body.Statements.First () as ExpressionStatement;
			var assignment = setAssignment != null ? setAssignment.Expression as AssignmentExpression : null;
			if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign)
				return null;
			var result = context.Resolve (assignment.Left);
			if (result == null || !(result is MemberResolveResult))
				return null;
			return ((MemberResolveResult)result).Member as IField;
		}
			public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
			{
				FindIssuesInNode(propertyDeclaration.Setter, propertyDeclaration.Setter.Body);
			}
예제 #59
0
파일: CSharpParser.cs 프로젝트: N3X15/ILSpy
			public override void Visit (Property p)
			{
				PropertyDeclaration newProperty = new PropertyDeclaration ();
				AddAttributeSection (newProperty, p);
				var location = LocationsBag.GetMemberLocation (p);
				AddModifiers (newProperty, location);
				newProperty.AddChild (ConvertToType (p.TypeName), AstNode.Roles.Type);
				if (p.MemberName.Left != null) {
					newProperty.AddChild (ConvertToType (p.MemberName.Left), PropertyDeclaration.PrivateImplementationTypeRole);
					var privateImplTypeLoc = LocationsBag.GetLocations (p.MemberName.Left);
					if (privateImplTypeLoc != null)
						newProperty.AddChild (new CSharpTokenNode (Convert (privateImplTypeLoc[0]), 1), MethodDeclaration.Roles.Dot);
				}
				
				newProperty.AddChild (Identifier.Create (p.MemberName.Name, Convert (p.Location)), PropertyDeclaration.Roles.Identifier);
				
				if (location != null)
					newProperty.AddChild (new CSharpTokenNode (Convert (location[0]), 1), MethodDeclaration.Roles.LBrace);
				
				Accessor getAccessor = null;
				if (p.Get != null) {
					getAccessor = new Accessor ();
					AddAttributeSection (getAccessor, p.Get);
					var getLocation = LocationsBag.GetMemberLocation (p.Get);
					AddModifiers (getAccessor, getLocation);
					getAccessor.AddChild (new CSharpTokenNode (Convert (p.Get.Location), "get".Length), PropertyDeclaration.Roles.Keyword);
					
					if (p.Get.Block != null) {
						getAccessor.AddChild ((BlockStatement)p.Get.Block.Accept (this), MethodDeclaration.Roles.Body);
					} else {
						if (getLocation != null && getLocation.Count > 0)
							getAccessor.AddChild (new CSharpTokenNode (Convert (getLocation[0]), 1), MethodDeclaration.Roles.Semicolon);
					}
				}
				
				Accessor setAccessor = null;
				if (p.Set != null) {
					setAccessor = new Accessor ();
					AddAttributeSection (setAccessor, p.Set);
					var setLocation = LocationsBag.GetMemberLocation (p.Set);
					AddModifiers (setAccessor, setLocation);
					setAccessor.AddChild (new CSharpTokenNode (Convert (p.Set.Location), "set".Length), PropertyDeclaration.Roles.Keyword);
					
					if (p.Set.Block != null) {
						setAccessor.AddChild ((BlockStatement)p.Set.Block.Accept (this), MethodDeclaration.Roles.Body);
					} else {
						if (setLocation != null && setLocation.Count > 0)
							setAccessor.AddChild (new CSharpTokenNode (Convert (setLocation[0]), 1), MethodDeclaration.Roles.Semicolon);
					}
				}
				if (getAccessor != null && setAccessor != null) {
					if (getAccessor.StartLocation < setAccessor.StartLocation) {
						newProperty.AddChild (getAccessor, PropertyDeclaration.GetterRole);
						newProperty.AddChild (setAccessor, PropertyDeclaration.SetterRole);
					} else {
						newProperty.AddChild (setAccessor, PropertyDeclaration.SetterRole);
						newProperty.AddChild (getAccessor, PropertyDeclaration.GetterRole);
					}
				} else {
					if (getAccessor != null)
						newProperty.AddChild (getAccessor, PropertyDeclaration.GetterRole);
					if (setAccessor != null)
						newProperty.AddChild (setAccessor, PropertyDeclaration.SetterRole);
				}
				
				if (location != null && location.Count > 1) {
					newProperty.AddChild (new CSharpTokenNode (Convert (location[1]), 1), MethodDeclaration.Roles.RBrace);
				} else {
					// parser error, set end node to max value.
					newProperty.AddChild (new ErrorNode (), AstNode.Roles.Error);
				}
				
				typeStack.Peek ().AddChild (newProperty, TypeDeclaration.MemberRole);
			}
예제 #60
0
        public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
        {
            CLRType t = m_clrTypes.Value.Last.Value;
            string returnType = propertyDeclaration.ReturnType.ToString();

            Property p = new Property(
                CheckFlag(propertyDeclaration.Modifiers, Modifiers.Override) ,
                CheckFlag(propertyDeclaration.Modifiers , Modifiers.Static),
                new Visibility(VisibilityMapper.Map(propertyDeclaration.Modifiers)),
                CheckFlag(propertyDeclaration.Modifiers , Modifiers.Virtual),
                propertyDeclaration.Name,
                CheckFlag(propertyDeclaration.Modifiers, Modifiers.Abstract),
                propertyDeclaration.ReturnType.ToString(),
                propertyDeclaration.Getter.HasChildren,
                propertyDeclaration.Setter.HasChildren
                );

            t.Properties.Add(p);    // connect
            AddToNotDefaultReferencedTypes(returnType);

            // call base to forward execution
            base.VisitPropertyDeclaration(propertyDeclaration);
        }