protected override ISymbol GetExceptionTypeSymbolFromCatchClause(CatchClauseSyntax catchNode, SemanticModel model) { Debug.Assert(catchNode != null); var typeDeclNode = catchNode.Declaration; return(typeDeclNode == null ? TypesOfInterest.SystemObject : SyntaxNodeHelper.GetSymbol(typeDeclNode.Type, model)); }
public static void Analyze(SyntaxNodeAnalysisContext context, CatchClauseSyntax catchClause) { CatchDeclarationSyntax declaration = catchClause.Declaration; if (declaration != null) { BlockSyntax block = catchClause.Block; if (block != null && declaration.Type != null && !block.Statements.Any()) { ITypeSymbol typeSymbol = context .SemanticModel .GetTypeSymbol(declaration.Type, context.CancellationToken); if (typeSymbol?.IsErrorType() == false) { INamedTypeSymbol exceptionTypeSymbol = context.GetTypeByMetadataName(MetadataNames.System_Exception); if (typeSymbol.Equals(exceptionTypeSymbol)) { context.ReportDiagnostic( DiagnosticDescriptors.AvoidEmptyCatchClauseThatCatchesSystemException, catchClause.CatchKeyword.GetLocation()); } } } } }
/// <summary> /// Добавление выражения внутрь catch конструкции try..catch.. /// </summary> /// <param name="catchClause"></param> /// <param name="expressionStatementSyntax">Выражение в начале кода.</param> /// <param name="paramName"></param> /// <param name="paramType"></param> /// <returns></returns> public CatchClauseSyntax AddExpressionToCatchConstructionMethodsBody(CatchClauseSyntax catchClause, string calledProc, string paramName = "", string paramType = "") { CodeAnalyzer codeAnalyzer = new CodeAnalyzer(); ExpressionStatementSyntax exp = null; if (catchClause.Declaration == null || catchClause.Declaration.Identifier.ValueText == null) { catchClause = AddParameterToCatch(catchClause, paramName, paramType); exp = CreatingCallProcedureExpression(calledProc, new List <string> { $"{paramName}.Message" }); } else { exp = CreatingCallProcedureExpression(calledProc, new List <string> { $"{catchClause.Declaration.Identifier.ValueText}.Message" }); } List <StatementSyntax> lst = new List <StatementSyntax>(); lst.Add(exp); lst.AddRange(catchClause.Block.Statements); catchClause = catchClause.WithBlock(SyntaxFactory.Block(lst)).NormalizeWhitespace(); return(catchClause); }
protected override ISymbol GetExceptionTypeSymbolFromCatchClause(CatchClauseSyntax catchNode, SemanticModel model) { Debug.Assert(catchNode != null); CatchDeclarationSyntax typeDeclNode = catchNode.Declaration; return(typeDeclNode == null ? TypesOfInterest.SystemObject : typeDeclNode.Type.GetDeclaredOrReferencedSymbol(model)); }
public override UstNode VisitCatchClause(CatchClauseSyntax node) { TypeToken typeToken; IdToken varName; if (node.Declaration == null) { typeToken = new TypeToken("Exception", node.CatchKeyword.GetTextSpan(), FileNode); varName = new IdToken("e", node.CatchKeyword.GetTextSpan(), FileNode); } else { typeToken = ConvertType(base.Visit(node.Declaration.Type)); varName = new IdToken(node.Declaration.Identifier.ValueText ?? "", node.Declaration.GetTextSpan(), FileNode); } var body = (BlockStatement)VisitBlock(node.Block); var result = new CatchClause( typeToken, varName, body, node.GetTextSpan(), FileNode); return(result); }
public static Doc Print(CatchClauseSyntax node) { var docs = new List <Doc>(); docs.Add(Token.Print(node.CatchKeyword)); if (node.Declaration != null) { docs.Add( " ", Token.Print(node.Declaration.OpenParenToken), Node.Print(node.Declaration.Type), node.Declaration.Identifier.RawKind != 0 ? " " : Doc.Null, Token.Print(node.Declaration.Identifier), Token.Print(node.Declaration.CloseParenToken) ); } if (node.Filter != null) { docs.Add( " ", Token.Print(node.Filter.WhenKeyword, " "), Token.Print(node.Filter.OpenParenToken), Node.Print(node.Filter.FilterExpression), Token.Print(node.Filter.CloseParenToken) ); } docs.Add(Block.Print(node.Block)); return(Doc.Concat(docs)); }
private static Diagnostic AnalyzeCatch(CatchClauseSyntax catchSyntax) { var variableName = GetCatchDeclarationVariableName(catchSyntax); // if specific exception type used, but no variable, assume that this is intentional handling. if (variableName == null) { return(null); } var catchAnalysisResults = catchSyntax.Block.Statements .Select(x => (node: x, result: IsVariableUsedInStatement(variableName, x))) .Distinct() .ToList(); if (catchAnalysisResults.Count == 0 || catchAnalysisResults.All(x => x.result == StatementAnalysisResult.NoUsage)) { return(Diagnostic.Create(Descriptors.NoExceptionUsageDescriptor, catchSyntax.CatchKeyword.GetLocation())); } var rethrowCase = catchAnalysisResults.FirstOrDefault(x => x.result == StatementAnalysisResult.RethrowSameException); if (rethrowCase.node != null) { return(Diagnostic.Create(Descriptors.RethrowSameExceptionDescriptor, rethrowCase.node.GetLocation())); } if (catchAnalysisResults.Any(x => x.result == StatementAnalysisResult.RethrowWithoutInnerException)) { return(Diagnostic.Create(Descriptors.RethrowWithoutInnerDescriptor, catchSyntax.CatchKeyword.GetLocation())); } return(null); }
private Doc PrintCatchClauseSyntax(CatchClauseSyntax node) { var parts = new Parts(); parts.Push(this.PrintSyntaxToken(node.CatchKeyword)); if (node.Declaration != null) { parts.Push( " ", this.PrintSyntaxToken(node.Declaration.OpenParenToken), this.Print(node.Declaration.Type), node.Declaration.Identifier.RawKind != 0 ? " " : Doc.Null, this.PrintSyntaxToken(node.Declaration.Identifier), this.PrintSyntaxToken(node.Declaration.CloseParenToken) ); } if (node.Filter != null) { parts.Push( " ", this.PrintSyntaxToken(node.Filter.WhenKeyword, " "), this.PrintSyntaxToken(node.Filter.OpenParenToken), this.Print(node.Filter.FilterExpression), this.PrintSyntaxToken(node.Filter.CloseParenToken) ); } parts.Push(this.PrintBlockSyntax(node.Block)); return(Concat(parts)); }
public static bool Catches(SemanticModel model, CatchClauseSyntax @catch, ITypeSymbol throwType) { var catchType = model.GetTypeInfo(@catch.Declaration.Type).Type; if (!throwType.InheritsFromOrEquals(catchType)) { return(false); } if (@catch.Filter != null) { string varName = @catch.Declaration.Identifier.ToString(); if (string.IsNullOrWhiteSpace(varName)) { // They don't capture the exception variable. As such, there is no way // the filter can be a simple type filter and thus it will likely // be too complex to analyze. Assume it's possible to leak the exception. return(false); } var result = @catch.Filter.FilterExpression.Accept(new FilterExpressionMatchesTypeVisitor(model, varName, throwType)); return(result); } return(true); }
public override void VisitCatchClause(CatchClauseSyntax node) { MethodInfo mi = m_MethodInfoStack.Peek(); mi.TryCatchUsingOrLoopSwitchStack.Push(true); ReturnContinueBreakAnalysis returnAnalysis = mi.TempReturnAnalysisStack.Peek(); string handledVar = string.Format("__catch_handled_{0}", GetSourcePosForVar(node)); string bodyVar = string.Format("__catch_body_{0}", GetSourcePosForVar(node)); CodeBuilder.AppendFormat("{0}(function({1}", GetIndentString(), handledVar); if (null != node.Declaration) { CodeBuilder.Append(", "); CodeBuilder.Append(node.Declaration.Identifier.Text); } CodeBuilder.Append("){"); CodeBuilder.AppendLine(); ++m_Indent; if (null != node.Filter) { CodeBuilder.Append("if("); IConversionExpression opd = m_Model.GetOperation(node.Filter.FilterExpression) as IConversionExpression; OutputExpressionSyntax(node.Filter.FilterExpression, opd); CodeBuilder.Append("){"); CodeBuilder.AppendLine(); ++m_Indent; } CodeBuilder.AppendFormat("{0}{1} = true;", GetIndentString(), handledVar); CodeBuilder.AppendLine(); if (null != node.Filter) { --m_Indent; CodeBuilder.AppendFormat("{0}}};", GetIndentString()); CodeBuilder.AppendLine(); } if (returnAnalysis.Exist) { CodeBuilder.AppendFormat("{0}local({1}); {1} = function(){{", GetIndentString(), bodyVar); CodeBuilder.AppendLine(); ++m_Indent; VisitBlock(node.Block); --m_Indent; CodeBuilder.AppendFormat("{0}}};", GetIndentString()); CodeBuilder.AppendLine(); CodeBuilder.AppendFormat("{0}return({1}, {2}());", GetIndentString(), handledVar, bodyVar); CodeBuilder.AppendLine(); } else { VisitBlock(node.Block); CodeBuilder.AppendFormat("{0}return({1}, null);", GetIndentString(), handledVar); CodeBuilder.AppendLine(); } --m_Indent; CodeBuilder.AppendFormat("{0}}})", GetIndentString()); CodeBuilder.AppendLine(); mi.TryCatchUsingOrLoopSwitchStack.Pop(); }
private static double ComputeWeightedDistance(CatchClauseSyntax left, CatchClauseSyntax right) { var blockDistance = ComputeDistance(left.Block, right.Block); var distance = CombineOptional(blockDistance, left.Declaration, right.Declaration, left.Filter, right.Filter); return(AdjustForLocalsInBlock(distance, left.Block, right.Block, localsWeight: 0.3)); }
public static Doc Print(CatchClauseSyntax node) { return(Doc.Concat( Token.Print(node.CatchKeyword), Doc.Group( node.Declaration != null ? Doc.Concat( " ", Token.Print(node.Declaration.OpenParenToken), Node.Print(node.Declaration.Type), node.Declaration.Identifier.RawKind != 0 ? " " : Doc.Null, Token.Print(node.Declaration.Identifier), Token.Print(node.Declaration.CloseParenToken) ) : Doc.Null, node.Filter != null ? Doc.Indent( Doc.Line, Token.PrintWithSuffix(node.Filter.WhenKeyword, " "), Token.Print(node.Filter.OpenParenToken), Doc.Group( Doc.Indent(Node.Print(node.Filter.FilterExpression)), Doc.SoftLine ), Token.Print(node.Filter.CloseParenToken) ) : Doc.Null ), Block.Print(node.Block) )); }
public static async Task <Document> RefactorAsync( Document document, FinallyClauseSyntax finallyClause, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); if (finallyClause.GetLeadingTrivia().All(f => f.IsWhitespaceOrEndOfLineTrivia())) { var tryStatement = (TryStatementSyntax)finallyClause.Parent; SyntaxList <CatchClauseSyntax> catches = tryStatement.Catches; CatchClauseSyntax lastCatch = catches[catches.Count - 1]; if (lastCatch.GetTrailingTrivia().All(f => f.IsWhitespaceOrEndOfLineTrivia())) { TryStatementSyntax newTryStatement = tryStatement .WithCatches(catches.Replace(lastCatch, lastCatch.WithTrailingTrivia(finallyClause.GetTrailingTrivia()))) .WithFinally(null); return(await document.ReplaceNodeAsync(tryStatement, newTryStatement, cancellationToken).ConfigureAwait(false)); } } return(await document.RemoveNodeAsync(finallyClause, SyntaxRemoveOptions.KeepExteriorTrivia, cancellationToken).ConfigureAwait(false)); }
protected override void VisitCatchClause(CatchClauseSyntax node) { if (node.Block.Statements.Count == 0) { Console.WriteLine("You have an empty catch block! bad developer! bad!"); } base.VisitCatchClause(node); }
internal static CatchBlock CreateCatchBlock(CatchClauseSyntax node, ISyntaxEntity parent, CodeFile codeFile, SyntaxTree tree) { return(new CatchBlock("", new FileSpan(tree.GetLineSpan(node.Span)), parent, codeFile) { CatchType = node.Declaration.Type.ToString(), CatchFilterClause = (null == node.Filter) ? string.Empty : node.Filter.FilterExpression.ToString() }); }
public override void VisitCatchClause(CatchClauseSyntax node) { node.Declaration?.Accept(this); node.Filter?.Accept(this); node.Block?.Accept(this); base.VisitCatchClause(node); }
public override Evaluation VisitCatchClause(CatchClauseSyntax node) { node.Declaration?.Accept <Evaluation>(this); node.Filter?.Accept <Evaluation>(this); node.Block?.Accept <Evaluation>(this); return(base.VisitCatchClause(node)); }
public CatchStatementInterpreter(StatementInterpreterHandler statementInterpreterHandler, CatchClauseSyntax catchClauseSyntax, Microsoft.CodeAnalysis.SemanticModel semanticModel) { this.statementInterpreterHandler = statementInterpreterHandler; this.catchClauseSyntax = catchClauseSyntax; this.semanticModel = semanticModel; }
public static CatchClauseSyntax FindProblematicCatchClause(WhileStatementSyntax whileStatement, SemanticModel model) { var blockSyntax = whileStatement.Statement as BlockSyntax; if (blockSyntax is null) { return(null); } var innerStatements = blockSyntax.Statements; if (innerStatements.Count != 1) { // only applies when try directly nested under while and only child return(null); } var tryCatchStatement = innerStatements[0] as TryStatementSyntax; if (tryCatchStatement is null) { // Not a try catch nested in a while return(null); } CatchClauseSyntax catchClause = null; var willCatchThreadAbort = false; var willRethrowThreadAbort = false; foreach (var catchSyntax in tryCatchStatement.Catches) { catchClause = catchSyntax; var exceptionTypeSyntax = catchSyntax.Declaration.Type; if (CanCatchThreadAbort(exceptionTypeSyntax, model)) { willCatchThreadAbort = true; // We're in the catch block that will catch the ThreadAbort // Make sure that we re-throw the exception // This is a very basic check, in that it doesn't check control flow etc // It requires that you have a throw; in the catch block // We are only checking the direct ancestors (nesting breaks this analysis) // and if you have an expression, it must be the exception declared in the willRethrowThreadAbort = catchSyntax.Block.Statements .OfType <ThrowStatementSyntax>() .Any(); break; } } if (willCatchThreadAbort && !willRethrowThreadAbort) { return(catchClause); } return(null); }
protected override SyntaxNode VisitCatchClause(CatchClauseSyntax node) { if (node.Block.Statements.Count == 0) { return Syntax.CatchClause( block: Syntax.Block(statements:Syntax.ThrowStatement())); } return base.VisitCatchClause(node); }
public AddThrowCodeAction(CodeActionEdit editFactory, IDocument document, CommonSyntaxNode node) { _editFactory = editFactory; _document = document; _node = (CatchClauseSyntax)node; Description = "please throw the exception if you can't handle it"; Icon = null; }
public override void VisitCatchClause(CatchClauseSyntax node) { var catchObj = CSharpEntityCreationHelper.CreateCatchBlock(node, m_currentParent, m_currentCodeFile, m_currentTree); ISyntaxEntity oldParent = setCurrentParent(catchObj); base.VisitCatchClause(node); m_currentParent = oldParent; }
public CatchClauseBinder(Binder enclosing, CatchClauseSyntax syntax) : base( enclosing, (enclosing.Flags | BinderFlags.InCatchBlock) & ~BinderFlags.InNestedFinallyBlock ) { Debug.Assert(syntax != null); _syntax = syntax; }
public override void VisitCatchClause(CatchClauseSyntax node) { if (entryPoint.IsMethodLevel() && node.IsParent <AnonymousFunctionExpressionSyntax>()) { return; } base.VisitCatchClause(node); nobcounter++; }
public override void VisitCatchClause(CatchClauseSyntax node) { if (!node.Block.Statements.Any()) { var method = node.Ancestors() .OfType<MethodDeclarationSyntax>().First(); Console.WriteLine("Empty catch block in method : {0}", method.Identifier.Text); } }
public override SyntaxNode VisitCatchClause(CatchClauseSyntax node) { if (node.Block.Statements.Count == 0) { return Syntax.CatchClause( declaration: node.Declaration, block: Syntax.Block(statements: Syntax.ThrowStatement())); } return base.VisitCatchClause(node); }
/// <remarks> /// Used to determine whether it would be appropriate to use the binder for the statement (if any). /// Not used to determine whether the position is syntactically within the statement. /// </remarks> internal static bool IsInCatchBlockScope(int position, CatchClauseSyntax catchClause) { Debug.Assert(catchClause != null); return(IsBetweenTokens( position, catchClause.Block.OpenBraceToken, catchClause.Block.CloseBraceToken )); }
private Task <Document> AddMethodCall(Document document, SyntaxNode root, CatchClauseSyntax catchClause, CancellationToken ct) { var variableName = catchClause.Declaration.Identifier.Text; var rewriter = new CatchClauseRewriter(variableName); var newCatchClause = catchClause.Accept(rewriter); var newRoot = root.ReplaceNode(catchClause, newCatchClause); var newDocument = document.WithSyntaxRoot(newRoot); return(Microsoft.CodeAnalysis.Formatting.Formatter.FormatAsync(newDocument, cancellationToken: ct)); }
public override void VisitCatchClause(CatchClauseSyntax node) { if (entryPoint.IsMethodLevel() && node.IsParent <AnonymousFunctionExpressionSyntax>()) { return; } embeddednessNode = node; embeddednessHasBeenIncreased = false; embeddednessHasBeenDecreased = false; base.VisitCatchClause(node); embeddednessNode = null; }
public static bool IsCatchingAllExceptions(this CatchClauseSyntax catchClause) { if (catchClause.Declaration == null) { return(true); } var exceptionTypeName = catchClause.Declaration.Type.GetText().ToString().Trim(); return(catchClause.Filter == null && (exceptionTypeName == "Exception" || exceptionTypeName == "System.Exception")); }
static bool HasFilterIncludingExpression(CatchClauseSyntax catchClause, string expression) { if (catchClause.Filter == null) { return(false); } var tokens = catchClause.Filter.DescendantNodes() .Where(node => node.ToString() == expression); return(tokens.Any()); }
private bool ProcessTry(CatchClauseSyntax catchSyntax) { if (catchSyntax.Block.Statements.Any()) { return(false); } if (DoCorrection) { return(Correct(catchSyntax)); } _result.Add(catchSyntax.Span); return(false); }
public override void VisitCatchClause(CatchClauseSyntax node) { var tokens = new List <SyntaxToken>(); if (node.Declaration != null) { tokens.Add(node.Declaration.Identifier); } tracker.AddIdentifiers(tokens); Visit(node.Block); tracker.AddIdentifiers(tokens); }
public override void VisitCatchClause(CatchClauseSyntax node) { if (null != node.Declaration) { VisitCatchDeclaration(node.Declaration); } if (null != node.Filter) { VisitCatchFilterClause(node.Filter); } //忽略 //VisitBlock(node.Block); }
public override void VisitCatchClause(CatchClauseSyntax node) { Node declaration = null; if (node.Declaration != null) { declaration = VisitSyntaxNode(node.Declaration); } var block = VisitSyntaxNode(node.Block) as Block; _currentNode = new Catch(declaration, block); }
public override SyntaxNode VisitCatchClause(CatchClauseSyntax node) { if (!node.Block.Statements.Any()) { return SyntaxFactory.CatchClause(block: SyntaxFactory.Block(statements: SyntaxFactory.ThrowStatement()), filter: null, declaration: node.Declaration) .WithAdditionalAnnotations(Formatter.Annotation); } return base.VisitCatchClause(node); }
private static bool IsGenericCatch(CatchClauseSyntax catchClause, SemanticModel semanticModel) { if (catchClause.Declaration == null) { return true; } if (catchClause.Filter != null) { return false; } var type = semanticModel.GetTypeInfo(catchClause.Declaration.Type).Type; return type.Is(KnownType.System_Exception); }
public override SyntaxNode VisitCatchClause(CatchClauseSyntax node) { if(!node.DescendantNodes().OfType<ThrowStatementSyntax>().Any()) { BlockSyntax block = node.DescendantNodes().OfType<BlockSyntax>().Single(); if (!block.Statements.Any()) { block = SyntaxFactory.Block(new StatementSyntax[] { SyntaxFactory.ThrowStatement() }); node = node.WithBlock(block); return node; } } return base.VisitCatchClause(node); }
public static async Task<CatchClauseSyntax> WitchExceptionDeclarationAsync( CatchClauseSyntax catchBlock, Document document, string identifierName = "ex") { // Create a new block with a list that contains a throw statement. var throwStatement = SyntaxFactory.ThrowStatement(); var root = await document.GetSyntaxRootAsync().ConfigureAwait(false); var semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false); var exceptionType = semanticModel.Compilation.GetTypeByMetadataName(typeof(Exception).FullName); // TODO: super naive pproach // Getting all using statements and looking for System there var usings = root.DescendantNodesAndSelf().OfType<NamespaceDeclarationSyntax>().SelectMany(nd => nd.Usings) .Union( root.DescendantNodesAndSelf().OfType<CompilationUnitSyntax>().SelectMany(nd => nd.Usings)).ToArray(); bool systemNamespaceAdded = usings.Any(x => x.As(y => y.Name as IdentifierNameSyntax)?.Identifier.ValueText == "System"); TypeSyntax name = SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName(@"System"), SyntaxFactory.IdentifierName(@"Exception")); if (systemNamespaceAdded) { name = SyntaxFactory.IdentifierName(exceptionType.Name); } var newDeclaration = SyntaxFactory .CatchDeclaration(name, SyntaxFactory.Identifier(identifierName)) .WithTrailingTrivia(catchBlock.CatchKeyword.TrailingTrivia); return // Trailing Trivia moved to catch declaration. Removing it from CatchKeyword catchBlock.WithCatchKeyword(catchBlock.CatchKeyword.WithTrailingTrivia(SyntaxTriviaList.Empty)) .WithDeclaration(newDeclaration) .WithAdditionalAnnotations(Formatter.Annotation); }
public void VisitCatchClause(CatchClauseSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); if (_writer.Configuration.LineBreaksAndWrapping.PlaceOnNewLine.PlaceCatchOnNewLine) _writer.WriteIndent(); else _writer.WriteSpace(); _writer.WriteKeyword(PrinterKeyword.Catch); if (node.Declaration != null) { if (_writer.Configuration.Spaces.BeforeParentheses.CatchParentheses) _writer.WriteSpace(); node.Declaration.Accept(this); } node.Block.Accept(this); }
public override void VisitCatchClause(CatchClauseSyntax node) { var saveCurrentScope = currentScope; currentScope = new DeclarationScope(currentScope); var declarationOpt = node.Declaration; if ((declarationOpt != null) && (declarationOpt.Identifier.CSharpKind() != SyntaxKind.None)) { builder.Add(new SemanticModelInfo(currentScope, declarationOpt)); } Visit(node.Filter); Visit(node.Block); Debug.Assert(currentScope.Parent == saveCurrentScope); currentScope = saveCurrentScope; }
private static double ComputeWeightedDistance(CatchClauseSyntax left, CatchClauseSyntax right) { double blockDistance = ComputeDistance(left.Block, right.Block); double distance = CombineOptional(blockDistance, left.Declaration, right.Declaration, left.Filter, right.Filter); return AdjustForLocalsInBlock(distance, left.Block, right.Block, localsWeight: 0.3); }
public CatchClauseTranslation(CatchClauseSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { Block = syntax.Block.Get<BlockTranslation>(this); Declaration = syntax.Declaration.Get<CatchDeclarationTranslation>(this); }
private static bool HasStatements(CatchClauseSyntax catchClause) { return catchClause.Block.Statements.Any(); }
public override void VisitCatchClause(CatchClauseSyntax node) { base.VisitCatchClause(node); _counter++; }
/// <remarks> /// Used to determine whether it would be appropriate to use the binder for the statement (if any). /// Not used to determine whether the position is syntactically within the statement. /// </remarks> internal static bool IsInCatchBlockScope(int position, CatchClauseSyntax catchClause) { Debug.Assert(catchClause != null); return IsBetweenTokens(position, catchClause.Block.OpenBraceToken, catchClause.Block.CloseBraceToken); }
public override void VisitCatchClause(CatchClauseSyntax node) { var clauseBinder = new CatchClauseBinder(this.method, enclosing, node); AddToMap(node, clauseBinder); Visit(node.Block, clauseBinder); if (node.Filter != null) { var filterBinder = clauseBinder.WithAdditionalFlags(BinderFlags.InCatchFilter); AddToMap(node.Filter, filterBinder); Visit(node.Filter, filterBinder); } }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitCatchClause(CatchClauseSyntax node) { this.OnNodeVisited(node, this.type.IsInstanceOfType(node)); base.VisitCatchClause(node); }
private static bool HasComments(CatchClauseSyntax catchClause) { return catchClause.Block.OpenBraceToken.TrailingTrivia.Any(IsCommentTrivia) || catchClause.Block.CloseBraceToken.LeadingTrivia.Any(IsCommentTrivia); }
public override void VisitCatchClause(CatchClauseSyntax node) { var tokens = new List<SyntaxToken>(); if (node.Declaration != null) { tokens.Add(node.Declaration.Identifier); } tracker.AddIdentifiers(tokens); Visit(node.Block); tracker.AddIdentifiers(tokens); }
public void Flatten(CatchClauseSyntax node, FlatOperand fop_exceptionType, string ehEndLabel, List<FlatStatement> instructions) { string catchPrefix = this.MakeUniqueLabelPrefix("catch"); string catchendLabel = catchPrefix + "end"; /* public BlockSyntax Block { get; } public SyntaxToken CatchKeyword { get; } public CatchDeclarationSyntax Declaration { get; } /**/ // JNE catchendLabel this.PushVariableScope(instructions); // declare local variable if (node.Declaration!=null) { TypeInfo ti = Model.GetTypeInfo(node.Declaration.Type); // TYPEOF exception FlatOperand fop_catchType = Resolve(ti.ConvertedType, null, instructions); instructions.Add(FlatStatement.JNE(FlatOperand.LabelRef(catchendLabel), fop_catchType, fop_exceptionType)); FlatOperand fop_register = AllocateRegister(""); CurrentVariableScope.Add(node.Declaration.Identifier.ToString(), fop_register.OperandIndex); // flatten the initializer into instructions { FlatOperand lvalue_register = fop_register.GetLValue(this, instructions); instructions.Add(FlatStatement.REFERENCE(lvalue_register,FlatOperand.ExceptionRef())); } } this.FlattenStatement(node.Block, instructions); this.PopVariableScope(instructions); instructions.Add(FlatStatement.JMP(FlatOperand.LabelRef(ehEndLabel))); instructions.Add(FlatStatement.LABEL(FlatOperand.LabelRef(catchendLabel))); }
private Decisions TraverseCatchClauses(CatchClauseSyntax ccs, ref int exitPoints, bool nested = false) { Decisions retDecision = new Decisions(); CatchStatements retCatch = new CatchStatements(); if (ccs.HasLeadingTrivia) { SetOuterComments(retCatch, ccs.GetLeadingTrivia().ToFullString()); } if (ccs.HasTrailingTrivia) { SetInnerComments(retCatch, ccs.GetTrailingTrivia().ToFullString()); } retCatch.IsNested = nested; var binaryExpressions = from aBinaryExpression in ccs.ChildNodes().OfType<BinaryExpressionSyntax>() select aBinaryExpression; foreach (BinaryExpressionSyntax bes in binaryExpressions) { Method tempMethod = TraverseBinaryExpression(bes); retCatch.AccessedVars.AddRange(tempMethod.AccessedVariables); retCatch.InvokedMethods.AddRange(tempMethod.InvokedMethods); } var catches = from aCatch in ccs.ChildNodes().OfType<CatchClauseSyntax>() select aCatch; foreach (CatchClauseSyntax ccs2 in catches) { Decisions tempCatch = TraverseCatchClauses(ccs2, ref exitPoints, true); retCatch.Nested.AddRange(tempCatch.Catches); } var elses = from aElse in ccs.ChildNodes().OfType<ElseClauseSyntax>() select aElse; foreach (ElseClauseSyntax ecs2 in elses) { Decisions tempElse = TraverseElseClauses(ecs2, ref exitPoints, true); retCatch.Nested.AddRange(tempElse.ElseStatements); } #region nested stuff var statements = from aStatement in ccs.ChildNodes().OfType<StatementSyntax>() select aStatement; foreach (StatementSyntax ss in statements) { if (ss is DoStatementSyntax) { Decisions dwl = TraverseDoStatements(ss as DoStatementSyntax, ref exitPoints, true); retCatch.Nested.AddRange(dwl.DoWhileLoops); } else if (ss is ExpressionStatementSyntax) { Method tempMethod = TraverseExpressionStatementSyntax(ss as ExpressionStatementSyntax); retCatch.AccessedVars.AddRange(tempMethod.AccessedVariables); retCatch.InvokedMethods.AddRange(tempMethod.InvokedMethods); } else if (ss is ForEachStatementSyntax) { Decisions fes = TraverseForEachStatements(ss as ForEachStatementSyntax, ref exitPoints, true); retCatch.Nested.AddRange(fes.ForEachStatements); } else if (ss is ForStatementSyntax) { Decisions fs = TraverseForStatements(ss as ForStatementSyntax, ref exitPoints, true); retCatch.Nested.AddRange(fs.ForStatements); } else if (ss is IfStatementSyntax) { Decisions decision = TraverseIfStatements(ss as IfStatementSyntax, ref exitPoints, true); retCatch.Nested.AddRange(decision.IfStatements); } else if (ss is LocalDeclarationStatementSyntax) { Model.Type tempType = new Model.Type(); LocalDeclarationStatementSyntax ldss = ss as LocalDeclarationStatementSyntax; if (ldss.Declaration != null) { VariableDeclarationSyntax vds = ldss.Declaration; tempType.Name = vds.Type.ToString(); tempType.IsKnownType = true; tempType.IsNotUserDefined = true; } Method tempMethod = TransverseAccessVars(ss as LocalDeclarationStatementSyntax); //NOT SURE if this will work but here goes tempMethod.AccessedVariables[0].Type = tempType; retCatch.AccessedVars.AddRange(tempMethod.AccessedVariables); retCatch.InvokedMethods.AddRange(tempMethod.InvokedMethods); } else if (ss is ReturnStatementSyntax) { exitPoints++; } else if (ss is SwitchStatementSyntax) { Decisions switchStm = TraverseSwitchStatements(ss as SwitchStatementSyntax, ref exitPoints, true); retCatch.Nested.AddRange(switchStm.SwitchStatements); } else if (ss is WhileStatementSyntax) { Decisions wl = TraverseWhileLoops(ss as WhileStatementSyntax, ref exitPoints, true); retCatch.Nested.AddRange(wl.WhileLoops); } } #endregion retDecision.Catches.Add(retCatch); return retDecision; }
public override void VisitCatchClause(CatchClauseSyntax node) { Debug.Assert((object)_method == _enclosing.ContainingMemberOrLambda); var clauseBinder = new CatchClauseBinder(_enclosing, node); AddToMap(node, clauseBinder); Visit(node.Block, clauseBinder); if (node.Filter != null) { var filterBinder = clauseBinder.WithAdditionalFlags(BinderFlags.InCatchFilter); AddToMap(node.Filter, filterBinder); Visit(node.Filter, filterBinder); } }
private BoundCatchBlock BindCatchBlock(CatchClauseSyntax node, ArrayBuilder<BoundCatchBlock> previousBlocks, DiagnosticBag diagnostics) { bool hasError = false; TypeSymbol type = null; BoundExpression boundFilter = null; var declaration = node.Declaration; if (declaration != null) { // Note: The type is being bound twice: here and in LocalSymbol.Type. Currently, // LocalSymbol.Type ignores diagnostics so it seems cleaner to bind the type here // as well. However, if LocalSymbol.Type is changed to report diagnostics, we'll // need to avoid binding here since that will result in duplicate diagnostics. type = this.BindType(declaration.Type, diagnostics); Debug.Assert((object)type != null); if (type.IsErrorType()) { hasError = true; } else { HashSet<DiagnosticInfo> useSiteDiagnostics = null; TypeSymbol effectiveType = type.EffectiveType(ref useSiteDiagnostics); if (!Compilation.IsExceptionType(effectiveType, ref useSiteDiagnostics)) { // "The type caught or thrown must be derived from System.Exception" Error(diagnostics, ErrorCode.ERR_BadExceptionType, declaration.Type); hasError = true; diagnostics.Add(declaration.Type, useSiteDiagnostics); } } } var filter = node.Filter; if (filter != null) { var filterBinder = this.GetBinder(filter); boundFilter = filterBinder.BindCatchFilter(filter, diagnostics); hasError |= boundFilter.HasAnyErrors; } if (!hasError) { // TODO: Loop is O(n), caller is O(n^2). Perhaps we could iterate in reverse order (since it's easier to find // base types than to find derived types). Debug.Assert(((object)type == null) || !type.IsErrorType()); foreach (var previousBlock in previousBlocks) { var previousType = previousBlock.ExceptionTypeOpt; // If the previous type is a generic parameter we don't know what exception types it's gonna catch exactly. // If it is a class-type we know it's gonna catch all exception types of its type and types that are derived from it. // So if the current type is a class-type (or an effective base type of a generic parameter) // that derives from the previous type the current catch is unreachable. if (previousBlock.ExceptionFilterOpt == null && (object)previousType != null && !previousType.IsErrorType()) { if ((object)type != null) { HashSet<DiagnosticInfo> useSiteDiagnostics = null; if (Conversions.HasIdentityOrImplicitReferenceConversion(type, previousType, ref useSiteDiagnostics)) { // "A previous catch clause already catches all exceptions of this or of a super type ('{0}')" Error(diagnostics, ErrorCode.ERR_UnreachableCatch, declaration.Type, previousType); diagnostics.Add(declaration.Type, useSiteDiagnostics); hasError = true; break; } diagnostics.Add(declaration.Type, useSiteDiagnostics); } else if (previousType == Compilation.GetWellKnownType(WellKnownType.System_Exception) && Compilation.SourceAssembly.RuntimeCompatibilityWrapNonExceptionThrows) { // If the RuntimeCompatibility(WrapNonExceptionThrows = false) is applied on the source assembly or any referenced netmodule. // an empty catch may catch exceptions that don't derive from System.Exception. // "A previous catch clause already catches all exceptions..." Error(diagnostics, ErrorCode.WRN_UnreachableGeneralCatch, node.CatchKeyword); break; } } } } BoundExpression exceptionSource = null; LocalSymbol local = this.Locals.FirstOrDefault(); if ((object)local != null) { Debug.Assert(this.Locals.Length == 1); // Check for local variable conflicts in the *enclosing* binder, not the *current* binder; // obviously we will find a local of the given name in the current binder. hasError |= this.ValidateDeclarationNameConflictsInScope(local, diagnostics); exceptionSource = new BoundLocal(declaration, local, ConstantValue.NotAvailable, local.Type); } var block = this.BindBlock(node.Block, diagnostics); Debug.Assert((object)local == null || local.DeclarationKind == LocalDeclarationKind.CatchVariable); Debug.Assert((object)local == null || local.Type.IsErrorType() || (local.Type == type)); return new BoundCatchBlock(node, local, exceptionSource, type, boundFilter, block, hasError); }
public CatchClauseBinder(Binder enclosing, CatchClauseSyntax syntax) : base(enclosing, enclosing.Flags | BinderFlags.InCatchBlock) { Debug.Assert(syntax != null); this.syntax = syntax; }
public CatchClauseBinder(Binder enclosing, CatchClauseSyntax syntax) : base(enclosing, (enclosing.Flags | BinderFlags.InCatchBlock) & ~BinderFlags.InNestedFinallyBlock) { Debug.Assert(syntax != null); _syntax = syntax; }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitCatchClause(CatchClauseSyntax node) { this.OnNodeVisited(node); if (!this.traverseRootOnly) base.VisitCatchClause(node); }