public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) { if (primitiveExpression.Value is bool) return (bool)primitiveExpression.Value ? SymbolDefined : null; else return null; }
internal PrimitiveEmitter(PrimitiveExpression primitiveExpression, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer) : base(ilGenerator, instructionsIndexer) { PrimitiveExpression = primitiveExpression; Type = PrimitiveExpression.Value.GetType(); PrimitiveInstruction = InstructionsIndexer.GetInstruction(PrimitiveExpression); }
protected override string GenerateCode(ITypeDefinition currentClass) { // string[] fields = listBox.SelectedItems.OfType<PropertyOrFieldWrapper>().Select(f2 => f2.MemberName).ToArray(); string[] fields = parameterList.Where(f => f.IsIncluded).Select(f2 => f2.MemberName).ToArray(); PrimitiveExpression formatString = new PrimitiveExpression(GenerateFormatString(currentClass, editor.Language.CodeGenerator, fields)); List<Expression> param = new List<Expression>() { formatString }; ReturnStatement ret = new ReturnStatement(new InvocationExpression( new MemberReferenceExpression(new TypeReferenceExpression(ConvertType(KnownTypeCode.String)), "Format"), param.Concat(fields.Select(f => new IdentifierExpression(f))).ToList() )); if (baseCallNode != null) { MethodDeclaration insertedOverrideMethod = refactoringContext.GetNode().PrevSibling as MethodDeclaration; if (insertedOverrideMethod == null) { // We are not inside of a method declaration return null; } using (Script script = refactoringContext.StartScript()) { NewLineNode nextNewLineNode = insertedOverrideMethod.NextSibling as NewLineNode; // Find base method call and replace it by return statement script.AddTo(insertedOverrideMethod.Body, ret); AppendNewLine(script, insertedOverrideMethod, nextNewLineNode); } } return null; }
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) { if(primitiveExpression.LiteralValue.StartsWith("'\\x")) { UnlockWith(primitiveExpression); } return base.VisitPrimitiveExpression(primitiveExpression, data); }
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) { if (primitiveExpression.LiteralValue.Contains("\\")) { UnlockWith(primitiveExpression); } return base.VisitPrimitiveExpression(primitiveExpression, data); }
public override object Visit(PrimitiveExpression primitiveExpression, object data) { if (primitiveExpression.Value != null) { // Console.WriteLine("Visiting " + primitiveExpression.Value); return new ReturnType(primitiveExpression.Value.GetType().FullName); } return null; }
void AddFormatCallToInvocation (RefactoringContext context, Script script, PrimitiveExpression pExpr, InvocationExpression invocation) { var newInvocation = (InvocationExpression)invocation.Clone (); newInvocation.Arguments.First ().ReplaceWith (CreateFormatString (context, pExpr, newInvocation.Arguments.Count () - 1)); newInvocation.Arguments.Add (CreateFormatArgument (context)); script.Replace (invocation, newInvocation); }
IEnumerable<CodeAction> GetActions(ObjectCreateExpression objectCreateExpression, PrimitiveExpression firstParam, PrimitiveExpression secondParam) { yield return new CodeAction(context.TranslateString("Swap parameters"), script => { var newOCE = objectCreateExpression.Clone() as ObjectCreateExpression; newOCE.Arguments.Clear(); newOCE.Arguments.Add(secondParam.Clone()); newOCE.Arguments.Add(firstParam.Clone()); script.Replace(objectCreateExpression, newOCE); }); }
private IEnumerable<PrimitiveExpression> FindMatching(LanguageElement scope, PrimitiveExpression primitiveExpression) { if (scope == null || primitiveExpression == null) yield break; ElementEnumerable primitivesEnumerable = new ElementEnumerable(scope, new PrimitiveFilter(primitiveExpression), true); if (primitivesEnumerable == null) yield break; foreach (object element in primitivesEnumerable) if (element is PrimitiveExpression) yield return (PrimitiveExpression)element; }
private StringBuilder TextureLod(MethodDefinition m, InvocationExpression i) { Debug.Assert(i.Arguments.Count == 3); var args = i.Arguments.ToArray(); var sampler = args[0]; var pos = args[1]; var lod = args[2]; var tref = ShaderDefinition.ToCecil(typeof(ShaderDefinition.vec4)); var zero = new PrimitiveExpression("0.0f"); var newPos = new ObjectCreateExpression(AstBuilder.ConvertType(tref), new[] { pos.Clone(), zero, lod.Clone() }); var result = new StringBuilder(); return(result.Append("tex2Dlod(").Append(ArgsToString(new[] { sampler, newPos })).Append(")")); }
public void CSharpHexIntegerTest1() { InvocationExpression invExpr = ParseUtilCSharp.ParseExpression <InvocationExpression>("0xAFFE.ToString()"); Assert.AreEqual(0, invExpr.Arguments.Count); Assert.IsTrue(invExpr.TargetObject is MemberReferenceExpression); MemberReferenceExpression fre = invExpr.TargetObject as MemberReferenceExpression; Assert.AreEqual("ToString", fre.MemberName); Assert.IsTrue(fre.TargetObject is PrimitiveExpression); PrimitiveExpression pe = fre.TargetObject as PrimitiveExpression; Assert.AreEqual("0xAFFE", pe.StringValue); Assert.AreEqual(0xAFFE, (int)pe.Value); }
public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration) { Expression initializer = enumMemberDeclaration.Initializer; if (enumMemberDeclaration.Initializer.IsNull) { initializer = new PrimitiveExpression(this.CurrentType.LastEnumValue); } this.CurrentType.StaticConfig.Fields.Add(new TypeConfigItem { Name = enumMemberDeclaration.Name, Entity = enumMemberDeclaration, Initializer = initializer }); }
/// <summary> /// Gets a PrimitiveExpression and a parenting property provided the PrimitiveExpression is of type System.String and the caret is inside that string. /// Returns true if both values are found and the contents of the string matches the name of the property. /// </summary> private static bool GetPrimitiveExpressionAndProperty(LanguageElement element, out PrimitiveExpression primitiveExpression, out Property property) { property = null; primitiveExpression = element as PrimitiveExpression; if (primitiveExpression == null) return false; if (primitiveExpression.ExpressionTypeName != "System.String") return false; property = primitiveExpression.GetParentProperty(); if (property == null) return false; return property.Name == (string)primitiveExpression.PrimitiveValue; }
protected virtual IEnumerable <string> GetScriptArguments(ICSharpCode.NRefactory.CSharp.Attribute attr) { if (attr == null) { return(null); } var result = new List <string>(); foreach (var arg in attr.Arguments) { PrimitiveExpression expr = (PrimitiveExpression)arg; result.Add((string)expr.Value); } return(result); }
private IScriptObject EvaluateExpression(PrimitiveExpression expression) { var value = expression.Value; try { return(this.ObjectCreator.CreatePrimitive(this, value)); } catch (RuntimeException) { throw; } catch (Exception ex) { throw new RuntimeException(expression.LinePragma, ex.Message, ex); } }
public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) { if (assignmentExpression.Right is PrimitiveExpression) { PrimitiveExpression prim = (PrimitiveExpression)assignmentExpression.Right; int number; if (int.TryParse(prim.StringValue, out number)) { if (number == 666) { UnlockWith(assignmentExpression); } } } return(base.VisitAssignmentExpression(assignmentExpression, data)); }
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) { if (primitiveExpression.Value == null) { return(Eval.CreateValue(context.Process, null)); } else if (primitiveExpression.Value is string) { return(Eval.NewString(context.Process, primitiveExpression.Value as string)); } else { Value val = Eval.NewObjectNoConstructor(DebugType.Create(context.Process, null, primitiveExpression.Value.GetType().FullName)); val.PrimitiveValue = primitiveExpression.Value; return(val); } }
bool CompareCase(CaseLabel label, GotoCaseStatement stmt) { if (label.IsDefault && stmt.IsDefaultCase) { return(true); } if (stmt.Expression is PrimitiveExpression && label.Label is PrimitiveExpression) { PrimitiveExpression e1 = stmt.Expression as PrimitiveExpression; PrimitiveExpression e2 = label.Label as PrimitiveExpression; return(object.Equals(e1.Value, e2.Value)); } return(false); }
public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration) { Expression initializer = enumMemberDeclaration.Initializer; if (enumMemberDeclaration.Initializer.IsNull) { dynamic i = this.CurrentType.LastEnumValue; if (this.CurrentType.Type.GetDefinition().Attributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute")) { if (i <= 0) { this.CurrentType.LastEnumValue = 1; } else { this.CurrentType.LastEnumValue = i * 2; } initializer = new PrimitiveExpression(this.CurrentType.LastEnumValue); } else { ++i; this.CurrentType.LastEnumValue = i; initializer = new PrimitiveExpression(this.CurrentType.LastEnumValue); } } else { var rr = this.Resolver.ResolveNode(enumMemberDeclaration.Initializer, null) as ConstantResolveResult; if (rr != null) { initializer = new PrimitiveExpression(rr.ConstantValue); this.CurrentType.LastEnumValue = rr.ConstantValue; } } this.CurrentType.StaticConfig.Fields.Add(new TypeConfigItem { Name = enumMemberDeclaration.Name, Entity = enumMemberDeclaration, Initializer = initializer }); }
protected void CompleteInternal(CompletionContext context, string key) { string insertString; if (this.outputVisitor != null) { PrimitiveExpression pre = new PrimitiveExpression(key, key); pre.AcceptVisitor(this.outputVisitor, null); insertString = this.outputVisitor.Text; } else { insertString = key; } context.Editor.Document.Replace(context.StartOffset, context.Length, insertString); context.EndOffset = context.StartOffset + insertString.Length; }
private void ConvertStringToAppSetting_CheckAvailability(Object sender, CheckContentAvailabilityEventArgs ea) { PrimitiveExpression Literal = ea.Element as PrimitiveExpression; if (Literal == null) { return; } if (Literal.PrimitiveType != PrimitiveType.String) { return; } if (((string)Literal.PrimitiveValue).Trim() == string.Empty) { return; } ea.Available = true; }
private void AddIssue(List <NamedArgumentExpression> nodes) { NamedArgumentExpression fnode = nodes.First(); if (fnode == null) { return; } AddIssue(fnode, ctx.TranslateString("Explicit argument name specifications are redundant if they are in the same order with the parameter list"), ctx.TranslateString("Remove redundant argument name"), script => { foreach (NamedArgumentExpression node in nodes) { PrimitiveExpression newExpression = new PrimitiveExpression(node.Expression.Clone()); script.Replace(node, newExpression); } }); }
private string GetSource(LanguageElement ex) { MethodCallExpression expression; if (ex is MethodCallExpression) { expression = ex as MethodCallExpression; } else { expression = ((ElementReferenceExpression)ex).FirstNode as MethodCallExpression; } PrimitiveExpression argumentNode = expression.DetailNodes[0] as PrimitiveExpression; string source = String.Format("$(\"#{0}\").get(0)", argumentNode.PrimitiveValue); return(source); }
public override void VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression) { base.VisitArrayCreateExpression(arrayCreateExpression); if (arrayCreateExpression == null) { return; } if (arrayCreateExpression.Arguments == null || !arrayCreateExpression.Arguments.Any()) { return; } var argument = arrayCreateExpression.Arguments.FirstOrNullObject(); if (argument == null || !(argument is PrimitiveExpression)) { return; } int arraySize = (Int32)((PrimitiveExpression)argument).Value; if (arraySize < 1) { return; } var initializer = arrayCreateExpression.Initializer; if (initializer.IsNull) { return; } if (arraySize != initializer.Elements.Count) { AddDiagnosticAnalyzer(new CodeIssue(argument, ctx.TranslateString("Unmatched size specification with array initializer"), ctx.TranslateString("Correct array size specification"), script => { var newArgument = new PrimitiveExpression(initializer.Elements.Count); script.Replace(argument, newArgument); })); } }
Expression ConvertXmlContentExpression(XmlContentExpression xmlContentExpression) { Expression newNode = null; switch (xmlContentExpression.Type) { case XmlContentType.Comment: newNode = new ObjectCreateExpression(new TypeReference("XComment"), Expressions(xmlContentExpression.Content)); break; case XmlContentType.Text: newNode = new PrimitiveExpression(ConvertEntities(xmlContentExpression.Content)); break; case XmlContentType.CData: newNode = new ObjectCreateExpression(new TypeReference("XCData"), Expressions(xmlContentExpression.Content)); break; case XmlContentType.ProcessingInstruction: string content = xmlContentExpression.Content.Trim(); if (content.StartsWith("xml", StringComparison.OrdinalIgnoreCase)) { XDeclaration decl; try { decl = XDocument.Parse("<?" + content + "?><Dummy />").Declaration; } catch (XmlException) { decl = new XDeclaration(null, null, null); } newNode = new ObjectCreateExpression(new TypeReference("XDeclaration"), Expressions(decl.Version, decl.Encoding, decl.Standalone)); } else { string target = content.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ?? ""; string piData = content.IndexOf(' ') > -1 ? content.Substring(content.IndexOf(' ')) : ""; newNode = new ObjectCreateExpression(new TypeReference("XProcessingInstruction"), Expressions(target, piData)); } break; default: throw new Exception("Invalid value for XmlContentType"); } return(newNode); }
public static BlockStatement add_Return(this BlockStatement blockStatement, object returnData) { if (returnData.notNull()) { Expression returnStatement; //if (returnData is ExpressionStatement) //returnStatement = returnData as ExpressionStatement; if (returnData is Expression) { returnStatement = (returnData as Expression); } else { returnStatement = new PrimitiveExpression(returnData, returnData.str()); } blockStatement.append(new ReturnStatement(returnStatement)); } return(blockStatement); }
private void SortFormatTokens_CheckAvailability(Object sender, CheckContentAvailabilityEventArgs ea) { _PrimitiveString = (CodeRush.Source.Active as PrimitiveExpression); if (_PrimitiveString == null) return; if (_PrimitiveString.PrimitiveType != PrimitiveType.String) return; LanguageElement Parent = _PrimitiveString.Parent; if (Parent == null) return; MethodCallExpression MCE = (Parent as MethodCallExpression); if (MCE == null) return; if (MCE.Name != "Format") return; _tokens = new TokenGatherer().GetTokens(_PrimitiveString.Name); if (!SequenceRenumberer.RequiresRenumbering(from item in _tokens select item.Index)) return; ea.Available = true; }
protected TypeReference GetConstantType(PrimitiveExpression expression) { if (expression.Value == null) { TypeReference nullType = TypeReference.Null; nullType.Parent = expression.Parent; return(nullType); } else { string typeName = expression.Value.GetType().FullName; if (primitiveTypeMappings.Contains(typeName)) { string csharpType = primitiveTypeMappings[typeName].ToString(); string javaType; if (csharpType == "bool") { javaType = "java.lang.Boolean"; } else if (csharpType == "string") { javaType = "java.lang.String"; } else { if (csharpType.ToLower().StartsWith("u")) { csharpType = csharpType.Remove(0, 1); } javaType = (string)TypeReference.PrimitiveTypesJava[csharpType]; } TypeReference typeReference = new TypeReference(javaType, javaType); typeReference.Parent = expression.Parent; return(typeReference); } else { throw new ApplicationException(); } } }
void HighlightStringFormatItems(PrimitiveExpression expr) { if (!(expr.Value is string)) { return; } int line = expr.StartLocation.Line; int col = expr.StartLocation.Column; TextLocation start = TextLocation.Empty; for (int i = 0; i < expr.LiteralValue.Length; i++) { char ch = expr.LiteralValue [i]; if (NewLine.GetDelimiterType(ch, i + 1 < expr.LiteralValue.Length ? expr.LiteralValue [i + 1] : '\0') != UnicodeNewline.Unknown) { line++; col = 1; continue; } if (ch == '{' && start.IsEmpty) { char next = i + 1 < expr.LiteralValue.Length ? expr.LiteralValue [i + 1] : '\0'; if (next == '{') { i++; col += 2; continue; } start = new TextLocation(line, col); } if (ch == '}' && !start.IsEmpty) { Colorize(start, new TextLocation(line, col + 1), stringFormatItemColor); start = TextLocation.Empty; } col++; } }
/// <summary> /// Try to parse a primitive value. /// /// Corresponding grammar : /// 'NULL' /// | 'TRUE' /// | 'FALSE' /// | String /// | (+|-)?Integer.Integer /// | (+|-)?Integer /// </summary> /// <returns>If succeed, returns a <see cref="PrimitiveExpression"/>.</returns> private PrimitiveExpression ParsePrimitiveExpression() { PrimitiveExpression primitiveValue; switch (CurrentToken.TokenType) { case TokenType.Null: primitiveValue = new PrimitiveExpression(); break; case TokenType.Integer: primitiveValue = new PrimitiveExpression(int.Parse(CurrentToken.Value)); break; case TokenType.Double: primitiveValue = new PrimitiveExpression(double.Parse(CurrentToken.Value)); break; case TokenType.String: primitiveValue = new PrimitiveExpression(FormatVerbatimString(CurrentToken.Value)); break; case TokenType.True: case TokenType.False: primitiveValue = new PrimitiveExpression(bool.Parse(CurrentToken.Value)); break; default: AddIssue(new BaZicParserException(CurrentToken.Line, CurrentToken.Column, CurrentToken.StartOffset, CurrentToken.ParsedLength, L.BaZic.Parser.Expressions.NotPrimitive)); DiscardToken(); return(null); } primitiveValue.Line = CurrentToken.Line; primitiveValue.Column = CurrentToken.Column; primitiveValue.StartOffset = CurrentToken.StartOffset; primitiveValue.NodeLength = CurrentToken.ParsedLength; DiscardToken(); return(primitiveValue); }
public override object VisitLocalVariableDeclaration(ICSharpCode.NRefactory.Ast.LocalVariableDeclaration localVariableDeclaration, object data) { if (localVariableDeclaration.TypeReference.ToString().Equals("System.Char")) { foreach (VariableDeclaration declaration in localVariableDeclaration.Variables) { if (declaration.Initializer is PrimitiveExpression) { PrimitiveExpression prim = (PrimitiveExpression)declaration.Initializer; var regex = new Regex("\\\\.{1}"); if (regex.IsMatch(prim.StringValue)) { UnlockWith(localVariableDeclaration); } } } } return(base.VisitLocalVariableDeclaration(localVariableDeclaration, data)); }
public static string TranslateArrayGetLength(this MemberReferenceExpression mre, object data) { var ex = data as InvocationExpression; if (ex == null) { throw new ArgumentNullException("data as InvocationExpression"); } PrimitiveExpression pe = ex.Arguments.First() as PrimitiveExpression; if (pe == null) { throw new ArgumentNullException("PrimitiveExpression pe"); } foreach (var ann in mre.Target.Annotations) { var pd = ann as ICSharpCode.Decompiler.ILAst.ILVariable; if (pd != null) { var at = pd.Type as Mono.Cecil.ArrayType; if (at != null) { return(string.Format("{0}Len{1}", mre.Target, pe.Value)); } } else { var fd = ann as FieldDefinition; if (fd != null) { var at = fd.FieldType as Mono.Cecil.ArrayType; if (at != null) { return(string.Format("{0}Len{1}", mre.Target.ToString().Replace(".", "->"), pe.Value)); } } } } return(string.Empty); }
public object VisitForNextStatement(ForNextStatement forNextStatement, object data) { if (forNextStatement.TypeReference.IsNull) { return(MakeManualLoop(forNextStatement)); } B.ForStatement fs = new B.ForStatement(GetLexicalInfo(forNextStatement)); fs.Block = ConvertBlock(forNextStatement.EmbeddedStatement); fs.Declarations.Add(new B.Declaration(forNextStatement.VariableName, null)); B.Expression start = ConvertExpression(forNextStatement.Start); Expression end = forNextStatement.End; if (forNextStatement.Step == null || forNextStatement.Step.IsNull) { // range only goes to end - 1, so increment end end = Expression.AddInteger(end, 1); fs.Iterator = MakeMethodCall("range", start, ConvertExpression(end)); } else { PrimitiveExpression stepPE = forNextStatement.Step as PrimitiveExpression; if (stepPE == null || !(stepPE.Value is int)) { AddError(forNextStatement, "Step must be an integer literal"); } else { if ((int)stepPE.Value < 0) { end = Expression.AddInteger(end, -1); } else { end = Expression.AddInteger(end, 1); } } fs.Iterator = MakeMethodCall("range", start, ConvertExpression(end), ConvertExpression(forNextStatement.Step)); } return(fs); }
bool IsZeroPrimitive(Expression expr) { //We want a very simple check -- no looking at constants, no constant folding, etc. //So 1+1 should return false, but (0) should return true var parenthesizedExpression = expr as ParenthesizedExpression; if (parenthesizedExpression != null) { return(IsZeroPrimitive(parenthesizedExpression.Expression)); } var zeroLiteralInteger = new PrimitiveExpression(0); var zeroLiteralFloat = new PrimitiveExpression(0.0f); var zeroLiteralDouble = new PrimitiveExpression(0.0); var zeroLiteralDecimal = new PrimitiveExpression(0.0m); return(SameNode(zeroLiteralInteger, expr) || SameNode(zeroLiteralFloat, expr) || SameNode(zeroLiteralDouble, expr) || SameNode(zeroLiteralDecimal, expr)); }
/// <summary> /// Translates a primitive type, e.g. "1f". /// </summary> public override StringBuilder VisitPrimitiveExpression(PrimitiveExpression primitiveExpr) { var result = new StringBuilder(); var cultureInfo = CultureInfo.InvariantCulture.NumberFormat; if (primitiveExpr.Value is float) { var value = ((float)primitiveExpr.Value).ToString(cultureInfo); if (!value.Contains(".")) { value += ".0"; } return(result.Append(value).Append("f")); } if (primitiveExpr.Value is double) { var value = ((double)primitiveExpr.Value).ToString(cultureInfo); if (!value.Contains(".")) { value += ".0"; } return(result.Append(value).Append("d")); } if (primitiveExpr.Value is uint) { var value = ((uint)primitiveExpr.Value).ToString(cultureInfo); return(result.Append(value).Append("u")); } if (primitiveExpr.Value is bool) { var value = primitiveExpr.Value.ToString().ToLower(); return(result.Append(value)); } return(result.Append(primitiveExpr.Value)); }
/// <summary> /// Insert the element represented by the completion data into the text /// editor. /// </summary> /// <param name="textArea">TextArea to insert the completion data in.</param> /// <param name="ch">Character that should be inserted after the completion data. /// \0 when no character should be inserted.</param> /// <returns>Returns true when the insert action has processed the character /// <paramref name="ch"/>; false when the character was not processed.</returns> public override bool InsertAction(TextArea textArea, char ch) { string insertString; if (this.outputVisitor != null) { PrimitiveExpression pre = new PrimitiveExpression(this.Text, this.Text); pre.AcceptVisitor(this.outputVisitor, null); insertString = this.outputVisitor.Text; } else { insertString = this.Text; } textArea.InsertString(insertString); if (ch == insertString[insertString.Length - 1]) { return(true); } return(false); }
public override object TrackedVisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) { Expression left = binaryOperatorExpression.Left; TypeReference leftType = GetExpressionType(left); if (leftType != null && (leftType.RankSpecifier == null || leftType.RankSpecifier.Length == 0) && (binaryOperatorExpression.Right is PrimitiveExpression)) { string fullName = GetFullName(leftType); if (types.Contains(fullName)) { Expression minValue = (Expression)values[fullName]; PrimitiveExpression nullRight = (PrimitiveExpression)binaryOperatorExpression.Right; if (nullRight.Value == null) { BinaryOperatorExpression replacedBinOP = binaryOperatorExpression; replacedBinOP.Right = minValue; ReplaceCurrentNode(replacedBinOP); } } } return(base.TrackedVisitBinaryOperatorExpression(binaryOperatorExpression, data)); }
void Unary(out Expression exp) { exp = null; Object val; LValue lv; if (StartOf(4)) { Const(out val); exp = new PrimitiveExpression(GetPragma(t), val); SetEndPragma(exp); } else if (la.kind == 4) { StringExpression(out exp); } else if (la.kind == 1) { LValue(out lv); exp = lv; SetEndPragma(exp); } else { SynErr(71); } }
public override object TrackedVisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) { if (assignmentExpression.Right is PrimitiveExpression) { PrimitiveExpression pe = (PrimitiveExpression)assignmentExpression.Right; if (pe.Value == null) { TypeReference leftType = GetExpressionType(assignmentExpression.Left); if (leftType != null && (leftType.RankSpecifier == null || leftType.RankSpecifier.Length == 0)) { string fullName = GetFullName(leftType); if (types.Contains(fullName)) { Expression minValue = (Expression)values[fullName]; assignmentExpression.Right = minValue; minValue.Parent = assignmentExpression; } } } } return(base.TrackedVisitAssignmentExpression(assignmentExpression, data)); }
protected override void Run(TextEditorControl editor, string clipboardText) { CodeGenerator codeGenerator = ParserService.CurrentProjectContent.Language.CodeGenerator; if (codeGenerator == null) { codeGenerator = LanguageProperties.CSharp.CodeGenerator; } Expression expression = null; using (StringReader reader = new StringReader(clipboardText)) { string line; while ((line = reader.ReadLine()) != null) { Expression newExpr = new PrimitiveExpression(line); if (expression == null) { expression = newExpr; } else { expression = expression .Operator(BinaryOperatorType.Concat, ExpressionBuilder.Identifier("Environment").Member("NewLine")) .Operator(BinaryOperatorType.Concat, newExpr); } } } if (expression == null) { return; } TextArea textArea = editor.ActiveTextAreaControl.TextArea; string indentation = GetIndentation(editor.Document, textArea.Caret.Line); textArea.InsertString(codeGenerator.GenerateCode(expression, indentation).Trim()); }
public override void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression) { if (!(primitiveExpression.Value is long || primitiveExpression.Value is ulong)) { //Literals such as "l" or 'l' are perfectly acceptable. //Also, no point in visiting integer or boolean literals return; } string literalValue = primitiveExpression.LiteralValue; if (literalValue.Length < 2) { return; } char prevChar = literalValue [literalValue.Length - 2]; char lastChar = literalValue [literalValue.Length - 1]; if (prevChar == 'u' || prevChar == 'U') { //No problem, '3ul' is not confusing return; } if (lastChar == 'l' || prevChar == 'l') { AddIssue(new CodeIssue(primitiveExpression, ctx.TranslateString("Long literal ends with 'l' instead of 'L'"), ctx.TranslateString("Make suffix upper case"), script => { object newValue = primitiveExpression.Value; string newLiteralValue = primitiveExpression.LiteralValue.ToUpperInvariant(); script.Replace(primitiveExpression, new PrimitiveExpression(newValue, newLiteralValue)); } )); } }
public override object Visit (Constant constant) { var result = new PrimitiveExpression (constant.GetValue (), Convert (constant.Location), constant.AsString ().Length); return result; }
public void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression) { StartNode(primitiveExpression); if (!string.IsNullOrEmpty(primitiveExpression.LiteralValue)) { formatter.WriteToken(primitiveExpression.LiteralValue); } else { WritePrimitiveValue(primitiveExpression.Value); } EndNode(primitiveExpression); }
public virtual void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression) { if (this.ThrowException) { throw (Exception)this.CreateException(primitiveExpression); } }
public virtual void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression) { VisitChildren (primitiveExpression); }
private void BuildArgumentsList(IList<Expression> arguments) { Expression paramsArg = null; string paramArgName = null; var resolveResult = this.ResolveResult; if (resolveResult != null) { var parameters = resolveResult.Member.Parameters; var resolvedMethod = resolveResult.Member as IMethod; var invocationResult = resolveResult as CSharpInvocationResolveResult; int shift = 0; if (resolvedMethod != null && invocationResult != null && resolvedMethod.IsExtensionMethod && invocationResult.IsExtensionMethodInvocation) { shift = 1; this.ThisName = resolvedMethod.Parameters[0].Name; this.IsExtensionMethod = true; } Expression[] result = new Expression[parameters.Count - shift]; string[] names = new string[result.Length]; int i = 0; foreach (var arg in arguments) { if (arg is NamedArgumentExpression) { NamedArgumentExpression namedArg = (NamedArgumentExpression)arg; var namedParam = parameters.First(p => p.Name == namedArg.Name); var index = parameters.IndexOf(namedParam); result[index] = namedArg.Expression; names[index] = namedArg.Name; } else { if (paramsArg == null && (parameters.Count > (i + shift)) && parameters[i + shift].IsParams) { if (resolvedMethod.DeclaringTypeDefinition == null || !this.Emitter.Validator.IsIgnoreType(resolvedMethod.DeclaringTypeDefinition)) { paramsArg = arg; } paramArgName = parameters[i + shift].Name; } if (i >= result.Length) { var list = result.ToList(); list.AddRange(new Expression[arguments.Count - i]); var strList = names.ToList(); strList.AddRange(new string[arguments.Count - i]); result = list.ToArray(); names = strList.ToArray(); } result[i] = arg; names[i] = (i + shift) < parameters.Count ? parameters[i + shift].Name : paramArgName; } i++; } for (i = 0; i < result.Length; i++) { if (result[i] == null) { var p = parameters[i + shift]; if (p.Type.Kind == TypeKind.Enum) { result[i] = new PrimitiveExpression(Helpers.GetEnumValue(this.Emitter, p.Type, p.ConstantValue)); } else { result[i] = new PrimitiveExpression(p.ConstantValue); } names[i] = parameters[i + shift].Name; } } this.ArgumentsExpressions = result; this.ArgumentsNames = names; this.ParamsExpression = paramsArg; this.NamedExpressions = this.CreateNamedExpressions(names, result); } else { this.ArgumentsExpressions = arguments.ToArray(); } }
public override object Visit(Constant constant) { if (constant.GetValue() == null) return new NullReferenceExpression(Convert(constant.Location)); string literalValue; var literalConstant = constant as ILiteralConstant; literalValue = literalConstant != null ? new string(literalConstant.ParsedValue) : constant.GetValueAsLiteral(); object val = constant.GetValue(); if (val is bool) literalValue = (bool)val ? "true" : "false"; var result = new PrimitiveExpression(val, Convert(constant.Location), literalValue); return result; }
// 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); }
bool IsZeroPrimitive(Expression expr) { //We want a very simple check -- no looking at constants, no constant folding, etc. //So 1+1 should return false, but (0) should return true var parenthesizedExpression = expr as ParenthesizedExpression; if (parenthesizedExpression != null) { return IsZeroPrimitive(parenthesizedExpression.Expression); } var zeroLiteralInteger = new PrimitiveExpression(0); var zeroLiteralFloat = new PrimitiveExpression(0.0f); var zeroLiteralDouble = new PrimitiveExpression(0.0); var zeroLiteralDecimal = new PrimitiveExpression(0.0m); return SameNode(zeroLiteralInteger, expr) || SameNode(zeroLiteralFloat, expr) || SameNode(zeroLiteralDouble, expr) || SameNode(zeroLiteralDecimal, expr); }
public void TrickyCast4() { Expression expr = new PrimitiveExpression(int.MinValue).CastTo(new SimpleType("MyType")); Assert.AreEqual("(MyType)(-2147483648)", InsertRequired(expr)); Assert.AreEqual("(MyType)(-2147483648)", InsertReadable(expr)); }
public void TrickyCast6() { Expression expr = new PrimitiveExpression(int.MinValue).CastTo(new PrimitiveType("double")); Assert.AreEqual("(double)-2147483648", InsertRequired(expr)); Assert.AreEqual("(double)-2147483648", InsertReadable(expr)); }
/// <summary> /// Divides expr by the size of 'type'. /// </summary> Expression DivideBySize(Expression expr, TypeReference type) { CastExpression cast = expr as CastExpression; if (cast != null && cast.Type is PrimitiveType && ((PrimitiveType)cast.Type).Keyword == "int") expr = cast.Expression.Detach(); Expression sizeOfExpression; switch (TypeAnalysis.GetInformationAmount(type)) { case 1: case 8: sizeOfExpression = new PrimitiveExpression(1); break; case 16: sizeOfExpression = new PrimitiveExpression(2); break; case 32: sizeOfExpression = new PrimitiveExpression(4); break; case 64: sizeOfExpression = new PrimitiveExpression(8); break; default: sizeOfExpression = new SizeOfExpression { Type = AstBuilder.ConvertType(type) }; break; } BinaryOperatorExpression boe = expr as BinaryOperatorExpression; if (boe != null && boe.Operator == BinaryOperatorType.Multiply && sizeOfExpression.IsMatch(boe.Right)) return boe.Left.Detach(); if (sizeOfExpression.IsMatch(expr)) return new PrimitiveExpression(1); return new BinaryOperatorExpression(expr, BinaryOperatorType.Divide, sizeOfExpression); }
static void AddArgument(InvocationExpression newNode, IParameter parameterToAdd, bool isNextInSequence) { Expression defaultValue; if (parameterToAdd.ConstantValue == null) { defaultValue = new NullReferenceExpression(); } else { defaultValue = new PrimitiveExpression(parameterToAdd.ConstantValue); } Expression newArgument; if (newNode.Arguments.Any(argument => argument is NamedExpression) || !isNextInSequence) { newArgument = new NamedArgumentExpression(parameterToAdd.Name, defaultValue); } else { newArgument = defaultValue; } newNode.Arguments.Add(newArgument); }
private void BuildOperatorArgumentsList(IList<Expression> arguments, IMethod method) { if (method != null) { var parameters = method.Parameters; Expression[] result = new Expression[parameters.Count]; string[] names = new string[result.Length]; int i = 0; foreach (var arg in arguments) { if (arg is NamedArgumentExpression) { NamedArgumentExpression namedArg = (NamedArgumentExpression)arg; var namedParam = parameters.First(p => p.Name == namedArg.Name); var index = parameters.IndexOf(namedParam); result[index] = namedArg.Expression; names[index] = namedArg.Name; } else { if (i >= result.Length) { var list = result.ToList(); list.AddRange(new Expression[arguments.Count - i]); var strList = names.ToList(); strList.AddRange(new string[arguments.Count - i]); result = list.ToArray(); names = strList.ToArray(); } result[i] = arg; names[i] = parameters[i].Name; } i++; } for (i = 0; i < result.Length; i++) { if (result[i] == null) { var p = parameters[i]; if (p.Type.Kind == TypeKind.Enum) { result[i] = new PrimitiveExpression(Helpers.GetEnumValue(this.Emitter, p.Type, p.ConstantValue)); } else { result[i] = new PrimitiveExpression(p.ConstantValue); } names[i] = parameters[i].Name; } } this.ArgumentsExpressions = result; this.ArgumentsNames = names; this.NamedExpressions = this.CreateNamedExpressions(names, result); } else { this.ArgumentsExpressions = arguments.ToArray(); } }
AssignmentExpression GetTransformedAssignmentExpression (RefactoringContext context, ForeachStatement foreachStatement) { var enumerableToIterate = foreachStatement.InExpression.Clone(); Statement statement = foreachStatement.EmbeddedStatement; Expression leftExpression, rightExpression; if (!ExtractExpression(statement, out leftExpression, out rightExpression)) { return null; } if (leftExpression == null || rightExpression == null) { return null; } var type = context.Resolve(leftExpression).Type; if (!IsLinqSummableType(type)) { return null; } if (rightExpression.DescendantsAndSelf.OfType<AssignmentExpression>().Any()) { // Reject loops such as // int k = 0; // foreach (var x in y) { k += (z = 2); } return null; } if (rightExpression.DescendantsAndSelf.OfType<UnaryOperatorExpression>().Any(IsUnaryModifierExpression)) { // int k = 0; // foreach (var x in y) { k += (z++); } return null; } var zeroLiteral = new PrimitiveExpression(0); Expression baseExpression = enumerableToIterate; for (;;) { ConditionalExpression condition = rightExpression as ConditionalExpression; if (condition == null) { break; } if (SameNode(zeroLiteral, condition.TrueExpression)) { baseExpression = new InvocationExpression(new MemberReferenceExpression(baseExpression.Clone(), "Where"), BuildLambda(foreachStatement.VariableName, CSharpUtil.InvertCondition(condition.Condition))); rightExpression = condition.FalseExpression.Clone(); continue; } if (SameNode(zeroLiteral, condition.FalseExpression)) { baseExpression = new InvocationExpression(new MemberReferenceExpression(baseExpression.Clone(), "Where"), BuildLambda(foreachStatement.VariableName, condition.Condition.Clone())); rightExpression = condition.TrueExpression.Clone(); continue; } break; } var primitiveOne = new PrimitiveExpression(1); bool isPrimitiveOne = SameNode(primitiveOne, rightExpression); var arguments = new List<Expression>(); string method = isPrimitiveOne ? "Count" : "Sum"; if (!isPrimitiveOne && !IsIdentifier(rightExpression, foreachStatement.VariableName)) { var lambda = BuildLambda(foreachStatement.VariableName, rightExpression); arguments.Add(lambda); } var rightSide = new InvocationExpression(new MemberReferenceExpression(baseExpression, method), arguments); return new AssignmentExpression(leftExpression.Clone(), AssignmentOperatorType.Add, rightSide); }
public override StringBuilder VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, int data) { var result = new StringBuilder(); if (primitiveExpression.Value is float) { var s = ((float)primitiveExpression.Value).ToString(CultureInfo.InvariantCulture.NumberFormat); result.Append(s); if (!s.Contains(".")) result.Append(".0"); result.Append("f"); return result; } if (primitiveExpression.Value is double) { var s = ((double)primitiveExpression.Value).ToString(CultureInfo.InvariantCulture.NumberFormat); result.Append(s); if (!s.Contains(".")) result.Append(".0"); result.Append("lf"); return result; } if (primitiveExpression.Value is uint) { var s = ((uint)primitiveExpression.Value).ToString(CultureInfo.InvariantCulture.NumberFormat); result.Append(s).Append("u"); return result; } return result.Append(primitiveExpression.Value.ToString()); }
bool ExtractExpression (Statement statement, out Expression leftSide, out Expression rightSide) { ExpressionStatement expression = statement as ExpressionStatement; if (expression != null) { AssignmentExpression assignment = expression.Expression as AssignmentExpression; if (assignment != null) { if (assignment.Operator == AssignmentOperatorType.Add) { leftSide = assignment.Left; rightSide = assignment.Right; return true; } if (assignment.Operator == AssignmentOperatorType.Subtract) { leftSide = assignment.Left; rightSide = new UnaryOperatorExpression(UnaryOperatorType.Minus, assignment.Right.Clone()); return true; } leftSide = null; rightSide = null; return false; } UnaryOperatorExpression unary = expression.Expression as UnaryOperatorExpression; if (unary != null) { leftSide = unary.Expression; if (unary.Operator == UnaryOperatorType.Increment || unary.Operator == UnaryOperatorType.PostIncrement) { rightSide = new PrimitiveExpression(1); return true; } else if (unary.Operator == UnaryOperatorType.Decrement || unary.Operator == UnaryOperatorType.PostDecrement) { rightSide = new PrimitiveExpression(-1); return true; } else { leftSide = null; rightSide = null; return false; } } } if (statement is EmptyStatement || statement.IsNull) { leftSide = null; rightSide = null; return true; } BlockStatement block = statement as BlockStatement; if (block != null) { leftSide = null; rightSide = null; foreach (Statement child in block.Statements) { Expression newLeft, newRight; if (!ExtractExpression(child, out newLeft, out newRight)) { leftSide = null; rightSide = null; return false; } if (newLeft == null) { continue; } if (leftSide == null) { leftSide = newLeft; rightSide = newRight; } else if (SameNode(leftSide, newLeft)) { rightSide = new BinaryOperatorExpression(ParenthesizeIfNeeded(rightSide).Clone(), BinaryOperatorType.Add, ParenthesizeIfNeeded(newRight).Clone()); } else { return false; } } return true; } IfElseStatement condition = statement as IfElseStatement; if (condition != null) { Expression ifLeft, ifRight; if (!ExtractExpression(condition.TrueStatement, out ifLeft, out ifRight)) { leftSide = null; rightSide = null; return false; } Expression elseLeft, elseRight; if (!ExtractExpression(condition.FalseStatement, out elseLeft, out elseRight)) { leftSide = null; rightSide = null; return false; } if (ifLeft == null && elseLeft == null) { leftSide = null; rightSide = null; return true; } if (ifLeft != null && elseLeft != null && !SameNode(ifLeft, elseLeft)) { leftSide = null; rightSide = null; return false; } ifRight = ifRight ?? new PrimitiveExpression(0); elseRight = elseRight ?? new PrimitiveExpression(0); leftSide = ifLeft ?? elseLeft; rightSide = new ConditionalExpression(condition.Condition.Clone(), ifRight.Clone(), elseRight.Clone()); return true; } leftSide = null; rightSide = null; return false; }
static PrimitiveExpression CreateFormatString(RefactoringContext context, PrimitiveExpression pExpr, int argumentNumber) { var start = context.GetOffset(pExpr.StartLocation); var end = context.GetOffset(pExpr.EndLocation); var sStart = context.GetOffset(context.SelectionStart); var sEnd = context.GetOffset(context.SelectionEnd); return new PrimitiveExpression("", context.GetText(start, sStart - start) + "{" + argumentNumber + "}" + context.GetText(sEnd, end - sEnd)); }
public void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression) { StartNode(primitiveExpression); writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.UnsafeLiteralValue); EndNode(primitiveExpression); }
public void TrickyCast5() { Expression expr = new PrimitiveExpression(-1.0).CastTo(new SimpleType("MyType")); Assert.AreEqual("(MyType)(-1.0)", InsertRequired(expr)); Assert.AreEqual("(MyType)(-1.0)", InsertReadable(expr)); }