11use std:: convert:: TryInto ;
22
3- use crate :: analysis:: parsing:: { expression:: { CastContent , FunctionCallContent , ParenExpressionContent } ,
4- lexer:: TokenKind ,
5- statement:: { self , CompoundContent , DoContent , ForContent , ForeachContent ,
6- IfContent , SwitchCase , SwitchContent , WhileContent } ,
7- structure:: { MethodContent , ObjectStatementsContent } ,
8- tree:: TreeElementTokenIterator ,
9- types:: { BitfieldsContent , LayoutContent , StructTypeContent } } ;
3+ use crate :: analysis:: parsing:: { expression:: { CastContent , FunctionCallContent , ParenExpressionContent } , lexer:: TokenKind , parser:: Token , statement:: { self , CompoundContent , DoContent , ForContent , ForeachContent , IfContent , StatementContent , SwitchCase , SwitchContent , WhileContent } , structure:: { DMLObjectContent , MethodContent , ObjectStatementsContent } , tree:: TreeElementTokenIterator , types:: { BitfieldsContent , LayoutContent , StructTypeContent } } ;
104use crate :: span:: { Range , ZeroIndexed } ;
115use crate :: analysis:: parsing:: tree:: { ZeroRange , Content , TreeElement } ;
126use serde:: { Deserialize , Serialize } ;
@@ -35,6 +29,9 @@ pub fn setup_indentation_size(cfg: &mut LintCfg) {
3529 if let Some ( indent_empty_loop) = & mut cfg. indent_empty_loop {
3630 indent_empty_loop. indentation_spaces = indentation_spaces;
3731 }
32+ if let Some ( indent_continuation_line) = & mut cfg. indent_continuation_line {
33+ indent_continuation_line. indentation_spaces = indentation_spaces;
34+ }
3835}
3936#[ derive( Clone , Debug , Serialize , Deserialize , PartialEq ) ]
4037pub struct LongLineOptions {
@@ -377,8 +374,8 @@ pub struct IndentParenExprArgs {
377374}
378375
379376impl IndentParenExprArgs {
380- fn filter_out_parenthesized_ranges ( expression_tokens : TreeElementTokenIterator ) -> Vec < ZeroRange > {
381- let mut token_ranges : Vec < ZeroRange > = vec ! [ ] ;
377+ pub fn filter_out_parenthesized_tokens ( expression_tokens : TreeElementTokenIterator ) -> Vec < Token > {
378+ let mut token_list : Vec < Token > = vec ! [ ] ;
382379 let mut paren_depth = 0 ;
383380 // paren_depth is used to identify nested
384381 // parenthesized expressions within other expressions
@@ -387,25 +384,32 @@ impl IndentParenExprArgs {
387384 for token in expression_tokens {
388385 match token. kind {
389386 TokenKind :: LParen => {
387+ if paren_depth == 0 { token_list. push ( token) ; }
390388 paren_depth += 1 ;
391- token_ranges. push ( token. range ) ;
392389 } ,
393- TokenKind :: RParen => paren_depth-=1 ,
394- _ => { if paren_depth == 0 { token_ranges. push ( token. range ) ; }
390+ TokenKind :: RParen => {
391+ paren_depth-=1 ;
392+ if paren_depth == 0 { token_list. push ( token) ; }
393+ } ,
394+ TokenKind :: LBrace => {
395+ break ;
396+ } ,
397+ _ => {
398+ if paren_depth == 0 { token_list. push ( token) ; }
395399 }
396400 }
397401 }
398- token_ranges
402+ token_list
399403 }
400404
401405 pub fn from_for ( node : & ForContent ) -> Option < IndentParenExprArgs > {
402406 // For loop has three parts within parentheses: pre, cond, and post
403407 let mut filtered_member_ranges: Vec < ZeroRange > = vec ! [ ] ;
404- filtered_member_ranges. append ( & mut Self :: filter_out_parenthesized_ranges ( node. pre . tokens ( ) ) ) ;
408+ filtered_member_ranges. extend ( & mut Self :: filter_out_parenthesized_tokens ( node. pre . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) ) ;
405409 filtered_member_ranges. push ( node. lsemi . range ( ) ) ;
406- filtered_member_ranges. append ( & mut Self :: filter_out_parenthesized_ranges ( node. cond . tokens ( ) ) ) ;
410+ filtered_member_ranges. extend ( & mut Self :: filter_out_parenthesized_tokens ( node. cond . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) ) ;
407411 filtered_member_ranges. push ( node. rsemi . range ( ) ) ;
408- filtered_member_ranges. append ( & mut Self :: filter_out_parenthesized_ranges ( node. post . tokens ( ) ) ) ;
412+ filtered_member_ranges. extend ( & mut Self :: filter_out_parenthesized_tokens ( node. post . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) ) ;
409413
410414 Some ( IndentParenExprArgs {
411415 members_ranges : filtered_member_ranges,
@@ -415,15 +419,15 @@ impl IndentParenExprArgs {
415419
416420 pub fn from_foreach ( node : & ForeachContent ) -> Option < IndentParenExprArgs > {
417421 Some ( IndentParenExprArgs {
418- members_ranges : Self :: filter_out_parenthesized_ranges ( node. expression . tokens ( ) ) ,
422+ members_ranges : Self :: filter_out_parenthesized_tokens ( node. expression . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) . collect ( ) ,
419423 lparen : node. lparen . range ( ) ,
420424 } )
421425 }
422426
423427 pub fn from_function_call ( node : & FunctionCallContent ) -> Option < IndentParenExprArgs > {
424428 let mut filtered_member_ranges: Vec < ZeroRange > = vec ! [ ] ;
425429 for ( arg, _comma) in node. arguments . iter ( ) {
426- filtered_member_ranges. append ( & mut Self :: filter_out_parenthesized_ranges ( arg. tokens ( ) ) ) ;
430+ filtered_member_ranges. extend ( Self :: filter_out_parenthesized_tokens ( arg. tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) ) ;
427431 }
428432 Some ( IndentParenExprArgs {
429433 members_ranges : filtered_member_ranges,
@@ -434,15 +438,15 @@ impl IndentParenExprArgs {
434438 pub fn from_paren_expression ( node : & ParenExpressionContent )
435439 -> Option < IndentParenExprArgs > {
436440 Some ( IndentParenExprArgs {
437- members_ranges : Self :: filter_out_parenthesized_ranges ( node. expr . tokens ( ) ) ,
441+ members_ranges : Self :: filter_out_parenthesized_tokens ( node. expr . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) . collect ( ) ,
438442 lparen : node. lparen . range ( ) ,
439443 } )
440444 }
441445
442446 pub fn from_method ( node : & MethodContent ) -> Option < IndentParenExprArgs > {
443447 let mut filtered_member_ranges: Vec < ZeroRange > = vec ! [ ] ;
444448 for ( arg, _comma) in node. arguments . iter ( ) {
445- filtered_member_ranges. append ( & mut Self :: filter_out_parenthesized_ranges ( arg. tokens ( ) ) ) ;
449+ filtered_member_ranges. extend ( Self :: filter_out_parenthesized_tokens ( arg. tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) ) ;
446450 }
447451 Some ( IndentParenExprArgs {
448452 members_ranges : filtered_member_ranges,
@@ -452,21 +456,21 @@ impl IndentParenExprArgs {
452456
453457 pub fn from_while ( node : & WhileContent ) -> Option < IndentParenExprArgs > {
454458 Some ( IndentParenExprArgs {
455- members_ranges : Self :: filter_out_parenthesized_ranges ( node. cond . tokens ( ) ) ,
459+ members_ranges : Self :: filter_out_parenthesized_tokens ( node. cond . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) . collect ( ) ,
456460 lparen : node. lparen . range ( ) ,
457461 } )
458462 }
459463
460464 pub fn from_do_while ( node : & DoContent ) -> Option < IndentParenExprArgs > {
461465 Some ( IndentParenExprArgs {
462- members_ranges : Self :: filter_out_parenthesized_ranges ( node. cond . tokens ( ) ) ,
466+ members_ranges : Self :: filter_out_parenthesized_tokens ( node. cond . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) . collect ( ) ,
463467 lparen : node. lparen . range ( ) ,
464468 } )
465469 }
466470
467471 pub fn from_if ( node : & IfContent ) -> Option < IndentParenExprArgs > {
468472 Some ( IndentParenExprArgs {
469- members_ranges : Self :: filter_out_parenthesized_ranges ( node. cond . tokens ( ) ) ,
473+ members_ranges : Self :: filter_out_parenthesized_tokens ( node. cond . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) . collect ( ) ,
470474 lparen : node. lparen . range ( ) ,
471475 } )
472476 }
@@ -475,14 +479,14 @@ impl IndentParenExprArgs {
475479 let mut cast_member_tokens = node. from . tokens ( ) ;
476480 cast_member_tokens. append ( & mut node. to . tokens ( ) ) ;
477481 Some ( IndentParenExprArgs {
478- members_ranges : Self :: filter_out_parenthesized_ranges ( cast_member_tokens) ,
482+ members_ranges : Self :: filter_out_parenthesized_tokens ( cast_member_tokens) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) . collect ( ) ,
479483 lparen : node. lparen . range ( ) ,
480484 } )
481485 }
482486
483487 pub fn from_switch ( node : & SwitchContent ) -> Option < IndentParenExprArgs > {
484488 Some ( IndentParenExprArgs {
485- members_ranges : Self :: filter_out_parenthesized_ranges ( node. expr . tokens ( ) ) ,
489+ members_ranges : Self :: filter_out_parenthesized_tokens ( node. expr . tokens ( ) ) . iter ( ) . filter ( |t| t . kind != TokenKind :: RParen ) . map ( |t| t . range ) . collect ( ) ,
486490 lparen : node. lparen . range ( ) ,
487491 } )
488492 }
@@ -689,3 +693,122 @@ impl Rule for IndentEmptyLoopRule {
689693 RuleType :: IN10
690694 }
691695}
696+
697+ // in6
698+ pub struct IndentContinuationLineRule {
699+ pub enabled : bool ,
700+ indentation_spaces : u32
701+ }
702+
703+ #[ derive( Clone , Debug , Serialize , Deserialize , PartialEq ) ]
704+ pub struct IndentContinuationLineOptions {
705+ #[ serde( default = "default_indentation_spaces" ) ]
706+ pub indentation_spaces : u32 ,
707+ }
708+
709+ pub struct IndentContinuationLineArgs {
710+ token_list : Vec < Token > ,
711+ expected_depth : u32 ,
712+ }
713+
714+ impl IndentContinuationLineArgs {
715+ pub fn filter_out_last_semi_ranges ( expression_tokens : & mut TreeElementTokenIterator ) {
716+ // This function filters out the last semicolon in a list of tokens
717+ // as it is not part of the continuation line check.
718+ expression_tokens. pop_if ( |token| token. kind == TokenKind :: SemiColon ) ;
719+ }
720+
721+ pub fn from_statement_content ( node : & StatementContent , depth : u32 ) -> Option < IndentContinuationLineArgs > {
722+ match node {
723+ StatementContent :: Compound ( _) |
724+ StatementContent :: If ( _) |
725+ StatementContent :: While ( _) |
726+ StatementContent :: Do ( _) |
727+ StatementContent :: For ( _) |
728+ StatementContent :: Try ( _) |
729+ StatementContent :: Foreach ( _) |
730+ StatementContent :: Throw ( _) |
731+ StatementContent :: Switch ( _) => return None ,
732+ _ => { }
733+ } ;
734+ let mut tokens = node. tokens ( ) ;
735+ Self :: filter_out_last_semi_ranges ( & mut tokens) ;
736+
737+ Some ( IndentContinuationLineArgs {
738+ token_list : IndentParenExprArgs :: filter_out_parenthesized_tokens ( tokens) ,
739+ expected_depth : depth,
740+ } )
741+ }
742+
743+ pub fn from_dml_object_content ( node : & DMLObjectContent , depth : u32 ) -> Option < IndentContinuationLineArgs > {
744+ match node {
745+ DMLObjectContent :: Parameter ( _) |
746+ DMLObjectContent :: Hook ( _) |
747+ DMLObjectContent :: Import ( _) |
748+ DMLObjectContent :: InEach ( _) |
749+ DMLObjectContent :: Session ( _) |
750+ DMLObjectContent :: Typedef ( _) => {
751+ let mut tokens = node. tokens ( ) ;
752+ Self :: filter_out_last_semi_ranges ( & mut tokens) ;
753+ return Some ( IndentContinuationLineArgs {
754+ token_list : IndentParenExprArgs :: filter_out_parenthesized_tokens ( tokens) ,
755+ expected_depth : depth,
756+ } ) } ,
757+ _ => return None ,
758+ }
759+ }
760+ }
761+
762+ impl IndentContinuationLineRule {
763+ pub fn from_options ( options : & Option < IndentContinuationLineOptions > ) -> IndentContinuationLineRule {
764+ match options {
765+ Some ( options) => IndentContinuationLineRule {
766+ enabled : true ,
767+ indentation_spaces : options. indentation_spaces
768+ } ,
769+ None => IndentContinuationLineRule {
770+ enabled : false ,
771+ indentation_spaces : 0
772+ }
773+ }
774+ }
775+
776+ pub fn check < ' a > ( & self , acc : & mut Vec < DMLStyleError > ,
777+ args : Option < IndentContinuationLineArgs > ) {
778+ if !self . enabled { return ; }
779+ let Some ( args) = args else { return ; } ;
780+ if args. token_list . is_empty ( ) { return ; }
781+ let expected_line_start = self . indentation_spaces * ( args. expected_depth + 1 ) ;
782+ let mut last_row = args. token_list . first ( ) . unwrap ( ) . range . row_start . 0 ;
783+
784+ for token in args. token_list {
785+ match token. kind {
786+ TokenKind :: RParen => {
787+ if token. range . row_start . 0 != last_row {
788+ last_row = token. range . row_start . 0 ;
789+ }
790+ }
791+ _ => {
792+ if token. range . row_start . 0 != last_row {
793+ last_row = token. range . row_start . 0 ;
794+ if token. range . col_start . 0 != expected_line_start {
795+ acc. push ( self . create_err ( token. range ) )
796+ }
797+ }
798+ }
799+ }
800+ }
801+ }
802+ }
803+
804+ impl Rule for IndentContinuationLineRule {
805+ fn name ( ) -> & ' static str {
806+ "INDENT_CONTINUATION_LINE"
807+ }
808+ fn description ( ) -> & ' static str {
809+ "A continuation line not broken inside a parenthesized expression is indented one level."
810+ }
811+ fn get_rule_type ( ) -> RuleType {
812+ RuleType :: IN6
813+ }
814+ }
0 commit comments