public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { if (tryCatchStatement.CatchClauses.Count > 5) { UnlockWith(tryCatchStatement); } return base.VisitTryCatchStatement(tryCatchStatement, data); }
public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { if(tryCatchStatement.CatchClauses.Count > 0 && !tryCatchStatement.FinallyBlock.IsNull) { UnlockWith(tryCatchStatement); } return base.VisitTryCatchStatement(tryCatchStatement, data); }
public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { var defaultCatchClause = tryCatchStatement.CatchClauses.FirstOrDefault(a => a.Type.IsNull); if(defaultCatchClause != null) { UnlockWith(defaultCatchClause); } return base.VisitTryCatchStatement(tryCatchStatement, data); }
public void TestEmptyFinallyDoesNotMatchNullFinally() { TryCatchStatement c1 = new TryCatchStatement { TryBlock = new BlockStatement(), CatchClauses = { new CatchClause { Body = new BlockStatement() } } }; TryCatchStatement c2 = new TryCatchStatement { TryBlock = new BlockStatement(), CatchClauses = { new CatchClause { Body = new BlockStatement() } }, FinallyBlock = new BlockStatement() }; Assert.IsFalse(c1.IsMatch(c2)); Assert.IsFalse(c2.IsMatch(c1)); // and vice versa }
public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { if (tryCatchStatement.CatchClauses.Count > 0) { foreach (CatchClause catchClause in tryCatchStatement.CatchClauses) { var throwStatement = catchClause.Body.Statements.FirstOrDefault(a => a is ThrowStatement); if(throwStatement != null) { UnlockWith(throwStatement); } } } return base.VisitTryCatchStatement(tryCatchStatement, data); }
public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { var redundantCatchClauses = new List<CatchClause>(); bool hasNonRedundantCatch = false; foreach (var catchClause in tryCatchStatement.CatchClauses) { if (IsRedundant(catchClause)) { redundantCatchClauses.Add(catchClause); } else { hasNonRedundantCatch = true; } } if (hasNonRedundantCatch || !tryCatchStatement.FinallyBlock.IsNull) { AddIssuesForClauses(redundantCatchClauses); } else { AddIssueForTryCatchStatement(tryCatchStatement); } }
public void VisitTryCatchStatement(TryCatchStatement statement) { Formatter.StartNode(statement); Formatter.WriteKeyword("try"); statement.TryBlock.AcceptVisitor(this); if (statement.CatchClauses.Count > 0) { Formatter.WriteLine(); WriteNodes(statement.CatchClauses, true); } if (statement.FinallyBlock != null) { Formatter.WriteLine(); Formatter.WriteKeyword("finally"); statement.FinallyBlock.AcceptVisitor(this); } Formatter.EndNode(); }
void TryStatement( #line 3245 "VBNET.ATG" out Statement tryStatement) { #line 3247 "VBNET.ATG" Statement blockStmt = null, finallyStmt = null;List<CatchClause> catchClauses = null; Expect(203); EndOfStmt(); Block( #line 3250 "VBNET.ATG" out blockStmt); if (la.kind == 62 || la.kind == 100 || la.kind == 110) { CatchClauses( #line 3251 "VBNET.ATG" out catchClauses); } if (la.kind == 110) { lexer.NextToken(); EndOfStmt(); Block( #line 3252 "VBNET.ATG" out finallyStmt); } Expect(100); Expect(203); #line 3255 "VBNET.ATG" tryStatement = new TryCatchStatement(blockStmt, catchClauses, finallyStmt); }
public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { new TryCatchBlock(this, tryCatchStatement).Emit(); }
public virtual void VisitTryCatchStatement (TryCatchStatement tryCatchStatement) { VisitChildren (tryCatchStatement); }
protected virtual void EmitCatchBlock() { TryCatchStatement tryCatchStatement = this.TryCatchStatement; string eName = "e".Ident(); this.WriteFunction(); this.WriteOpenParentheses(); this.Write(eName); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginFunctionBlock(); int index = 0; bool isWriteElse = true; bool isIfExists = false; foreach (CatchClause clause in tryCatchStatement.CatchClauses) { if (!clause.Type.IsNull) { if (index != 0) { this.WriteElse(); } string exceptionType = BridgeTypes.ToJsName(clause.Type, this.Emitter); if (exceptionType != "System.Exception") { isIfExists = true; this.WriteIf(); this.Write(string.Format("System.is({0}, {1})", eName, exceptionType)); this.BeginIfBlock(); if (clause.VariableName.IsNotEmpty()) { this.Write(string.Format("local {0} = {1};", clause.VariableName, eName)); this.WriteNewLine(); } this.Emitter.NoBraceBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); this.Emitter.NoBraceBlock = null; this.Outdent(); } else { isWriteElse = false; this.BeginFunctionBlock(); if (clause.VariableName.IsNotEmpty()) { this.Write(string.Format("local {0} = {1};", clause.VariableName, eName)); this.WriteNewLine(); } this.Emitter.NoBraceBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); this.Emitter.NoBraceBlock = null; this.Outdent(); } } else { isWriteElse = false; if (index != 0) { this.BeginElseBlock(); } this.Emitter.NoBraceBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); this.Emitter.NoBraceBlock = null; this.Write("return true;"); this.WriteNewLine(); if (index != 0) { this.Outdent(); } } ++index; } if (isWriteElse) { this.BeginElseBlock(); this.Write("return true;"); this.WriteNewLine(); this.Outdent(); } if (isIfExists) { this.Indent(); this.EndCodeBlock(); this.WriteNewLine(); } this.EndFunctionBlock(); if (!tryCatchStatement.FinallyBlock.IsNull) { this.WriteComma(); } else { this.Write(");"); } this.WriteNewLine(); }
private bool IsMatch(TryCatchStatement left, TryCatchStatement right) { return(true); }
public TryCatchBlock(IEmitter emitter, TryCatchStatement tryCatchStatement) : base(emitter, tryCatchStatement) { this.Emitter = emitter; this.TryCatchStatement = tryCatchStatement; }
public Node VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { return(CreateDummy(tryCatchStatement)); }
void ChangeNodeStatus(DefiniteAssignmentNode node, DefiniteAssignmentStatus inputStatus) { if (node.NodeStatus == inputStatus) { return; } node.NodeStatus = inputStatus; DefiniteAssignmentStatus outputStatus; switch (node.Type) { case ControlFlowNodeType.StartNode: case ControlFlowNodeType.BetweenStatements: if (node.NextStatement is IfElseStatement) { // Handle if-else as a condition node goto case ControlFlowNodeType.LoopCondition; } if (inputStatus == DefiniteAssignmentStatus.DefinitelyAssigned) { // There isn't any way to un-assign variables, so we don't have to check the expression // if the status already is definitely assigned. outputStatus = DefiniteAssignmentStatus.DefinitelyAssigned; } else { outputStatus = CleanSpecialValues(node.NextStatement.AcceptVisitor(visitor, inputStatus)); } break; case ControlFlowNodeType.EndNode: outputStatus = inputStatus; if (node.PreviousStatement.Role == TryCatchStatement.FinallyBlockRole && (outputStatus == DefiniteAssignmentStatus.DefinitelyAssigned || outputStatus == DefiniteAssignmentStatus.PotentiallyAssigned)) { TryCatchStatement tryFinally = (TryCatchStatement)node.PreviousStatement.Parent; // Changing the status on a finally block potentially changes the status of all edges leaving that finally block: foreach (ControlFlowEdge edge in allNodes.SelectMany(n => n.Outgoing)) { if (edge.IsLeavingTryFinally && edge.TryFinallyStatements.Contains(tryFinally)) { DefiniteAssignmentStatus s = edgeStatus[edge]; if (s == DefiniteAssignmentStatus.PotentiallyAssigned) { ChangeEdgeStatus(edge, outputStatus); } } } } break; case ControlFlowNodeType.LoopCondition: ForeachStatement foreachStmt = node.NextStatement as ForeachStatement; if (foreachStmt != null) { outputStatus = CleanSpecialValues(foreachStmt.InExpression.AcceptVisitor(visitor, inputStatus)); if (foreachStmt.VariableName == this.variableName) { outputStatus = DefiniteAssignmentStatus.DefinitelyAssigned; } break; } else { Debug.Assert(node.NextStatement is IfElseStatement || node.NextStatement is WhileStatement || node.NextStatement is ForStatement || node.NextStatement is DoWhileStatement); Expression condition = node.NextStatement.GetChildByRole(AstNode.Roles.Condition); if (condition.IsNull) { outputStatus = inputStatus; } else { outputStatus = condition.AcceptVisitor(visitor, inputStatus); } foreach (ControlFlowEdge edge in node.Outgoing) { if (edge.Type == ControlFlowEdgeType.ConditionTrue && outputStatus == DefiniteAssignmentStatus.AssignedAfterTrueExpression) { ChangeEdgeStatus(edge, DefiniteAssignmentStatus.DefinitelyAssigned); } else if (edge.Type == ControlFlowEdgeType.ConditionFalse && outputStatus == DefiniteAssignmentStatus.AssignedAfterFalseExpression) { ChangeEdgeStatus(edge, DefiniteAssignmentStatus.DefinitelyAssigned); } else { ChangeEdgeStatus(edge, CleanSpecialValues(outputStatus)); } } return; } default: throw new InvalidOperationException(); } foreach (ControlFlowEdge edge in node.Outgoing) { ChangeEdgeStatus(edge, outputStatus); } }
public void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { throw new NotImplementedException(); }
protected void VisitAsyncTryCatchStatement() { TryCatchStatement tryCatchStatement = TryCatchStatement; Emitter.AsyncBlock.Steps.Last().JumpToStep = Emitter.AsyncBlock.Step; var tryStep = Emitter.AsyncBlock.AddAsyncStep(); AsyncTryInfo tryInfo = new AsyncTryInfo(); tryInfo.StartStep = tryStep.Step; Emitter.IgnoreBlock = tryCatchStatement.TryBlock; tryCatchStatement.TryBlock.AcceptVisitor(Emitter); tryStep = Emitter.AsyncBlock.Steps.Last(); tryInfo.EndStep = tryStep.Step; List <IAsyncStep> catchSteps = new List <IAsyncStep>(); foreach (var clause in tryCatchStatement.CatchClauses) { var catchStep = Emitter.AsyncBlock.AddAsyncStep(); PushLocals(); var varName = clause.VariableName; if (!String.IsNullOrEmpty(varName) && !Emitter.Locals.ContainsKey(varName)) { varName = AddLocal(varName, clause.VariableNameToken, clause.Type); } Emitter.IgnoreBlock = clause.Body; clause.Body.AcceptVisitor(Emitter); Write(JS.Vars.ASYNC_E + " = null;"); PopLocals(); WriteNewLine(); tryInfo.CatchBlocks.Add(new Tuple <string, string, int, int>(varName, clause.Type.IsNull ? JS.Types.System.Exception.NAME : H5Types.ToJsName(clause.Type, Emitter), catchStep.Step, Emitter.AsyncBlock.Steps.Last().Step)); catchSteps.Add(Emitter.AsyncBlock.Steps.Last()); } if (!Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E)) { AddLocal(JS.Vars.ASYNC_E, null, AstType.Null); } IAsyncStep finalyStep = null; if (!tryCatchStatement.FinallyBlock.IsNull) { finalyStep = Emitter.AsyncBlock.AddAsyncStep(tryCatchStatement.FinallyBlock); Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock; tryCatchStatement.FinallyBlock.AcceptVisitor(Emitter); var finallyNode = GetParentFinallyBlock(tryCatchStatement, false); WriteNewLine(); WriteIf(); WriteOpenParentheses(); Write(JS.Vars.ASYNC_JUMP + " > -1"); WriteCloseParentheses(); WriteSpace(); BeginBlock(); if (finallyNode != null) { var hashcode = finallyNode.GetHashCode(); Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel { Node = finallyNode, Output = Emitter.Output }); Write(JS.Vars.ASYNC_STEP + " = " + Helpers.PrefixDollar("{", hashcode, "};")); WriteNewLine(); Write("continue;"); } else { Write(JS.Vars.ASYNC_STEP + " = " + JS.Vars.ASYNC_JUMP + ";"); WriteNewLine(); Write(JS.Vars.ASYNC_JUMP + " = null;"); } WriteNewLine(); EndBlock(); WriteSpace(); WriteElse(); WriteIf(); WriteOpenParentheses(); Write(JS.Vars.ASYNC_E); WriteCloseParentheses(); WriteSpace(); BeginBlock(); if (Emitter.AsyncBlock.IsTaskReturn) { Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_EXCEPTION + "(" + JS.Vars.ASYNC_E + ");"); } else { Write("throw " + JS.Vars.ASYNC_E + ";"); } WriteNewLine(); WriteReturn(false); WriteSemiColon(); WriteNewLine(); EndBlock(); WriteSpace(); WriteElse(); WriteIf(); WriteOpenParentheses(); Write(JS.Funcs.H5_IS_DEFINED); WriteOpenParentheses(); Write(JS.Vars.ASYNC_RETURN_VALUE); WriteCloseParentheses(); WriteCloseParentheses(); WriteSpace(); BeginBlock(); if (finallyNode != null) { var hashcode = finallyNode.GetHashCode(); Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel { Node = finallyNode, Output = Emitter.Output }); Write(JS.Vars.ASYNC_STEP + " = " + Helpers.PrefixDollar("{", hashcode, "};")); WriteNewLine(); Write("continue;"); } else { Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_RESULT + "(" + JS.Vars.ASYNC_RETURN_VALUE + ");"); WriteNewLine(); WriteReturn(false); WriteSemiColon(); } WriteNewLine(); EndBlock(); if (!Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E)) { AddLocal(JS.Vars.ASYNC_E, null, AstType.Null); } } var lastFinallyStep = Emitter.AsyncBlock.Steps.Last(); var nextStep = Emitter.AsyncBlock.AddAsyncStep(); if (finalyStep != null) { tryInfo.FinallyStep = finalyStep.Step; lastFinallyStep.JumpToStep = nextStep.Step; } tryStep.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step; foreach (var step in catchSteps) { step.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step; } Emitter.AsyncBlock.TryInfos.Add(tryInfo); }
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { TryCatchStatement o = other as TryCatchStatement; return(o != null && this.TryBlock.DoMatch(o.TryBlock, match) && this.CatchClauses.DoMatch(o.CatchClauses, match) && this.FinallyBlock.DoMatch(o.FinallyBlock, match)); }
public virtual S VisitTryCatchStatement(TryCatchStatement tryCatchStatement, T data) { return(VisitChildren(tryCatchStatement, data)); }
public object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { throw new NotImplementedException(); }
protected virtual void EmitMultipleCatchBlock() { TryCatchStatement tryCatchStatement = this.TryCatchStatement; this.WriteCatch(); this.WriteOpenParentheses(); this.Write("$e"); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); this.Write("$e = Bridge.Exception.create($e);"); this.WriteNewLine(); var catchVars = new Dictionary <string, string>(); var writeVar = false; foreach (var clause in tryCatchStatement.CatchClauses) { if (clause.VariableName.IsNotEmpty() && !catchVars.ContainsKey(clause.VariableName)) { if (!writeVar) { writeVar = true; this.WriteVar(true); } this.EnsureComma(false); catchVars.Add(clause.VariableName, clause.VariableName); this.Write(clause.VariableName); this.Emitter.Comma = true; } } this.Emitter.Comma = false; if (writeVar) { this.WriteSemiColon(true); } var firstClause = true; var writeElse = true; foreach (var clause in tryCatchStatement.CatchClauses) { var exceptionType = clause.Type.IsNull ? null : BridgeTypes.ToJsName(clause.Type, this.Emitter); var isBaseException = exceptionType == null || exceptionType == "Bridge.Exception"; if (!firstClause) { this.WriteElse(); } if (isBaseException) { writeElse = false; } else { this.WriteIf(); this.WriteOpenParentheses(); this.Write("Bridge.is($e, " + exceptionType + ")"); this.WriteCloseParentheses(); this.WriteSpace(); } firstClause = false; this.PushLocals(); this.BeginBlock(); if (clause.VariableName.IsNotEmpty()) { this.Write(clause.VariableName + " = $e;"); this.WriteNewLine(); } this.Emitter.NoBraceBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); this.Emitter.NoBraceBlock = null; this.EndBlock(); this.WriteNewLine(); this.PopLocals(); } if (writeElse) { this.WriteElse(); this.BeginBlock(); this.Write("throw $e;"); this.WriteNewLine(); this.EndBlock(); this.WriteNewLine(); } this.EndBlock(); this.WriteNewLine(); }
// Break/Continue/Goto: handled by default logic // ThrowStatement: handled by default logic (just visit the expression) // ReturnStatement: handled by default logic (just visit the expression) public override DefiniteAssignmentStatus VisitTryCatchStatement(TryCatchStatement tryCatchStatement, DefiniteAssignmentStatus data) { return(data); // no special logic when entering the try-catch-finally statement // TODO: where to put the special logic when exiting the try-finally statement? }
public override void Visit(TryCatchStatement node) { this.action(node); }
public void CSharpSimpleTryCatchStatementTest() { TryCatchStatement tryCatchStatement = ParseUtilCSharp.ParseStatement <TryCatchStatement>("try { } catch { } "); // TODO : Extend test. }
public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { if (!tryCatchStatement.TryBlock.IsNull) { FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.TryBlock); } foreach (CatchClause clause in tryCatchStatement.CatchClauses) { PlaceOnNewLine(policy.PlaceCatchOnNewLine, clause.CatchToken); if (!clause.LParToken.IsNull) { ForceSpacesBefore(clause.LParToken, policy.SpaceBeforeCatchParentheses); ForceSpacesAfter(clause.LParToken, policy.SpacesWithinCatchParentheses); ForceSpacesBefore(clause.RParToken, policy.SpacesWithinCatchParentheses); } FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, clause.Body); } if (!tryCatchStatement.FinallyBlock.IsNull) { PlaceOnNewLine(policy.PlaceFinallyOnNewLine, tryCatchStatement.FinallyToken); FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.FinallyBlock); } }
public void CSharpSimpleTryCatchFinallyStatementTest() { TryCatchStatement tryCatchStatement = ParseUtilCSharp.ParseStatement <TryCatchStatement>("try { } catch (Exception) { } finally { } "); // TODO : Extend test. }
// 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); }
public override object Visit (TryCatch tryCatchStatement) { var result = new TryCatchStatement (); result.AddChild (new CSharpTokenNode (Convert (tryCatchStatement.loc), "try".Length), TryCatchStatement.TryKeywordRole); result.AddChild ((INode)tryCatchStatement.Block.Accept (this), TryCatchStatement.TryBlockRole); foreach (Catch ctch in tryCatchStatement.Specific) { result.AddChild (ConvertCatch (ctch), TryCatchStatement.CatchClauseRole); } if (tryCatchStatement.General != null) result.AddChild (ConvertCatch (tryCatchStatement.General), TryCatchStatement.CatchClauseRole); return result; }
public virtual void Enter(TryCatchStatement tryCatchStatement) { }
public virtual void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { StartNode(tryCatchStatement); var oldRef = currentTryReference; currentTryReference = new object(); WriteKeywordReference(TryCatchStatement.TryKeywordRole, currentTryReference); tryCatchStatement.TryBlock.AcceptVisitor(this); int count = 0; foreach (var catchClause in tryCatchStatement.CatchClauses) { if (count-- <= 0) { cancellationToken.ThrowIfCancellationRequested(); count = CANCEL_CHECK_LOOP_COUNT; } catchClause.AcceptVisitor(this); } if (!tryCatchStatement.FinallyBlock.IsNull) { WriteKeywordReference(TryCatchStatement.FinallyKeywordRole, currentTryReference); tryCatchStatement.FinallyBlock.AcceptVisitor(this); } currentTryReference = oldRef; EndNode(tryCatchStatement); }
public virtual void Exit(TryCatchStatement tryCatchStatement) { }
public override void ExplicitVisit(TryCatchStatement fragment) { _fragments.Add(fragment); }
IEnumerable<Statement> TransformNode(ILNode node) { if (node is ILLabel) { yield return new LabelStatement { Label = ((ILLabel)node).Name }; } else if (node is ILExpression) { List<ILRange> ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges)); AstNode codeExpr = TransformExpression((ILExpression)node); if (codeExpr != null) { codeExpr = codeExpr.WithAnnotation(ilRanges); if (codeExpr is Expression) { yield return new ExpressionStatement { Expression = (Expression)codeExpr }; } else if (codeExpr is Statement) { yield return (Statement)codeExpr; } else { throw new Exception(); } } } else if (node is ILWhileLoop) { ILWhileLoop ilLoop = (ILWhileLoop)node; WhileStatement whileStmt = new WhileStatement() { Condition = ilLoop.Condition != null ? (Expression)TransformExpression(ilLoop.Condition) : new PrimitiveExpression(true), EmbeddedStatement = TransformBlock(ilLoop.BodyBlock) }; yield return whileStmt; } else if (node is ILCondition) { ILCondition conditionalNode = (ILCondition)node; bool hasFalseBlock = conditionalNode.FalseBlock.EntryGoto != null || conditionalNode.FalseBlock.Body.Count > 0; yield return new IfElseStatement { Condition = (Expression)TransformExpression(conditionalNode.Condition), TrueStatement = TransformBlock(conditionalNode.TrueBlock), FalseStatement = hasFalseBlock ? TransformBlock(conditionalNode.FalseBlock) : null }; } else if (node is ILSwitch) { ILSwitch ilSwitch = (ILSwitch)node; if (TypeAnalysis.IsBoolean(ilSwitch.Condition.InferredType) && ( from cb in ilSwitch.CaseBlocks where cb.Values != null from val in cb.Values select val ).Any(val => val != 0 && val != 1)) { // If switch cases contain values other then 0 and 1, force the condition to be non-boolean ilSwitch.Condition.ExpectedType = typeSystem.Int32; } SwitchStatement switchStmt = new SwitchStatement() { Expression = (Expression)TransformExpression(ilSwitch.Condition) }; foreach (var caseBlock in ilSwitch.CaseBlocks) { SwitchSection section = new SwitchSection(); if (caseBlock.Values != null) { section.CaseLabels.AddRange(caseBlock.Values.Select(i => new CaseLabel() { Expression = AstBuilder.MakePrimitive(i, ilSwitch.Condition.ExpectedType ?? ilSwitch.Condition.InferredType) })); } else { section.CaseLabels.Add(new CaseLabel()); } section.Statements.Add(TransformBlock(caseBlock)); switchStmt.SwitchSections.Add(section); } yield return switchStmt; } else if (node is ILTryCatchBlock) { ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node); var tryCatchStmt = new TryCatchStatement(); tryCatchStmt.TryBlock = TransformBlock(tryCatchNode.TryBlock); foreach (var catchClause in tryCatchNode.CatchBlocks) { CatchClause clause = new CatchClause { Body = TransformBlock(catchClause) }; if (catchClause.ExceptionVariable != null || (catchClause.ExceptionType != null && !catchClause.ExceptionType.IsCorLibType("System", "Object"))) { clause.Type = AstBuilder.ConvertType(catchClause.ExceptionType); clause.VariableName = catchClause.ExceptionVariable == null ? null : catchClause.ExceptionVariable.Name; clause.AddAnnotation(catchClause.ExceptionVariable); } if (catchClause.FilterBlock != null) { clause.Filter = new FilterClause { Expression = new LambdaExpression { Body = TransformBlock(catchClause.FilterBlock) }.WithAnnotation(new FilterClauseAnnotation()) }; } tryCatchStmt.CatchClauses.Add(clause); } if (tryCatchNode.FinallyBlock != null) tryCatchStmt.FinallyBlock = TransformBlock(tryCatchNode.FinallyBlock); if (tryCatchNode.FaultBlock != null) { CatchClause cc = new CatchClause(); cc.Body = TransformBlock(tryCatchNode.FaultBlock); cc.Body.Add(new ThrowStatement()); // rethrow tryCatchStmt.CatchClauses.Add(cc); } yield return tryCatchStmt; } else if (node is ILFixedStatement) { ILFixedStatement fixedNode = (ILFixedStatement)node; FixedStatement fixedStatement = new FixedStatement(); foreach (ILExpression initializer in fixedNode.Initializers) { Debug.Assert(initializer.Code == ILCode.Stloc); ILVariable v = (ILVariable)initializer.Operand; fixedStatement.Variables.Add( new VariableInitializer { Name = v.Name, Initializer = (Expression)TransformExpression(initializer.Arguments[0]) }.WithAnnotation(v)); } fixedStatement.Type = AstBuilder.ConvertType(((ILVariable)fixedNode.Initializers[0].Operand).Type); fixedStatement.EmbeddedStatement = TransformBlock(fixedNode.BodyBlock); yield return fixedStatement; } else if (node is ILBlock) { yield return TransformBlock((ILBlock)node); } else { throw new Exception("Unknown node type"); } }
public RedILNode VisitTryCatchStatement(TryCatchStatement tryCatchStatement, State data) { throw new System.NotImplementedException(); }
void AddIssueForTryCatchStatement(TryCatchStatement tryCatchStatement) { var lastCatch = tryCatchStatement.CatchClauses.LastOrNullObject(); if (lastCatch.IsNull) return; var removeTryCatchMessage = ctx.TranslateString("Remove try statement"); var removeTryStatementAction = new CodeAction(removeTryCatchMessage, script => { var statements = tryCatchStatement.TryBlock.Statements; if (statements.Count == 1 || tryCatchStatement.Parent is BlockStatement) { foreach (var statement in statements) { script.InsertAfter(tryCatchStatement.PrevSibling, statement.Clone()); } script.Remove(tryCatchStatement); } else { var blockStatement = new BlockStatement(); foreach (var statement in statements) { blockStatement.Statements.Add(statement.Clone()); } script.Replace(tryCatchStatement, blockStatement); } // The replace and insert script functions does not format these things well on their own script.FormatText(tryCatchStatement.Parent); }); var fixes = new [] { removeTryStatementAction }; AddIssue(tryCatchStatement.TryBlock.EndLocation, lastCatch.EndLocation, removeTryCatchMessage, fixes); }
IEnumerable <Syntax> IAstVisitor <ILTranslationContext, IEnumerable <Syntax> > .VisitTryCatchStatement(TryCatchStatement tryCatchStatement, ILTranslationContext data) => OnVisiting(data, tryCatchStatement, VisitingTryCatchStatement) ?? OnVisited(data, tryCatchStatement, VisitedTryCatchStatement, TranslateTryCatchStatement(tryCatchStatement, data));
protected virtual Statement EmitUsing(UsingStatement usingStatement, AstNode expression, IEnumerable <AstNode> inner, VariableDeclarationStatement varStat) { string name = null; BlockStatement wrapper = null; var varInit = expression as VariableInitializer; if (varInit != null) { name = varInit.Name; wrapper = new BlockStatement(); wrapper.Statements.Add(new VariableDeclarationStatement(varStat != null ? varStat.Type.Clone() : AstType.Null, varInit.Name, varInit.Initializer.Clone())); } else if (expression is IdentifierExpression) { name = ((IdentifierExpression)expression).Identifier; } else { name = this.GetTempVarName(); wrapper = new BlockStatement(); wrapper.Statements.Add(new VariableDeclarationStatement(varStat != null ? varStat.Type.Clone() : AstType.Null, name, expression.Clone() as Expression)); } var tryCatchStatement = new TryCatchStatement(); if (wrapper != null) { wrapper.Statements.Add(tryCatchStatement); } if (inner != null && inner.Any()) { var block = new BlockStatement(); block.Statements.Add(this.EmitUsing(usingStatement, inner.First(), inner.Skip(1), varStat)); tryCatchStatement.TryBlock = block; } else { var block = usingStatement.EmbeddedStatement as BlockStatement; if (block == null) { block = new BlockStatement(); block.Add(usingStatement.EmbeddedStatement.Clone()); } else { block = (BlockStatement)block.Clone(); } tryCatchStatement.TryBlock = block; } var finallyBlock = new BlockStatement(); var dispose = new InvocationExpression( new MemberReferenceExpression( new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "Write"), new PrimitiveExpression( string.Format("if (" + JS.Funcs.BRIDGE_HASVALUE + "({0})) {0}." + JS.Funcs.DISPOSE + "();", name)) ); finallyBlock.Statements.Add(dispose); tryCatchStatement.FinallyBlock = finallyBlock; return(wrapper ?? (Statement)tryCatchStatement); }
public StringBuilder VisitTryCatchStatement(TryCatchStatement tryCatchStatement, int data) { throw new SLSharpException("SL# does not have exceptions."); }
public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { if (tryCatchStatement == null) { return data; } if (tryCatchStatement.StatementBlock != null) { tryCatchStatement.StatementBlock.AcceptVisitor(this, data); } if (tryCatchStatement.CatchClauses != null) { foreach (CatchClause catchClause in tryCatchStatement.CatchClauses) { if (catchClause != null) { if (catchClause.TypeReference != null && catchClause.VariableName != null) { AddVariable(catchClause.TypeReference, catchClause.VariableName, catchClause.StatementBlock.StartLocation, catchClause.StatementBlock.EndLocation, false, false, null, null); } catchClause.StatementBlock.AcceptVisitor(this, data); } } } if (tryCatchStatement.FinallyBlock != null) { return tryCatchStatement.FinallyBlock.AcceptVisitor(this, data); } return data; }
public override AstNode VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { return(TransformTryCatchFinally(tryCatchStatement) ?? base.VisitTryCatchStatement(tryCatchStatement)); }
public StringBuilder VisitTryCatchStatement(TryCatchStatement tryCatchStatement, int data) { throw new ASLException("ASL does not have exceptions."); }
//There is no Try/Catch command in MySQL protected override void VisitTryCatchStatement(TryCatchStatement statement) { throw new NotImplementedException(); }
public virtual object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { throw new global::System.NotImplementedException("TryCatchStatement"); }
static Statement GetWatchInstrument (string id, Expression expr) { var r = new MemberReferenceExpression ( new MemberReferenceExpression ( new MemberReferenceExpression ( new IdentifierExpression ("Continuous"), "Server"), "WatchStore"), "Record"); var i = new ExpressionStatement (new InvocationExpression (r, new PrimitiveExpression (id), expr)); var t = new TryCatchStatement (); t.TryBlock = new BlockStatement (); t.TryBlock.Statements.Add (i); var c = new CatchClause (); c.Body = new BlockStatement (); t.CatchClauses.Add (c); return t; }
protected void VisitAsyncTryCatchStatement() { TryCatchStatement tryCatchStatement = this.TryCatchStatement; this.Emitter.AsyncBlock.Steps.Last().JumpToStep = this.Emitter.AsyncBlock.Step; var tryStep = this.Emitter.AsyncBlock.AddAsyncStep(); AsyncTryInfo tryInfo = new AsyncTryInfo(); tryInfo.StartStep = tryStep.Step; this.Emitter.IgnoreBlock = tryCatchStatement.TryBlock; tryCatchStatement.TryBlock.AcceptVisitor(this.Emitter); tryStep = this.Emitter.AsyncBlock.Steps.Last(); tryInfo.EndStep = tryStep.Step; List <IAsyncStep> catchSteps = new List <IAsyncStep>(); foreach (var clause in tryCatchStatement.CatchClauses) { var catchStep = this.Emitter.AsyncBlock.AddAsyncStep(); catchSteps.Add(catchStep); this.PushLocals(); var varName = clause.VariableName; if (!String.IsNullOrEmpty(varName) && !this.Emitter.Locals.ContainsKey(varName)) { varName = this.AddLocal(varName, clause.Type); } tryInfo.CatchBlocks.Add(new Tuple <string, string, int>(varName, clause.Type.IsNull ? "Bridge.Exception" : BridgeTypes.ToJsName(clause.Type, this.Emitter), catchStep.Step)); this.Emitter.IgnoreBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); this.PopLocals(); this.WriteNewLine(); } if (!this.Emitter.Locals.ContainsKey("$async_e")) { this.AddLocal("$async_e", AstType.Null); } IAsyncStep finalyStep = null; if (!tryCatchStatement.FinallyBlock.IsNull) { finalyStep = this.Emitter.AsyncBlock.AddAsyncStep(tryCatchStatement.FinallyBlock); this.Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock; tryCatchStatement.FinallyBlock.AcceptVisitor(this.Emitter); var finallyNode = this.GetParentFinallyBlock(tryCatchStatement, false); this.WriteNewLine(); this.WriteIf(); this.WriteOpenParentheses(); this.Write("$jumpFromFinally > -1"); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); if (finallyNode != null) { var hashcode = finallyNode.GetHashCode(); this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel { Node = finallyNode, Output = this.Emitter.Output }); this.Write("$step = ${" + hashcode + "};"); this.WriteNewLine(); this.Write("continue;"); } else { this.Write("$step = $jumpFromFinally;"); this.WriteNewLine(); this.Write("$jumpFromFinally = null;"); } this.WriteNewLine(); this.EndBlock(); this.WriteSpace(); this.WriteElse(); this.WriteIf(); this.WriteOpenParentheses(); this.Write("$async_e"); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); this.Write("$tcs.setException($async_e);"); this.WriteNewLine(); this.WriteReturn(false); this.WriteSemiColon(); this.WriteNewLine(); this.EndBlock(); this.WriteSpace(); this.WriteElse(); this.WriteIf(); this.WriteOpenParentheses(); this.Write("Bridge.isDefined($returnValue)"); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); if (finallyNode != null) { var hashcode = finallyNode.GetHashCode(); this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel { Node = finallyNode, Output = this.Emitter.Output }); this.Write("$step = ${" + hashcode + "};"); this.WriteNewLine(); this.Write("continue;"); } else { this.Write("$tcs.setResult($returnValue);"); this.WriteNewLine(); this.WriteReturn(false); this.WriteSemiColon(); } this.WriteNewLine(); this.EndBlock(); if (!this.Emitter.Locals.ContainsKey("$async_e")) { this.AddLocal("$async_e", AstType.Null); } } var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); if (finalyStep != null) { tryInfo.FinallyStep = finalyStep.Step; } if (finalyStep != null) { finalyStep.JumpToStep = nextStep.Step; } tryStep.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step; foreach (var step in catchSteps) { step.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step; } this.Emitter.AsyncBlock.TryInfos.Add(tryInfo); }
public virtual void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { VisitBlock(tryCatchStatement.TryBlock); VisitBlock(tryCatchStatement.CatchBlock); }
public override object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) { return(base.VisitTryCatchStatement(tryCatchStatement, data)); }
public virtual void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { StartNode(tryCatchStatement); WriteKeyword(TryCatchStatement.TryKeywordRole); WriteBlock(tryCatchStatement.TryBlock, policy.StatementBraceStyle); foreach (var catchClause in tryCatchStatement.CatchClauses) { if (policy.CatchNewLinePlacement == NewLinePlacement.SameLine) Space(); else NewLine(); catchClause.AcceptVisitor(this); } if (!tryCatchStatement.FinallyBlock.IsNull) { if (policy.FinallyNewLinePlacement == NewLinePlacement.SameLine) Space(); else NewLine(); WriteKeyword(TryCatchStatement.FinallyKeywordRole); WriteBlock(tryCatchStatement.FinallyBlock, policy.StatementBraceStyle); } NewLine(); EndNode(tryCatchStatement); }
public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data) { if (!IsClassType(ClassType.Interface) && (methodDeclaration.Modifier & Modifiers.Visibility) == 0) { methodDeclaration.Modifier |= Modifiers.Public; } if ("Finalize".Equals(methodDeclaration.Name, StringComparison.InvariantCultureIgnoreCase) && methodDeclaration.Parameters.Count == 0 && methodDeclaration.Modifier == (Modifiers.Protected | Modifiers.Override) && methodDeclaration.Body.Children.Count == 1) { TryCatchStatement tcs = methodDeclaration.Body.Children[0] as TryCatchStatement; if (tcs != null && tcs.StatementBlock is BlockStatement && tcs.CatchClauses.Count == 0 && tcs.FinallyBlock is BlockStatement && tcs.FinallyBlock.Children.Count == 1) { ExpressionStatement se = tcs.FinallyBlock.Children[0] as ExpressionStatement; if (se != null) { InvocationExpression ie = se.Expression as InvocationExpression; if (ie != null && ie.Arguments.Count == 0 && ie.TargetObject is MemberReferenceExpression && (ie.TargetObject as MemberReferenceExpression).TargetObject is BaseReferenceExpression && "Finalize".Equals((ie.TargetObject as MemberReferenceExpression).MemberName, StringComparison.InvariantCultureIgnoreCase)) { DestructorDeclaration des = new DestructorDeclaration("Destructor", Modifiers.None, methodDeclaration.Attributes); ReplaceCurrentNode(des); des.Body = (BlockStatement)tcs.StatementBlock; return(base.VisitDestructorDeclaration(des, data)); } } } } if ((methodDeclaration.Modifier & (Modifiers.Static | Modifiers.Extern)) == Modifiers.Static && methodDeclaration.Body.Children.Count == 0) { foreach (AttributeSection sec in methodDeclaration.Attributes) { foreach (Attribute att in sec.Attributes) { if ("DllImport".Equals(att.Name, StringComparison.InvariantCultureIgnoreCase)) { methodDeclaration.Modifier |= Modifiers.Extern; methodDeclaration.Body = null; } } } } if (methodDeclaration.TypeReference.Type != "System.Void" && methodDeclaration.Body.Children.Count > 0) { if (IsAssignmentTo(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1], methodDeclaration.Name)) { Expression returnValue = GetAssignmentFromStatement(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1]).Right; methodDeclaration.Body.Children.RemoveAt(methodDeclaration.Body.Children.Count - 1); methodDeclaration.Body.Return(returnValue); } else { ReturnStatementForFunctionAssignment visitor = new ReturnStatementForFunctionAssignment(methodDeclaration.Name); methodDeclaration.Body.AcceptVisitor(visitor, null); if (visitor.replacementCount > 0) { Expression init; init = ExpressionBuilder.CreateDefaultValueForType(methodDeclaration.TypeReference); methodDeclaration.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, methodDeclaration.TypeReference))); methodDeclaration.Body.Children[0].Parent = methodDeclaration.Body; methodDeclaration.Body.Return(new IdentifierExpression(FunctionReturnValueName)); } } } return(base.VisitMethodDeclaration(methodDeclaration, data)); }
public virtual void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { if (this.ThrowException) { throw (Exception)this.CreateException(tryCatchStatement); } }
public Ust VisitStatement(JavaParser.StatementContext context) { var textSpan = context.GetTextSpan(); Statement result; Expression expression; Statement statement; List <Statement> statements; if (context.blockLabel != null) { result = (Statement)Visit(context.blockLabel); return(result); } if (context.statementExpression != null) { result = Visit(context.statementExpression).ToStatementIfRequired(); return(result); } if (context.identifierLabel != null) { var defaultResult = VisitChildren(context); return(new WrapperStatement(defaultResult, textSpan)); } int firstTokenType = context.GetChild <ITerminalNode>(0).Symbol.Type; if (firstTokenType == JavaLexer.ASSERT) { var defaultResult = VisitChildren(context); return(new WrapperStatement(defaultResult, textSpan)); } if (firstTokenType == JavaLexer.IF) { var condition = (Expression)Visit(context.parExpression()); var trueStatement = (Statement)Visit(context.statement(0)); var falseStatment = context.ELSE() == null ? null : (Statement)Visit(context.statement(1)); result = new IfElseStatement(condition, trueStatement, textSpan) { FalseStatement = falseStatment }; return(result); } if (firstTokenType == JavaLexer.FOR) { result = (Statement)Visit(context.forControl()); return(result); } if (firstTokenType == JavaLexer.WHILE) { var conditionWhile = (Expression)Visit(context.parExpression()); statement = (Statement)Visit(context.statement(0)); result = new WhileStatement(conditionWhile, statement, textSpan); return(result); } if (firstTokenType == JavaLexer.DO) { statement = (Statement)Visit(context.statement(0)); expression = (Expression)Visit(context.parExpression()); result = new DoWhileStatement(statement, expression, textSpan); return(result); } if (firstTokenType == JavaLexer.TRY) { // TODO: implement 'try' resourceSpecification block catchClause* finallyBlock? (C# using) var block = (BlockStatement)Visit(context.block()); JavaParser.ResourceSpecificationContext resSpec = context.resourceSpecification(); List <CatchClause> catchClauses = context.catchClause() ?.Select(cc => (CatchClause)Visit(cc)) .Where(cc => cc != null).ToList(); var finallyBlock = context.finallyBlock() == null ? null : (BlockStatement)Visit(context.finallyBlock()); if (resSpec == null) { result = new TryCatchStatement(block, textSpan) { CatchClauses = catchClauses, FinallyBlock = finallyBlock }; } else { // C# using conversion to tryCatch statements = new List <Statement>(); statements.AddRange(resSpec.resources().resource() .Select(res => { var e = (VariableDeclarationExpression)Visit(res); return(e == null ? null : new ExpressionStatement(e)); }) .Where(res => res != null)); statements.AddRange(block.Statements); var blockStatement = new BlockStatement(statements, context.GetTextSpan()); result = new TryCatchStatement(block, textSpan) { CatchClauses = catchClauses, FinallyBlock = finallyBlock }; } return(result); } if (firstTokenType == JavaLexer.SWITCH) { expression = (Expression)Visit(context.parExpression()); SwitchSection[] switchSections = context.switchBlockStatementGroup() .Select(group => (SwitchSection)Visit(group)) .Where(group => group != null).ToArray(); result = new SwitchStatement(expression, switchSections, textSpan); return(result); } if (firstTokenType == JavaLexer.SYNCHRONIZED) // synchronized(a) { b; c; } => { a; b; c; } { var resultStatements = new List <Statement>(); expression = (Expression)Visit(context.parExpression()); statements = context.block().blockStatement() .Select(s => (Statement)Visit(s)) .Where(s => s != null).ToList(); resultStatements.Add(new ExpressionStatement(expression, expression.TextSpan)); resultStatements.AddRange(statements); result = new BlockStatement(resultStatements, textSpan); return(result); } if (firstTokenType == JavaLexer.RETURN) { expression = context.expression(0) != null ? (Expression)Visit(context.expression(0)) : null; result = new ReturnStatement(expression, textSpan); return(result); } if (firstTokenType == JavaLexer.THROW) { expression = (Expression)Visit(context.expression(0)); result = new ThrowStatement(expression, textSpan); return(result); } if (firstTokenType == JavaLexer.BREAK) { result = new BreakStatement(textSpan); return(result); } if (firstTokenType == JavaLexer.CONTINUE) { result = new ContinueStatement(textSpan); return(result); } if (firstTokenType == JavaLexer.SEMI) { result = new EmptyStatement(textSpan); return(result); } return(VisitShouldNotBeVisited(context)); }
public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { var tryBlock = CreateInnerCompiler().Compile(tryCatchStatement.TryBlock); JsCatchClause catchClause = null; if (tryCatchStatement.CatchClauses.Count > 0) { var oldVariableForRethrow = _currentVariableForRethrow; _currentVariableForRethrow = CreateTemporaryVariable(_compilation.FindType(KnownTypeCode.Object), tryCatchStatement.CatchClauses.First().GetRegion()); string catchVariableName = _variables[_currentVariableForRethrow].Name; var catchClauses = tryCatchStatement.CatchClauses.ToList(); var systemException = _compilation.FindType(KnownTypeCode.Exception); RemoveCatchClausesAfterExceptionType(catchClauses, systemException); bool lastIsCatchall = (catchClauses[catchClauses.Count - 1].Type.IsNull || _resolver.Resolve(catchClauses[catchClauses.Count - 1].Type).Type.Equals(systemException)); JsStatement current = lastIsCatchall ? CompileCatchClause(new LocalResolveResult(_currentVariableForRethrow), catchClauses[catchClauses.Count - 1], true, catchClauses.Count == 1) : JsStatement.Block(JsStatement.Throw(JsExpression.Identifier(catchVariableName))); for (int i = catchClauses.Count - (lastIsCatchall ? 2 : 1); i >= 0; i--) { var test = _runtimeLibrary.TypeIs(JsExpression.Identifier(catchVariableName), _currentVariableForRethrow.Type, _resolver.Resolve(catchClauses[i].Type).Type, this); current = JsStatement.If(test, CompileCatchClause(new LocalResolveResult(_currentVariableForRethrow), catchClauses[i], false, catchClauses.Count == 1), current); } if (!lastIsCatchall || catchClauses.Count > 1) { // We need to wrap the exception. current = JsStatement.Block(JsExpression.Assign(JsExpression.Identifier(catchVariableName), _runtimeLibrary.MakeException(JsExpression.Identifier(catchVariableName), this)), current); } catchClause = JsStatement.Catch(catchVariableName, current); _currentVariableForRethrow = oldVariableForRethrow; } var finallyBlock = (!tryCatchStatement.FinallyBlock.IsNull ? CreateInnerCompiler().Compile(tryCatchStatement.FinallyBlock) : null); _result.Add(JsStatement.Try(tryBlock, catchClause, finallyBlock)); }
public override object Visit(TryCatch tryCatchStatement) { var result = new TryCatchStatement(); result.AddChild(new CSharpTokenNode(Convert(tryCatchStatement.loc), TryCatchStatement.TryKeywordRole), TryCatchStatement.TryKeywordRole); if (tryCatchStatement.Block != null) result.AddChild((BlockStatement)tryCatchStatement.Block.Accept(this), TryCatchStatement.TryBlockRole); if (tryCatchStatement.Clauses != null) { foreach (var ctch in tryCatchStatement.Clauses) { result.AddChild(ConvertCatch(ctch), TryCatchStatement.CatchClauseRole); } } // if (tryCatchStatement.General != null) // result.AddChild (ConvertCatch (tryCatchStatement.General), TryCatchStatement.CatchClauseRole); return result; }
protected virtual void EmitMultipleCatchBlock() { TryCatchStatement tryCatchStatement = this.TryCatchStatement; this.WriteCatch(); this.WriteOpenParentheses(); var varName = this.AddLocal(this.GetUniqueName(JS.Vars.E), null, AstType.Null); var oldVar = this.Emitter.CatchBlockVariable; this.Emitter.CatchBlockVariable = varName; this.Write(varName); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); this.Write(string.Format("{0} = " + JS.Types.System.Exception.CREATE + "({0});", varName)); this.WriteNewLine(); var catchVars = new Dictionary <string, string>(); var writeVar = false; foreach (var clause in tryCatchStatement.CatchClauses) { if (clause.VariableName.IsNotEmpty() && !catchVars.ContainsKey(clause.VariableName)) { if (!writeVar) { writeVar = true; this.WriteVar(true); } this.EnsureComma(false); catchVars.Add(clause.VariableName, clause.VariableName); this.Write(clause.VariableName); this.Emitter.Comma = true; } } this.Emitter.Comma = false; if (writeVar) { this.WriteSemiColon(true); } var firstClause = true; var writeElse = true; var needNewLine = false; foreach (var clause in tryCatchStatement.CatchClauses) { var exceptionType = clause.Type.IsNull ? null : BridgeTypes.ToJsName(clause.Type, this.Emitter); var isBaseException = exceptionType == null || exceptionType == JS.Types.System.Exception.NAME; if (!firstClause) { this.WriteSpace(); this.WriteElse(); } if (isBaseException) { writeElse = false; } else { this.WriteIf(); this.WriteOpenParentheses(); this.Write(string.Format(JS.Types.Bridge.IS + "({0}, {1})", varName, exceptionType)); this.WriteCloseParentheses(); this.WriteSpace(); } firstClause = false; this.PushLocals(); this.BeginBlock(); if (clause.VariableName.IsNotEmpty()) { this.Write(clause.VariableName + " = " + varName); this.WriteSemiColon(); this.WriteNewLine(); } this.Emitter.NoBraceBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); this.Emitter.NoBraceBlock = null; this.EndBlock(); needNewLine = true; this.PopLocals(); } if (writeElse) { this.WriteSpace(); this.WriteElse(); this.BeginBlock(); this.Write("throw " + varName); this.WriteSemiColon(); this.WriteNewLine(); this.EndBlock(); needNewLine = true; } if (needNewLine) { this.WriteNewLine(); needNewLine = false; } this.EndBlock(); this.WriteNewLine(); this.Emitter.CatchBlockVariable = oldVar; }
public override object Visit (TryFinally tryFinallyStatement) { TryCatchStatement result; var location = LocationsBag.GetLocations (tryFinallyStatement); if (tryFinallyStatement.Stmt is TryCatch) { result = (TryCatchStatement)tryFinallyStatement.Stmt.Accept (this); } else { result = new TryCatchStatement (); result.AddChild (new CSharpTokenNode (Convert (tryFinallyStatement.loc), "try".Length), TryCatchStatement.TryKeywordRole); result.AddChild ((INode)tryFinallyStatement.Stmt.Accept (this), TryCatchStatement.TryBlockRole); } if (location != null) result.AddChild (new CSharpTokenNode (Convert (location[0]), "finally".Length), TryCatchStatement.FinallyKeywordRole); result.AddChild ((INode)tryFinallyStatement.Fini.Accept (this), TryCatchStatement.FinallyBlockRole); return result; }
void TryStatement( #line 1697 "cs.ATG" out Statement tryStatement) { #line 1699 "cs.ATG" Statement blockStmt = null, finallyStmt = null; List<CatchClause> catchClauses = null; Expect(114); Block( #line 1703 "cs.ATG" out blockStmt); if (la.kind == 56) { CatchClauses( #line 1705 "cs.ATG" out catchClauses); if (la.kind == 73) { lexer.NextToken(); Block( #line 1705 "cs.ATG" out finallyStmt); } } else if (la.kind == 73) { lexer.NextToken(); Block( #line 1706 "cs.ATG" out finallyStmt); } else SynErr(203); #line 1709 "cs.ATG" tryStatement = new TryCatchStatement(blockStmt, catchClauses, finallyStmt); if (catchClauses != null) { foreach (CatchClause cc in catchClauses) cc.Parent = tryStatement; } }
public void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { StartNode(tryCatchStatement); WriteKeyword(TryCatchStatement.TryKeywordRole); tryCatchStatement.TryBlock.AcceptVisitor(this); foreach (var catchClause in tryCatchStatement.CatchClauses) { catchClause.AcceptVisitor(this); } if (!tryCatchStatement.FinallyBlock.IsNull) { WriteKeyword(TryCatchStatement.FinallyKeywordRole); tryCatchStatement.FinallyBlock.AcceptVisitor(this); } EndNode(tryCatchStatement); }
public virtual Node VisitTryCatchStatement(TryCatchStatement tryCatchStatement) { throw new System.NotImplementedException(); }