IPSIS_S05.tcl
328 lines
| 16.0 KiB
| application/x-tcl
|
TclLexer
r2 | #!/usr/bin/tclsh | ||
# Declaration order inside classes | |||
proc createMachine {visibility initState} { | |||
set machine [dict create visibility $visibility state $initState waitingFor "typedef" previousState "" bracesCounter 0 isStatic 0] | |||
return $machine | |||
} | |||
proc createVisibilityMachine {} { | |||
set machine [dict create state "beforeLeftBrace" visibilityState "waitingForPublic" bracesCounter 0 visibility ""] | |||
return $machine | |||
} | |||
set tokenFilter { | |||
public | |||
protected | |||
private | |||
colon | |||
typedef | |||
class | |||
struct | |||
enum | |||
static | |||
const | |||
identifier | |||
operator | |||
assign | |||
semicolon | |||
leftbrace | |||
rightbrace | |||
leftparen | |||
rightparen | |||
} | |||
set globalOrder "The global order is public members then public slots, protected members then protected slots and private members then private slots." | |||
foreach fileName [getSourceFileNames] { | |||
set machines [list] | |||
set visibilityMachines [list] | |||
set visibilityState "waitingForPublic" | |||
set prev1 "" | |||
set prev2 "" | |||
set lastIdentifier "" | |||
foreach token [getTokens $fileName 1 0 -1 -1 $tokenFilter] { | |||
set type [lindex $token 3] | |||
set line [lindex $token 1] | |||
if {$type == "identifier"} { | |||
set lastIdentifier [lindex $token 0] | |||
} | |||
if {$type == "class" || $type == "struct"} { | |||
lappend visibilityMachines [createVisibilityMachine] | |||
} | |||
if {$type == "colon" && ($prev1 == "public" || $prev1 == "protected" || $prev1 == "private")} { | |||
lappend machines [createMachine $prev1 "beforeVisibility"] | |||
} | |||
# Machines for the visibility order | |||
set visibilityMachinesToKeep [list] | |||
foreach m $visibilityMachines { | |||
set keepMachine 1 | |||
dict with m { | |||
if {$state == "beforeLeftBrace"} { | |||
if {$type == "semicolon"} { | |||
set keepMachine 0 | |||
} elseif {$type == "leftbrace"} { | |||
set state "root" | |||
} | |||
} elseif {$state == "root"} { | |||
if {$type == "public" || $type == "protected" || $type == "private"} { | |||
set visibility $type | |||
set state "waitingForColon" | |||
} elseif {$type == "leftbrace"} { | |||
incr bracesCounter | |||
set state "consumeBraces" | |||
} elseif {$type == "rightbrace"} { | |||
set keepMachine 0 | |||
} | |||
} elseif {$state == "waitingForColon"} { | |||
if {$type == "colon"} { | |||
if {$visibility == "public" && $prev1 != "identifier"} { | |||
if {$visibilityState == "waitingForPublicSlots" | |||
|| $visibilityState == "waitingForProtected" | |||
|| $visibilityState == "waitingForProtectedSlots" | |||
|| $visibilityState == "waitingForPrivate" | |||
|| $visibilityState == "waitingForPrivateSlots" | |||
|| $visibilityState == "done"} { | |||
report $fileName $line "There should be at most one public visibility and it should be at the start of the class. $globalOrder" | |||
} else { | |||
set visibilityState "waitingForPublicSlots" | |||
} | |||
} elseif {$visibility == "public" && $prev1 == "identifier" && $lastIdentifier == "slots"} { | |||
if {$visibilityState == "waitingForProtected" | |||
|| $visibilityState == "waitingForProtectedSlots" | |||
|| $visibilityState == "waitingForPrivate" | |||
|| $visibilityState == "waitingForPrivateSlots" | |||
|| $visibilityState == "done"} { | |||
report $fileName $line "There should be at most one public slots visibility and it should be between public and protected. $globalOrder" | |||
} else { | |||
set visibilityState "waitingForProtected" | |||
} | |||
} elseif {$visibility == "protected" && $prev1 != "identifier"} { | |||
if {$visibilityState == "waitingForProtectedSlots" | |||
|| $visibilityState == "waitingForPrivate" | |||
|| $visibilityState == "waitingForPrivateSlots" | |||
|| $visibilityState == "done"} { | |||
report $fileName $line "There should be at most one protected visibility and it should be between public slots and protected slots. $globalOrder" | |||
} else { | |||
set visibilityState "waitingForProtectedSlots" | |||
} | |||
} elseif {$visibility == "protected" && $prev1 == "identifier" && $lastIdentifier == "slots"} { | |||
if {$visibilityState == "waitingForPrivate" | |||
|| $visibilityState == "waitingForPrivateSlots" | |||
|| $visibilityState == "done"} { | |||
report $fileName $line "There should be at most one protected slots visibility and it should be between protected and private. $globalOrder" | |||
} else { | |||
set visibilityState "waitingForPrivate" | |||
} | |||
} elseif {$visibility == "private" && $prev1 != "identifier"} { | |||
if {$visibilityState == "waitingForPrivateSlots" | |||
|| $visibilityState == "done"} { | |||
report $fileName $line "There should be at most one private visibility and it should be between protected slots and private slots. $globalOrder" | |||
} else { | |||
set visibilityState "waitingForPrivateSlots" | |||
} | |||
} elseif {$visibility == "private" && $prev1 == "identifier" && $lastIdentifier == "slots"} { | |||
if {$visibilityState == "done"} { | |||
report $fileName $line "There should be at most one private visibility and it should be the last of the class. $globalOrder" | |||
} else { | |||
set visibilityState "done" | |||
} | |||
} | |||
set state "root" | |||
} | |||
} elseif {$state == "consumeBraces"} { | |||
if {$type == "leftbrace"} { | |||
incr bracesCounter | |||
} elseif {$type == "rightbrace"} { | |||
incr bracesCounter -1 | |||
if {$bracesCounter == 0} { | |||
set state "root" | |||
} | |||
} | |||
} | |||
} | |||
if {$keepMachine} { | |||
lappend visibilityMachinesToKeep $m | |||
} | |||
} | |||
set visibilityMachines $visibilityMachinesToKeep | |||
# Machines for the declaration order inside a visibility | |||
set machinesToKeep [list] | |||
foreach m $machines { | |||
set keepMachine 1 | |||
dict with m { | |||
if {$state == "beforeVisibility" && $type == $visibility} { | |||
set state "root" | |||
} elseif {$state == "root"} { | |||
if {$type == "public" || $type == "protected" || $type == "private" || $type == "rightbrace"} { | |||
# End of the state machine when we reach the next | |||
# visibility block | |||
set keepMachine 0 | |||
} else { | |||
if {$type == "static"} { | |||
set isStatic 1 | |||
} | |||
if {$waitingFor == "typedef"} { | |||
if {$type == "typedef"} { | |||
set state "consumeUntilNextSemiColon" | |||
} else { | |||
set waitingFor "enum" | |||
} | |||
} | |||
if {$waitingFor == "enum"} { | |||
if {$type == "typedef"} { | |||
set state "consumeUntilNextSemiColon" | |||
report $fileName $line "The typedefs should be before the enums" | |||
} elseif {$type == "enum"} { | |||
set state "consumeUntilNextSemiColon" | |||
} else { | |||
set waitingFor "class/struct" | |||
} | |||
} | |||
if {$waitingFor == "class/struct"} { | |||
if {$type == "typedef" || $type == "enum"} { | |||
set state "consumeUntilNextSemiColon" | |||
report $fileName $line "The typedefs and enums should be before the classes/structs" | |||
} elseif {$type == "class" || $type == "struct"} { | |||
set state "consumeUntilNextSemiColon" | |||
} else { | |||
set waitingFor "staticFunc" | |||
} | |||
} | |||
if {$waitingFor == "staticFunc"} { | |||
if {$type == "typedef" || $type == "enum" || $type == "class" || $type == "struct"} { | |||
set state "consumeUntilNextSemiColon" | |||
report $fileName $line "The typedefs, enums, classes and structs should be before the static functions" | |||
} elseif {$prev1 == "identifier"} { | |||
if {$type == "leftparen"} { | |||
if {$isStatic} { | |||
set state "consumeFunction" | |||
} else { | |||
set waitingFor "method" | |||
} | |||
} elseif {$type == "assign" || $type == "semicolon"} { | |||
set waitingFor "staticVar" | |||
} | |||
} | |||
} | |||
if {$waitingFor == "staticVar"} { | |||
if {$type == "typedef" || $type == "enum" || $type == "class" || $type == "struct"} { | |||
set state "consumeUntilNextSemiColon" | |||
report $fileName $line "The typedefs, enums, classes and structs should be before the static variables" | |||
} elseif {$prev1 == "identifier"} { | |||
if {$type == "leftparen"} { | |||
if {$isStatic} { | |||
set state "consumeFunction" | |||
report $fileName $line "The static functions should be before the static variables" | |||
} else { | |||
set waitingFor "method" | |||
} | |||
} elseif {$type == "assign" || $type == "semicolon"} { | |||
if {!$isStatic} { | |||
set waitingFor "method" | |||
} | |||
if {$type != "semicolon"} { | |||
set state "consumeUntilNextSemiColon" | |||
} else { | |||
set isStatic 0 | |||
} | |||
} | |||
} | |||
} | |||
if {$waitingFor == "method"} { | |||
if {$type == "typedef" || $type == "enum" || $type == "class" || $type == "struct"} { | |||
set state "consumeUntilNextSemiColon" | |||
report $fileName $line "The typedefs, enums, classes and structs should be before the methods" | |||
} elseif {$prev2 == "identifier" && $prev1 == "operator" && $type == "assign"} { | |||
# override of operator=() | |||
set state "consumeFunction" | |||
} elseif {$prev1 == "identifier"} { | |||
if {$type == "leftparen"} { | |||
if {$isStatic} { | |||
report $fileName $line "The static functions should be before the methods" | |||
} | |||
set state "consumeFunction" | |||
} elseif {$type == "assign" || $type == "semicolon"} { | |||
if {$isStatic} { | |||
report $fileName $line "The static variables should be before the methods" | |||
} else { | |||
set waitingFor "var" | |||
} | |||
} | |||
} | |||
} | |||
if {$waitingFor == "var"} { | |||
if {$type == "typedef" || $type == "enum" || $type == "class" || $type == "struct"} { | |||
set state "consumeUntilNextSemiColon" | |||
report $fileName $line "The typedefs, enums, classes and structs should be before the variables" | |||
} elseif {$prev1 == "identifier"} { | |||
if {$type == "leftparen"} { | |||
if {$isStatic} { | |||
report $fileName $line "The static functions should be before the variables" | |||
} else { | |||
report $fileName $line "The methods should be before the variables" | |||
} | |||
set state "consumeFunction" | |||
} elseif {$type == "assign" || $type == "semicolon"} { | |||
if {$isStatic} { | |||
report $fileName $line "The static variables should be before the variables" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} elseif {$state == "consumeUntilNextSemiColon"} { | |||
set isStatic 0 | |||
if {$type == "semicolon"} { | |||
set state "root" | |||
} elseif {$type == "leftbrace"} { | |||
incr bracesCounter | |||
set previousState $state | |||
set state "consumeBraces" | |||
} | |||
} elseif {$state == "consumeFunction"} { | |||
set isStatic 0 | |||
if {$type == "semicolon"} { | |||
set state "root" | |||
} elseif {$type == "leftbrace"} { | |||
incr bracesCounter | |||
set previousState "root" | |||
set state "consumeBraces" | |||
} | |||
} elseif {$state == "consumeBraces"} { | |||
if {$type == "leftbrace"} { | |||
incr bracesCounter | |||
} elseif {$type == "rightbrace"} { | |||
incr bracesCounter -1 | |||
if {$bracesCounter == 0} { | |||
set state $previousState | |||
} | |||
} | |||
} | |||
} | |||
if {$keepMachine} { | |||
lappend machinesToKeep $m | |||
} | |||
} | |||
set machines $machinesToKeep | |||
set prev2 $prev1 | |||
set prev1 $type | |||
} | |||
} |