/// <summary> /// Parse an orphaned <see cref="Finally"/>. /// </summary> public static Finally ParseOrphan(Parser parser, CodeObject parent, ParseFlags flags) { Token token = parser.Token; Finally @finally = Parse(parser, parent); parser.AttachMessage(@finally, "Orphaned 'finally' - missing parent 'try'", token); return(@finally); }
protected Try(Parser parser, CodeObject parent) : base(parser, parent) { // Flush any unused objects first, so that they don't interfere with skipping // compiler directives below, or the parsing of any 'else' part. if (parser.HasUnused && _parent is BlockStatement) { ((BlockStatement)_parent).Body.FlushUnused(parser); } parser.NextToken(); // Move past 'try' new Block(out _body, parser, this, true); // Parse the body // Skip over any compiler directives that might occur before a 'catch' or 'finally', adding them to the unused list ParseAnnotations(parser, parent, false, true); while (parser.TokenText == Catch.ParseToken || parser.TokenText == Finally.ParseToken) { // Parse optional 'catch' child part while (parser.TokenText == Catch.ParseToken) { CreateCatches().Add(Catch.Parse(parser, this)); // Skip over any compiler directives that might occur before a 'catch' or 'finally', adding them to the unused list ParseAnnotations(parser, parent, false, true); } // Parse optional 'finally' child part if (parser.TokenText == Finally.ParseToken) { _finally = Finally.Parse(parser, this); } } // If we skipped any compiler directives that weren't followed by a 'catch' or 'finally', we have // to move them now so they can be manually flushed by the parent Block *after* this statement. if (parser.HasUnused) { parser.MoveUnusedToPostUnused(); } }
/// <summary> /// Create a <see cref="Try"/>. /// </summary> public Try(CodeObject body, Finally @finally, params Catch[] catches) : this(body, @finally) { CreateCatches().AddRange(catches); }
/// <summary> /// Create a <see cref="Try"/>. /// </summary> public Try(CodeObject body, Finally @finally) : base(body, false) { Finally = @finally; }