src/checkstyle/checks/whitespace/ExtendedEmptyLinesCheck.hx
package checkstyle.checks.whitespace;
import checkstyle.checks.whitespace.ListOfEmptyLines.EmptyLineRange;
/**
Checks for consecutive empty lines.
**/ @name("ExtendedEmptyLines")
@desc("Checks for consecutive empty lines.")
class ExtendedEmptyLinesCheck extends Check {
/**
number of empty lines to allow / enforce (used by "exact", "upto" and "atleast" policies)
**/
public var max:Int;
/**
skips single line type definitions
**/
public var skipSingleLineTypes:Bool;
/**
"defaultPolicy" applies to all places not in "ignore", "none", "exact", "upto" or "atleast"
**/
public var defaultPolicy:EmptyLinesPolicy;
/**
list of places to ignore
**/
public var ignore:Array<EmptyLinesPlace>;
/**
list of places where no empty line is permitted
**/
public var none:Array<EmptyLinesPlace>;
/**
list of places where exactly "max" empty lines are required
**/
public var exact:Array<EmptyLinesPlace>;
/**
list of places where up to "max" empty lines are permitted
**/
public var upto:Array<EmptyLinesPlace>;
/**
list of places where at least "max" empty lines are required
**/
public var atleast:Array<EmptyLinesPlace>;
var placemap:Map<EmptyLinesPlace, EmptyLinesPolicy>;
public function new() {
super(TOKEN);
max = 1;
skipSingleLineTypes = true;
defaultPolicy = UPTO;
ignore = [];
none = [];
exact = [];
upto = [];
atleast = [];
categories = [Category.STYLE, Category.CLARITY];
}
function buildPolicyMap() {
placemap = new Map<EmptyLinesPlace, EmptyLinesPolicy>();
for (place in ignore) placemap.set(place, IGNORE);
for (place in none) placemap.set(place, NONE);
for (place in exact) placemap.set(place, EXACT);
for (place in upto) placemap.set(place, UPTO);
for (place in atleast) placemap.set(place, ATLEAST);
}
function getPolicy(place:EmptyLinesPlace):EmptyLinesPolicy {
if (placemap.exists(place)) return placemap.get(place);
return defaultPolicy;
}
function isIgnored(places:Array<EmptyLinesPlace>):Bool {
for (place in places) {
if (getPolicy(place) != IGNORE) return false;
}
return true;
}
override function actualRun() {
buildPolicyMap();
var emptyLines:ListOfEmptyLines = ListOfEmptyLines.detectEmptyLines(checker);
if (max <= 0) max = 1;
checkPackages(emptyLines);
checkImports(emptyLines);
checkTypes(emptyLines);
checkFile(emptyLines);
checkFunctions(emptyLines);
checkComments(emptyLines);
}
function checkPackages(emptyLines:ListOfEmptyLines) {
if (isIgnored([BEFORE_PACKAGE, AFTER_PACKAGE])) return;
var root:TokenTree = checker.getTokenTree();
var packages:Array<TokenTree> = root.filterCallback(function(token:TokenTree, depth:Int):FilterResult {
return switch (token.tok) {
case Kwd(KwdPackage):
FoundSkipSubtree;
case Kwd(_):
SkipSubtree;
default:
GoDeeper;
}
});
for (pack in packages) {
checkBetweenToken(emptyLines, null, pack, getPolicy(BEFORE_PACKAGE), "before package");
checkBetweenToken(emptyLines, pack, pack.nextSibling, getPolicy(AFTER_PACKAGE), "after package");
}
}
function checkImports(emptyLines:ListOfEmptyLines) {
if (isIgnored([AFTER_IMPORTS, BEFORE_USING, BETWEEN_IMPORTS])) return;
var root:TokenTree = checker.getTokenTree();
var imports:Array<TokenTree> = root.filterCallback(function(token:TokenTree, depth:Int):FilterResult {
return switch (token.tok) {
case Kwd(KwdImport) | Kwd(KwdUsing):
FoundSkipSubtree;
default:
GoDeeper;
}
});
if (imports.length <= 0) return;
var lastImport:TokenTree = imports[imports.length - 1];
if (lastImport.nextSibling != null) {
switch (lastImport.nextSibling.tok) {
case Kwd(KwdAbstract), Kwd(KwdClass), Kwd(KwdEnum), Kwd(KwdInterface), Kwd(KwdTypedef):
checkBetweenToken(emptyLines, lastImport, lastImport.nextSibling, getPolicy(AFTER_IMPORTS), "after imports/using");
default:
}
}
for (index in 1...imports.length) {
var imp:TokenTree = imports[index];
var prev:TokenTree = imp.previousSibling;
if (prev == null) continue;
if (imp.matches(Kwd(KwdUsing))) {
if (prev.matches(Kwd(KwdImport))) {
checkBetweenToken(emptyLines, prev, imp, getPolicy(BEFORE_USING), "between import and using");
continue;
}
}
else {
if (prev.matches(Kwd(KwdUsing))) {
checkBetweenToken(emptyLines, prev, imp, getPolicy(BEFORE_USING), "between import and using");
continue;
}
}
switch (prev.tok) {
case Kwd(KwdImport), Kwd(KwdUsing), Comment(_), CommentLine(_):
checkBetweenToken(emptyLines, prev, imp, getPolicy(BETWEEN_IMPORTS), "between imports/using");
default:
}
}
}
function checkTypes(emptyLines:ListOfEmptyLines) {
var root:TokenTree = checker.getTokenTree();
var types:Array<TokenTree> = root.filterCallback(function(token:TokenTree, depth:Int):FilterResult {
return switch (token.tok) {
case Kwd(KwdAbstract) | Kwd(KwdClass) | Kwd(KwdEnum) | Kwd(KwdInterface) | Kwd(KwdTypedef):
FoundSkipSubtree;
default:
GoDeeper;
}
});
if (types.length <= 0) return;
checkBetweenTypes(emptyLines, types);
for (type in types) {
var pos:Position = type.getPos();
if (skipSingleLineTypes && (checker.getLinePos(pos.min).line - checker.getLinePos(pos.max).line == 0)) continue;
switch (type.tok) {
case Kwd(KwdAbstract):
checkAbstract(emptyLines, type);
case Kwd(KwdClass):
checkClass(emptyLines, type);
case Kwd(KwdEnum):
if (isIgnored([BEGIN_ENUM, END_ENUM, BETWEEN_ENUM_FIELDS, TYPE_DEFINITION])) continue;
checkType(emptyLines, type, getPolicy(BEGIN_ENUM), getPolicy(END_ENUM), function(child:TokenTree, next:TokenTree):PolicyAndWhat {
if (hasDocComment(child)) {
return makePolicyAndWhat(getPolicy(AFTER_DOC_COMMENT_FIELD), "between type fields");
}
return makePolicyAndWhat(getPolicy(BETWEEN_ENUM_FIELDS), "between type fields");
});
case Kwd(KwdInterface):
if (isIgnored([BEGIN_INTERFACE, END_INTERFACE, BETWEEN_INTERFACE_FIELDS, TYPE_DEFINITION])) continue;
checkType(emptyLines, type, getPolicy(BEGIN_INTERFACE), getPolicy(END_INTERFACE), function(child:TokenTree, next:TokenTree):PolicyAndWhat {
if (hasDocComment(child)) {
return makePolicyAndWhat(getPolicy(AFTER_DOC_COMMENT_FIELD), "between type fields");
}
return makePolicyAndWhat(getPolicy(BETWEEN_INTERFACE_FIELDS), "between type fields");
});
case Kwd(KwdTypedef):
if (isIgnored([BEGIN_TYPEDEF, END_TYPEDEF, BETWEEN_TYPEDEF_FIELDS, TYPE_DEFINITION])) continue;
checkType(emptyLines, type, getPolicy(BEGIN_TYPEDEF), getPolicy(END_TYPEDEF), function(child:TokenTree, next:TokenTree):PolicyAndWhat {
if (hasDocComment(child)) {
return makePolicyAndWhat(getPolicy(AFTER_DOC_COMMENT_FIELD), "between type fields");
}
return makePolicyAndWhat(getPolicy(BETWEEN_TYPEDEF_FIELDS), "between type fields");
});
default:
}
}
}
function hasDocComment(token:TokenTree):Bool {
var docToken:TokenTree = TokenTreeCheckUtils.getDocComment(token);
return (docToken != null);
}
function checkBetweenTypes(emptyLines:ListOfEmptyLines, types:Array<TokenTree>) {
if (isIgnored([BETWEEN_TYPES])) return;
for (index in 1...types.length) {
var type:TokenTree = types[index];
var sibling:TokenTree = type.previousSibling;
var prevType:TokenTree = types[index - 1];
if (sibling == null) {
continue;
}
if (sibling != prevType) {
switch (sibling.tok) {
case Comment(_):
type = sibling;
case CommentLine(_):
type = sibling;
case Sharp(_):
continue;
default:
}
}
var prevPos:Position = prevType.getPos();
if (skipSingleLineTypes && (checker.getLinePos(prevPos.min).line - checker.getLinePos(prevPos.max).line == 0)) continue;
var startLine:Int = checker.getLinePos(prevPos.max).line;
var endLine:Int = checker.getLinePos(type.getPos().min).line;
checkBetween(emptyLines, startLine, endLine, getPolicy(BETWEEN_TYPES), "between types");
}
}
function checkAbstract(emptyLines:ListOfEmptyLines, typeToken:TokenTree) {
if (isIgnored([
BEGIN_ABSTRACT,
END_ABSTRACT,
BETWEEN_ABSTRACT_METHODS,
AFTER_ABSTRACT_VARS,
BETWEEN_ABSTRACT_VARS,
TYPE_DEFINITION
])) {
return;
}
checkType(emptyLines, typeToken, getPolicy(BEGIN_ABSTRACT), getPolicy(END_ABSTRACT), function(child:TokenTree, next:TokenTree):PolicyAndWhat {
if (hasDocComment(child)) {
return makePolicyAndWhat(getPolicy(AFTER_DOC_COMMENT_FIELD), "between type fields");
}
var isFuncChild:Bool = child.matches(Kwd(KwdFunction));
var isVarChild:Bool = child.matches(Kwd(KwdVar));
if (!isVarChild && !isFuncChild) return null;
var type:EmptyLinesFieldType = detectNextFieldType(next);
if (type == OTHER) return null;
if (isFuncChild && (type == FUNCTION)) return makePolicyAndWhat(getPolicy(BETWEEN_ABSTRACT_METHODS), "between abstract functions");
if (isVarChild && (type == FUNCTION)) return makePolicyAndWhat(getPolicy(AFTER_ABSTRACT_VARS), "after abstract vars");
if (isFuncChild && (type == VAR)) return makePolicyAndWhat(getPolicy(AFTER_ABSTRACT_VARS), "after abstract vars");
return makePolicyAndWhat(getPolicy(BETWEEN_ABSTRACT_VARS), "between abstract vars");
});
}
function checkClass(emptyLines:ListOfEmptyLines, typeToken:TokenTree) {
var places:Array<EmptyLinesPlace> = [
BEGIN_CLASS,
END_CLASS,
BETWEEN_CLASS_METHODS,
AFTER_CLASS_VARS,
BETWEEN_CLASS_STATIC_VARS,
BETWEEN_CLASS_VARS,
AFTER_CLASS_STATIC_VARS,
TYPE_DEFINITION
];
if (isIgnored(places)) return;
checkType(emptyLines, typeToken, getPolicy(BEGIN_CLASS), getPolicy(END_CLASS), function(child:TokenTree, next:TokenTree):PolicyAndWhat {
if (hasDocComment(child)) {
return makePolicyAndWhat(getPolicy(AFTER_DOC_COMMENT_FIELD), "between type fields");
}
while (next != null) {
if (!next.isComment()) break;
next = next.nextSibling;
}
if (next == null) return null;
var isFuncChild:Bool = child.matches(Kwd(KwdFunction));
var isVarChild:Bool = child.matches(Kwd(KwdVar));
if (!isVarChild && !isFuncChild) return null;
var type:EmptyLinesFieldType = detectNextFieldType(next);
if (type == OTHER) return null;
if (isFuncChild && (type == FUNCTION)) return makePolicyAndWhat(getPolicy(BETWEEN_CLASS_METHODS), "between class methods");
if (isVarChild && (type == FUNCTION)) return makePolicyAndWhat(getPolicy(AFTER_CLASS_VARS), "after class vars");
if (isFuncChild && (type == VAR)) return makePolicyAndWhat(getPolicy(AFTER_CLASS_VARS), "after class vars");
var isStaticChild:Bool = (child.filterCallback(function(token:TokenTree, depth:Int):FilterResult {
return switch (token.tok) {
case Kwd(KwdStatic):
FoundSkipSubtree;
default:
GoDeeper;
}
}).length > 0);
var isStaticNext:Bool = (next.filterCallback(function(token:TokenTree, depth:Int):FilterResult {
return switch (token.tok) {
case Kwd(KwdStatic):
FoundSkipSubtree;
default:
GoDeeper;
}
}).length > 0);
if (isStaticChild && isStaticNext) return makePolicyAndWhat(getPolicy(BETWEEN_CLASS_STATIC_VARS), "between class static vars");
if (!isStaticChild && !isStaticNext) return makePolicyAndWhat(getPolicy(BETWEEN_CLASS_VARS), "between class vars");
return makePolicyAndWhat(getPolicy(AFTER_CLASS_STATIC_VARS), "after class static vars");
});
}
function detectNextFieldType(field:TokenTree):EmptyLinesFieldType {
if (field.matches(Kwd(KwdFunction))) return FUNCTION;
if (field.matches(Kwd(KwdVar))) return VAR;
if (!field.isComment()) return OTHER;
var after:TokenTree = field.nextSibling;
while (after != null) {
if (after.matches(Kwd(KwdFunction))) return FUNCTION;
if (after.matches(Kwd(KwdVar))) return VAR;
if (after.isComment()) {
after = after.nextSibling;
continue;
}
return OTHER;
}
return OTHER;
}
function checkType(emptyLines:ListOfEmptyLines, typeToken:TokenTree, beginPolicy:EmptyLinesPolicy, endPolicy:EmptyLinesPolicy,
fieldPolicyProvider:FieldPolicyProvider) {
var brOpen = findTypeBrOpen(typeToken);
if (brOpen == null) return;
checkBetweenToken(emptyLines, typeToken, brOpen, getPolicy(TYPE_DEFINITION), "between type definition and left curly");
var brClose:Null<TokenTree> = brOpen.getLastChild();
if (brClose == null) return;
var start:Int = checker.getLinePos(brOpen.pos.max).line;
var end:Int = checker.getLinePos(brClose.pos.min).line;
if (start == end) return;
checkLines(emptyLines, beginPolicy, start + 1, start + 1, "after left curly");
checkLines(emptyLines, endPolicy, end - 1, end - 1, "before right curly");
for (child in brOpen.children) {
switch (child.tok) {
case Comment(_):
case CommentLine(_):
case At:
default:
var next:TokenTree = child.nextSibling;
if (next == null) continue;
switch (next.tok) {
case BrClose:
continue;
case CommentLine(_):
continue;
case Comment(_):
continue;
default:
}
var policyAndWhat:PolicyAndWhat = fieldPolicyProvider(child, next);
if (policyAndWhat == null) continue;
checkBetweenFullToken(emptyLines, child, next, policyAndWhat.policy, policyAndWhat.whatMsg);
}
}
}
function findTypeBrOpen(parent:TokenTree):TokenTree {
if (parent == null) return null;
var brOpens:Array<TokenTree> = parent.filterCallback(function(tok:TokenTree, depth:Int):FilterResult {
return switch (tok.tok) {
case BrOpen: FoundSkipSubtree;
default: GoDeeper;
}
});
if (brOpens.length <= 0) return null;
return brOpens[0];
}
function checkFile(emptyLines:ListOfEmptyLines) {
if (isIgnored([ANYWHERE_IN_FILE, BEFORE_FILE_END])) return;
var ranges:Array<EmptyLineRange> = emptyLines.getRanges(0, checker.lines.length);
for (range in ranges) {
var line:Int = 0;
switch (range) {
case NONE:
case SINGLE(l):
line = l;
case RANGE(start, end):
line = end;
}
var result:EmptyLineRange = emptyLines.checkRange(getPolicy(ANYWHERE_IN_FILE), max, range, line);
logEmptyRange(getPolicy(ANYWHERE_IN_FILE), "anywhere in file", result);
}
var range:EmptyLineRange = NONE;
if (ranges.length > 0) {
var lastRange:EmptyLineRange = ranges[ranges.length - 1];
switch (lastRange) {
case NONE:
case SINGLE(line):
if (line == checker.lines.length - 1) range = lastRange;
case RANGE(start, end):
if (end == checker.lines.length - 1) range = lastRange;
}
}
var result:EmptyLineRange = emptyLines.checkRange(getPolicy(BEFORE_FILE_END), max, range, checker.lines.length - 1);
logEmptyRange(getPolicy(BEFORE_FILE_END), "before file end", result);
}
function checkFunctions(emptyLines:ListOfEmptyLines) {
if (isIgnored([IN_FUNCTION, AFTER_LEFT_CURLY, BEFORE_RIGHT_CURLY])) return;
var root:TokenTree = checker.getTokenTree();
var funcs:Array<TokenTree> = root.filterCallback(function(token:TokenTree, depth:Int):FilterResult {
return switch (token.tok) {
case Kwd(KwdFunction):
FoundGoDeeper;
default:
GoDeeper;
}
});
if (funcs.length <= 0) return;
for (func in funcs) {
var pos:Position = func.getPos();
var start:Int = checker.getLinePos(pos.min).line;
var end:Int = checker.getLinePos(pos.max).line;
checkLines(emptyLines, getPolicy(IN_FUNCTION), start, end, "inside functions", true);
var brOpen:Array<TokenTree> = func.filterCallback(function(token:TokenTree, depth:Int):FilterResult {
return switch (token.tok) {
case BrOpen:
FoundGoDeeper;
default:
GoDeeper;
}
});
for (open in brOpen) {
var close:TokenTree = open.getLastChild();
if (close == null) continue;
var start:Int = checker.getLinePos(open.pos.max).line;
var end:Int = checker.getLinePos(close.pos.min).line;
if (start == end) continue;
checkLines(emptyLines, getPolicy(AFTER_LEFT_CURLY), start + 1, start + 1, "after left curly");
checkLines(emptyLines, getPolicy(BEFORE_RIGHT_CURLY), end - 1, end - 1, "before right curly");
}
}
}
function checkComments(emptyLines:ListOfEmptyLines) {
if (isIgnored([
AFTER_MULTILINE_COMMENT,
AFTER_SINGLELINE_COMMENT,
BEFORE_MULTILINE_COMMENT,
BEFORE_SINGLELINE_COMMENT
])) {
return;
}
var root:TokenTree = checker.getTokenTree();
var comments:Array<TokenTree> = root.filterCallback(function(tok:TokenTree, depth:Int):FilterResult {
return switch (tok.tok) {
case Comment(_): FoundSkipSubtree;
case CommentLine(_): FoundSkipSubtree;
default: GoDeeper;
}
});
for (comment in comments) {
var line:Int = checker.getLinePos(comment.pos.min).line;
if (!~/^\s*(\/\/|\/\*)/.match(checker.lines[line])) continue;
var prevLine:Int = checker.getLinePos(comment.getPos().min).line - 1;
var nextLine:Int = checker.getLinePos(comment.getPos().max).line + 1;
switch (comment.tok) {
case Comment(_):
if (checkPreviousSiblingComment(comment.previousSibling)) {
checkLines(emptyLines, getPolicy(BEFORE_MULTILINE_COMMENT), prevLine, prevLine, "before comment");
}
if ((comment.nextSibling == null) || (!comment.nextSibling.isComment())) {
checkLines(emptyLines, getPolicy(AFTER_MULTILINE_COMMENT), nextLine, nextLine, "after comment");
}
case CommentLine(_):
if (checkPreviousSiblingComment(comment.previousSibling)) {
checkLines(emptyLines, getPolicy(BEFORE_SINGLELINE_COMMENT), prevLine, prevLine, "before comment");
}
if ((comment.nextSibling == null) || (!comment.nextSibling.isComment())) {
checkLines(emptyLines, getPolicy(AFTER_SINGLELINE_COMMENT), nextLine, nextLine, "after comment");
}
default:
}
}
}
function checkPreviousSiblingComment(token:TokenTree):Bool {
if ((token == null) || (token.tok == Root)) {
return false;
}
switch (token.tok) {
case Comment(_), CommentLine(_):
return false;
case Sharp(_):
return false;
case POpen, Const(CIdent(_)):
var parent:Null<TokenTree> = token.parent;
if (parent != null) {
switch (parent.tok) {
case Sharp(_):
return false;
default:
}
}
default:
}
return true;
}
function checkLines(emptyLines:ListOfEmptyLines, policy:EmptyLinesPolicy, start:Int, end:Int, whatMsg:String, tolerateEmptyRange:Bool = false) {
var ranges:Array<EmptyLineRange> = emptyLines.getRanges(start, end);
if (!tolerateEmptyRange && (ranges.length <= 0)) ranges = [NONE];
for (range in ranges) {
var result:EmptyLineRange = emptyLines.checkRange(policy, max, range, end);
logEmptyRange(policy, whatMsg, result);
}
}
function checkBetweenFullToken(emptyLines:ListOfEmptyLines, firstToken:TokenTree, secondToken:TokenTree, policy:EmptyLinesPolicy, whatMsg:String) {
var lineStart:Int = 0;
var lineEnd:Int = checker.lines.length;
if (firstToken != null) {
lineStart = checker.getLinePos(firstToken.getPos().max).line;
}
if (secondToken != null) {
lineEnd = checker.getLinePos(secondToken.getPos().min).line;
}
checkBetween(emptyLines, lineStart, lineEnd, policy, whatMsg);
}
function checkBetweenToken(emptyLines:ListOfEmptyLines, firstToken:TokenTree, secondToken:TokenTree, policy:EmptyLinesPolicy, whatMsg:String) {
var lineStart:Int = 0;
var lineEnd:Int = checker.lines.length;
if (firstToken != null) {
lineStart = checker.getLinePos(firstToken.pos.max).line;
}
if (secondToken != null) {
lineEnd = checker.getLinePos(secondToken.pos.min).line;
}
checkBetween(emptyLines, lineStart, lineEnd, policy, whatMsg);
}
function checkBetween(emptyLines:ListOfEmptyLines, lineStart:Int, lineEnd:Int, policy:EmptyLinesPolicy, whatMsg:String) {
if (lineStart < 0) lineStart = 0;
if (lineEnd < 0) lineEnd = checker.lines.length;
var result:EmptyLineRange = emptyLines.checkPolicySingleRange(policy, max, lineStart, lineEnd);
logEmptyRange(policy, whatMsg, result);
}
function makePolicyAndWhat(policy:EmptyLinesPolicy, whatMsg:String):PolicyAndWhat {
return {
policy: policy,
whatMsg: whatMsg
};
}
function logEmptyRange(policy:EmptyLinesPolicy, whatMsg:String, range:EmptyLineRange) {
if (range == null) return;
switch (range) {
case NONE:
case SINGLE(line):
if (isLineSuppressed(line)) return;
log(formatMessage(policy, whatMsg), line + 1, 0, line + 1, 0);
case RANGE(start, end):
if (isLineSuppressed(start)) return;
log(formatMessage(policy, whatMsg), start + 1, 0, end + 1, 0);
}
}
function formatMessage(policy:EmptyLinesPolicy, what:String):String {
var line:String = "lines";
if (max == 1) line = "line";
return switch (policy) {
case IGNORE: "ignored empty lines " + what;
case NONE: "should not have empty line(s) " + what;
case EXACT: 'should have exactly $max empty $line $what';
case UPTO: 'should have upto $max empty $line $what';
case ATLEAST: 'should have at least $max empty $line $what';
}
}
override public function detectableInstances():DetectableInstances {
return [{
fixed: [{
propertyName: "max",
value: 1
}],
properties: [{
"propertyName": "skipSingleLineTypes",
"values": [false, true]
}, {
"propertyName": "defaultPolicy",
"values": ["none", "exact", "upto", "atleast", "ignore"]
}, {
"propertyName": "none",
"values": [[
BEFORE_PACKAGE,
BETWEEN_IMPORTS,
BEFORE_USING,
TYPE_DEFINITION,
AFTER_LEFT_CURLY,
BEFORE_RIGHT_CURLY
]]
}]
}];
}
}
typedef FieldPolicyProvider = TokenTree -> TokenTree -> PolicyAndWhat;
typedef PolicyAndWhat = {
var policy:EmptyLinesPolicy;
var whatMsg:String;
}
/**
policy for empty lines
- ignore = ignores all entries
- none = no empty line permitted
- exact = exactly "max" empty line(s) required
- upto = up to "max" empty line(s) allowed (0 - "max")
- atleast = at least "max" empty lines required
**/
enum abstract EmptyLinesPolicy(String) {
var IGNORE = "ignore";
var NONE = "none";
var EXACT = "exact";
var UPTO = "upto";
var ATLEAST = "atleast";
}
enum EmptyLinesFieldType {
VAR;
FUNCTION;
OTHER;
}
/**
empty line check supports the following places
- afterAbstractVars = after abstract var block
- afterClassStaticVars = after static class var block
- afterClassVars = after class var block
- afterImports = after all imports/usings
- afterLeftCurly = after left curly
- afterMultiLineComment = after multi line comment
- afterPackage = after package
- afterSingleLineComment = after single line comment
- anywhereInFile = anywhere in file
- beforePackage = before package
- beforeRightCurly = before right curly
- beforeUsing = before using block
- beginAbstract = after abstract left curly
- beginClass = after class left curly
- beginEnum = after enum left curly
- beforeFileEnd = before EOF
- beginInterface = after interface left curly
- beginTypedef = after typedef left curly
- betweenAbstractMethods = between abstract methods
- betweenAbstractVars = between abstract vars
- betweenClassMethods = between class methods
- betweenClassStaticVars = between static class vars
- betweenClassVars = between class vars
- betweenEnumFields = between enum fields
- betweenImports = between imports/usings
- betweenInterfaceFields = between interface fields
- betweenTypedefFields = between typedef fields
- betweenTypes = betgween two types
- endClass = before class right curly
- endAbstract = before abstract right curly
- endInterface = before interface right curly
- endEnum = before enum right curly
- endTypedef = before typedef right curly
- inFunction = anywhere inside function body
- typeDefinition = between type and left curly
**/
enum abstract EmptyLinesPlace(String) to String {
var BEFORE_PACKAGE = "beforePackage";
var AFTER_PACKAGE = "afterPackage";
var BETWEEN_IMPORTS = "betweenImports";
var BEFORE_USING = "beforeUsing";
var AFTER_IMPORTS = "afterImports";
var ANYWHERE_IN_FILE = "anywhereInFile";
var BETWEEN_TYPES = "betweenTypes";
var BEFORE_FILE_END = "beforeFileEnd";
var IN_FUNCTION = "inFunction";
var AFTER_LEFT_CURLY = "afterLeftCurly";
var BEFORE_RIGHT_CURLY = "beforeRightCurly";
var TYPE_DEFINITION = "typeDefinition";
var BEGIN_CLASS = "beginClass";
var END_CLASS = "endClass";
var AFTER_CLASS_STATIC_VARS = "afterClassStaticVars";
var AFTER_CLASS_VARS = "afterClassVars";
var BETWEEN_CLASS_STATIC_VARS = "betweenClassStaticVars";
var BETWEEN_CLASS_VARS = "betweenClassVars";
var BETWEEN_CLASS_METHODS = "betweenClassMethods";
var BEGIN_ABSTRACT = "beginAbstract";
var END_ABSTRACT = "endAbstract";
var AFTER_ABSTRACT_VARS = "afterAbstractVars";
var BETWEEN_ABSTRACT_VARS = "betweenAbstractVars";
var BETWEEN_ABSTRACT_METHODS = "betweenAbstractMethods";
var BEGIN_INTERFACE = "beginInterface";
var END_INTERFACE = "endInterface";
var BETWEEN_INTERFACE_FIELDS = "betweenInterfaceFields";
var BEGIN_ENUM = "beginEnum";
var END_ENUM = "endEnum";
var BETWEEN_ENUM_FIELDS = "betweenEnumFields";
var BEGIN_TYPEDEF = "beginTypedef";
var END_TYPEDEF = "endTypedef";
var BETWEEN_TYPEDEF_FIELDS = "betweenTypedefFields";
var AFTER_SINGLELINE_COMMENT = "afterSingleLineComment";
var AFTER_MULTILINE_COMMENT = "afterMultiLineComment";
var BEFORE_SINGLELINE_COMMENT = "beforeSingleLineComment";
var BEFORE_MULTILINE_COMMENT = "beforeMultiLineComment";
var AFTER_DOC_COMMENT_FIELD = "afterDocCommentField";
}