
org.codenarc.rule.formatting.BracesForTryCatchFinallyRule.groovy Maven / Gradle / Ivy
/*
* Copyright 2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codenarc.rule.formatting
import org.codehaus.groovy.ast.stmt.CatchStatement
import org.codehaus.groovy.ast.stmt.TryCatchStatement
import org.codenarc.rule.AbstractAstVisitor
import org.codenarc.rule.AbstractAstVisitorRule
/**
* Checks the location of the opening brace ({) for try statements, the location
* of the 'catch' keyword and corresponding opening braces, and the location of the 'finally'
* keyword and the corresponding opening braces. By default, requires opening braces on the
* same line, but the sameLine property can be set to false to override this.
*
* By default does not validate catch and finally clauses, to turn this on set properties
* validateCatch and validateFinally to true respectively. The catch and finally handling
* defaults to using the sameLine value so if sameLine is true, we expect "} catch(x) {"
* and "} finally {". For fine grained control, use boolean properties catchOnSameLineAsClosingBrace,
* catchOnSameLineAsOpeningBrace, finallyOnSameLineAsClosingBrace, finallyOnSameLineAsOpeningBrace
*
* @author Geli Crick
* @author Hamlet D'Arcy
* @author Matias Bjarland
* @author Chris Mair
*/
class BracesForTryCatchFinallyRule extends AbstractAstVisitorRule {
String name = 'BracesForTryCatchFinally'
int priority = 2
Class astVisitorClass = BracesForTryCatchFinallyAstVisitor
boolean sameLine = true
boolean validateCatch = false
Boolean catchOnSameLineAsClosingBrace
Boolean catchOnSameLineAsOpeningBrace
boolean validateFinally = false
Boolean finallyOnSameLineAsClosingBrace
Boolean finallyOnSameLineAsOpeningBrace
}
class BracesForTryCatchFinallyAstVisitor extends AbstractAstVisitor {
@Override
void visitTryCatchFinally(TryCatchStatement node) {
BracesForTryCatchFinallyRule myRule = rule as BracesForTryCatchFinallyRule
boolean isBraceOnSameLine = node.lineNumber == node.tryStatement.lineNumber
if (myRule.sameLine) {
if (!isBraceOnSameLine) {
addViolation(node, "Opening brace should be on the same line as 'try'")
}
} else {
if (isBraceOnSameLine) {
addViolation(node, "Opening brace should not be on the same line as 'try'")
}
}
visitCatch(myRule, node)
visitFinally(myRule, node)
super.visitTryCatchFinally(node)
}
void visitCatch(BracesForTryCatchFinallyRule myRule, TryCatchStatement node) {
//TODO: Understand AstUtil.isBlock and isFirstVisit and apply them as appropriate to the below block
if (myRule.validateCatch && node.catchStatements) {
//if user has not explicitly set the catch brace settings, 'inherit' them from sameLine
if (myRule.catchOnSameLineAsClosingBrace == null) {
myRule.catchOnSameLineAsClosingBrace = myRule.sameLine
}
if (myRule.catchOnSameLineAsOpeningBrace == null) {
myRule.catchOnSameLineAsOpeningBrace = myRule.sameLine
}
node.catchStatements.each { CatchStatement stmt ->
def srcLine = sourceLineTrimmed(stmt)
if (myRule.catchOnSameLineAsClosingBrace && !srcLine?.contains('}')) {
addViolation(stmt, "'catch' should be on the same line as the closing brace")
} else if (!myRule.catchOnSameLineAsClosingBrace && srcLine?.contains('}')) {
addViolation(stmt, "'catch' should not be on the same line as the closing brace")
}
boolean isBraceOnSameLine = stmt.lineNumber == stmt.code.lineNumber
if (myRule.catchOnSameLineAsOpeningBrace && !isBraceOnSameLine) {
addViolation(stmt, "Opening brace should be on the same line as 'catch'")
} else if (!myRule.catchOnSameLineAsOpeningBrace && isBraceOnSameLine) {
addViolation(stmt, "Opening brace should not be on the same line as 'catch'")
}
}
}
}
void visitFinally(BracesForTryCatchFinallyRule myRule, TryCatchStatement node) {
//TODO: Understand AstUtil.isBlock and isFirstVisit and apply them as appropriate to the below block
//if user has not explicitly set the finally brace settings, 'inherit' them from sameLine
if (myRule.finallyOnSameLineAsClosingBrace == null) {
myRule.finallyOnSameLineAsClosingBrace = myRule.sameLine
}
if (myRule.finallyOnSameLineAsOpeningBrace == null) {
myRule.finallyOnSameLineAsOpeningBrace = myRule.sameLine
}
if (myRule.validateFinally && node.finallyStatement) {
def stmt = node.finallyStatement
def srcLine = sourceLineTrimmed(stmt)
if (myRule.finallyOnSameLineAsClosingBrace && srcLine && !srcLine?.contains('}')) {
addViolation(stmt, "'finally' should be on the same line as the closing brace")
} else if (!myRule.finallyOnSameLineAsClosingBrace && srcLine?.contains('}')) {
addViolation(stmt, "'finally' should not be on the same line as the closing brace")
}
if (myRule.finallyOnSameLineAsOpeningBrace && srcLine && !srcLine?.contains('{')) {
addViolation(stmt, "Opening brace should be on the same line as 'finally'")
} else if (!myRule.catchOnSameLineAsOpeningBrace && srcLine?.contains('}')) {
addViolation(stmt, "Opening brace should not be on the same line as 'finally'")
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy