11use itertools:: izip;
22use std:: convert:: TryInto ;
33use serde:: { Deserialize , Serialize } ;
4+ use crate :: analysis:: parsing:: lexer:: TokenKind ;
5+ use crate :: analysis:: parsing:: misc:: CDeclContent ;
46use crate :: analysis:: parsing:: types:: { BitfieldsContent , LayoutContent ,
57 StructTypeContent } ;
68use crate :: lint:: { rules:: { Rule , RuleType } ,
79 DMLStyleError } ;
8- use crate :: analysis:: parsing:: tree:: { TreeElement , ZeroRange } ;
10+ use crate :: analysis:: parsing:: tree:: { LeafToken , TreeElement , ZeroRange } ;
911use crate :: analysis:: parsing:: expression:: { FunctionCallContent , IndexContent ,
1012 PostUnaryExpressionContent ,
1113 UnaryExpressionContent } ;
@@ -501,3 +503,132 @@ impl Rule for NspTrailingRule {
501503 RuleType :: NspTrailing
502504 }
503505}
506+ pub struct SpPtrDeclRule {
507+ pub enabled : bool ,
508+ }
509+
510+ #[ derive( Clone , Debug , Serialize , Deserialize , PartialEq ) ]
511+ pub struct SpPtrDeclOptions { }
512+
513+ impl Rule for SpPtrDeclRule {
514+ fn name ( ) -> & ' static str {
515+ "SP_PTRDECL"
516+ }
517+ fn description ( ) -> & ' static str {
518+ "There should be a space between type and * marking a pointer"
519+ }
520+ fn get_rule_type ( ) -> RuleType {
521+ RuleType :: SpPtrDecl
522+ }
523+ }
524+
525+ fn has_space_between ( range_left : & ZeroRange ,
526+ range_right : & ZeroRange ) -> bool {
527+ return !( ( range_left. row_end == range_right. row_start )
528+ && ( range_left. col_end == range_right. col_start ) )
529+ }
530+ pub struct SpPtrDeclArgs {
531+ type_name_range : ZeroRange ,
532+ operator_ranges : Vec < ZeroRange >
533+ }
534+
535+ fn extract_operator_ranges_from_cdecl ( node : & CDeclContent ) -> Vec < ZeroRange > {
536+ node. modifiers . iter ( )
537+ . filter_map ( |m| {
538+ match m {
539+ LeafToken :: Actual ( token) => {
540+ match token. kind {
541+ TokenKind :: Multiply => Some ( m. range ( ) ) ,
542+ _ => None
543+ }
544+ }
545+ LeafToken :: Missing ( _) => None
546+ }
547+ } ) . collect ( )
548+ }
549+
550+ impl SpPtrDeclArgs {
551+ pub fn from_cdecl ( node : & CDeclContent ) -> Option < SpPtrDeclArgs > {
552+ // Check if node has a multiply token inside its modifiers
553+ let operator_ranges: Vec < ZeroRange > = extract_operator_ranges_from_cdecl ( node) ;
554+ Some ( SpPtrDeclArgs {
555+ type_name_range : node. base . range ( ) ,
556+ operator_ranges : operator_ranges,
557+ } )
558+ }
559+ }
560+
561+ impl SpPtrDeclRule {
562+ pub fn check ( & self , acc : & mut Vec < DMLStyleError > ,
563+ ranges : Option < SpPtrDeclArgs > ) {
564+ if !self . enabled { return ; }
565+ match ranges {
566+ None => return ,
567+ Some ( ranges) => {
568+ if ranges. operator_ranges . iter ( ) . any ( |op_range| {
569+ !has_space_between ( & ranges. type_name_range , op_range)
570+ } ) {
571+ self . push_err ( acc, ranges. type_name_range ) ;
572+ }
573+ }
574+ }
575+
576+ }
577+ }
578+
579+ pub struct NspPtrDeclRule {
580+ pub enabled : bool ,
581+ }
582+
583+ #[ derive( Clone , Debug , Serialize , Deserialize , PartialEq ) ]
584+ pub struct NspPtrDeclOptions { }
585+
586+ pub struct NspPtrDeclArgs {
587+ rightmost_multiply : Option < ZeroRange > ,
588+ identifier_range : ZeroRange
589+ }
590+
591+ impl NspPtrDeclArgs {
592+ pub fn from_cdecl ( node : & CDeclContent ) -> Option < NspPtrDeclArgs > {
593+ // Check if node has a multiply token inside its modifiers
594+ let operator_ranges: Vec < ZeroRange > = extract_operator_ranges_from_cdecl ( node) ;
595+ let rightmost_multiply: Option < ZeroRange > = operator_ranges. last ( ) . cloned ( ) ;
596+ Some ( NspPtrDeclArgs {
597+ rightmost_multiply : rightmost_multiply,
598+ identifier_range : node. decl . range ( )
599+ } )
600+ }
601+ }
602+
603+ impl Rule for NspPtrDeclRule {
604+ fn name ( ) -> & ' static str {
605+ "NSP_PTRDECL"
606+ }
607+ fn description ( ) -> & ' static str {
608+ "There should be no space after the * marking a pointer in a declaration"
609+ }
610+ fn get_rule_type ( ) -> RuleType {
611+ RuleType :: NspPtrDecl
612+ }
613+ }
614+
615+ impl NspPtrDeclRule {
616+ pub fn check ( & self , acc : & mut Vec < DMLStyleError > ,
617+ ranges : Option < NspPtrDeclArgs > ) {
618+ if !self . enabled { return ; }
619+ match ranges {
620+ None => return ,
621+ Some ( ranges) => {
622+ match ranges. rightmost_multiply {
623+ None => return ,
624+ Some ( op_range) => {
625+ if has_space_between ( & op_range, & ranges. identifier_range ) {
626+ self . push_err ( acc, ranges. identifier_range ) ;
627+ }
628+ }
629+ }
630+ }
631+ }
632+
633+ }
634+ }
0 commit comments