public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data) { Push(); object result = base.VisitPropertyDeclaration(propertyDeclaration, data); Pop(); return result; }
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; } }
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); }
public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data) { if (propertyDeclaration.Setter.Modifiers.HasFlag(Modifiers.Private)) { UnlockWith(propertyDeclaration.Setter); } return base.VisitPropertyDeclaration(propertyDeclaration, data); }
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; }
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)); }
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); }
public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) { if (propertyDeclaration.HasModifier(Modifiers.Static)) { this.CheckDependency(propertyDeclaration.ReturnType); if (!propertyDeclaration.Getter.IsNull) { propertyDeclaration.Getter.AcceptVisitor(this); } } }
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; }
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(); } }
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); }
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; }
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); }
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); }
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); }
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)); }
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); }
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); }
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(); }
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 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)); }
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)); }
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(); }
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); }
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); }
/// <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;", " }", "}"); }
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); }
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); }
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"); } } }
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")))); }
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); }
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)); } } }
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)); }
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)); }
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; }
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); }
public override void VisitPropertyDeclaration (PropertyDeclaration propertyDeclaration) { if (!propertyDeclaration.LBraceToken.IsNull) AddFolding (GetEndOfPrev(propertyDeclaration.LBraceToken), propertyDeclaration.RBraceToken.EndLocation, true); base.VisitPropertyDeclaration (propertyDeclaration); }
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); }
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); }
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); }
// 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; }
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; }
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); }
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); }
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); }