@specs-feup/clava-misra 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.gitignore +8 -0
  2. package/README.md +53 -19
  3. package/dist/MISRA.d.ts +28 -10
  4. package/dist/MISRA.d.ts.map +1 -1
  5. package/dist/MISRA.js +30 -10
  6. package/dist/MISRA.js.map +1 -1
  7. package/dist/MISRAContext.d.ts +65 -11
  8. package/dist/MISRAContext.d.ts.map +1 -1
  9. package/dist/MISRAContext.js +131 -35
  10. package/dist/MISRAContext.js.map +1 -1
  11. package/dist/MISRARule.d.ts +38 -25
  12. package/dist/MISRARule.d.ts.map +1 -1
  13. package/dist/MISRARule.js +40 -18
  14. package/dist/MISRARule.js.map +1 -1
  15. package/dist/MISRATool.d.ts +46 -5
  16. package/dist/MISRATool.d.ts.map +1 -1
  17. package/dist/MISRATool.js +118 -45
  18. package/dist/MISRATool.js.map +1 -1
  19. package/dist/StandardGuideline.d.ts +22 -0
  20. package/dist/StandardGuideline.d.ts.map +1 -0
  21. package/dist/StandardGuideline.js +12 -0
  22. package/dist/StandardGuideline.js.map +1 -0
  23. package/dist/ast-visitor/Context.d.ts +11 -0
  24. package/dist/ast-visitor/Context.d.ts.map +1 -0
  25. package/dist/ast-visitor/Context.js +15 -0
  26. package/dist/ast-visitor/Context.js.map +1 -0
  27. package/dist/ast-visitor/Visit.d.ts +23 -0
  28. package/dist/ast-visitor/Visit.d.ts.map +1 -0
  29. package/dist/ast-visitor/Visit.js +18 -0
  30. package/dist/ast-visitor/Visit.js.map +1 -0
  31. package/dist/ast-visitor/VisitWithContext.d.ts +32 -0
  32. package/dist/ast-visitor/VisitWithContext.d.ts.map +1 -0
  33. package/dist/ast-visitor/VisitWithContext.js +26 -0
  34. package/dist/ast-visitor/VisitWithContext.js.map +1 -0
  35. package/dist/main.js +1 -2
  36. package/dist/main.js.map +1 -1
  37. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts +27 -0
  38. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts.map +1 -0
  39. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js +98 -0
  40. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js.map +1 -0
  41. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts +45 -6
  42. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts.map +1 -1
  43. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js +91 -8
  44. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js.map +1 -1
  45. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts +15 -5
  46. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts.map +1 -1
  47. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js +20 -6
  48. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js.map +1 -1
  49. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts +11 -5
  50. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts.map +1 -1
  51. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js +13 -10
  52. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js.map +1 -1
  53. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts +11 -6
  54. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts.map +1 -1
  55. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js +19 -11
  56. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js.map +1 -1
  57. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts +15 -5
  58. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts.map +1 -1
  59. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js +24 -10
  60. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js.map +1 -1
  61. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts +22 -6
  62. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts.map +1 -1
  63. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js +37 -10
  64. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js.map +1 -1
  65. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts +66 -0
  66. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts.map +1 -0
  67. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js +209 -0
  68. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js.map +1 -0
  69. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts +37 -12
  70. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts.map +1 -1
  71. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js +112 -39
  72. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js.map +1 -1
  73. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts +15 -5
  74. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts.map +1 -1
  75. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js +21 -7
  76. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js.map +1 -1
  77. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts +11 -6
  78. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts.map +1 -1
  79. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js +17 -8
  80. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js.map +1 -1
  81. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts +105 -0
  82. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts.map +1 -0
  83. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js +258 -0
  84. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js.map +1 -0
  85. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts +25 -0
  86. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts.map +1 -0
  87. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js +27 -0
  88. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js.map +1 -0
  89. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts +29 -0
  90. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts.map +1 -0
  91. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js +31 -0
  92. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js.map +1 -0
  93. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts +25 -0
  94. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts.map +1 -0
  95. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js +27 -0
  96. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js.map +1 -0
  97. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts +25 -0
  98. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts.map +1 -0
  99. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js +27 -0
  100. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js.map +1 -0
  101. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts +25 -0
  102. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts.map +1 -0
  103. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js +27 -0
  104. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js.map +1 -0
  105. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts +30 -0
  106. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts.map +1 -0
  107. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js +32 -0
  108. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js.map +1 -0
  109. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts +25 -0
  110. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts.map +1 -0
  111. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js +27 -0
  112. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js.map +1 -0
  113. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts +6 -14
  114. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts.map +1 -1
  115. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js +17 -27
  116. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js.map +1 -1
  117. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts +13 -7
  118. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts.map +1 -1
  119. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js +31 -17
  120. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js.map +1 -1
  121. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts +26 -7
  122. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts.map +1 -1
  123. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js +32 -14
  124. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js.map +1 -1
  125. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts +48 -6
  126. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts.map +1 -1
  127. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js +84 -34
  128. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js.map +1 -1
  129. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts +24 -5
  130. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts.map +1 -1
  131. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js +27 -7
  132. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js.map +1 -1
  133. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts +46 -0
  134. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts.map +1 -0
  135. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js +40 -0
  136. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js.map +1 -0
  137. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts +25 -0
  138. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts.map +1 -0
  139. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js +46 -0
  140. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js.map +1 -0
  141. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts +26 -0
  142. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts.map +1 -0
  143. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js +54 -0
  144. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js.map +1 -0
  145. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts +27 -0
  146. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts.map +1 -0
  147. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js +55 -0
  148. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js.map +1 -0
  149. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts +24 -0
  150. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts.map +1 -0
  151. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js +42 -0
  152. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js.map +1 -0
  153. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts +24 -0
  154. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts.map +1 -0
  155. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js +42 -0
  156. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js.map +1 -0
  157. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts +35 -0
  158. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts.map +1 -0
  159. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js +98 -0
  160. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js.map +1 -0
  161. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts +35 -0
  162. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts.map +1 -0
  163. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js +76 -0
  164. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js.map +1 -0
  165. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts +32 -0
  166. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts.map +1 -0
  167. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js +57 -0
  168. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js.map +1 -0
  169. package/dist/rules/UserConfigurableRule.d.ts +55 -0
  170. package/dist/rules/UserConfigurableRule.d.ts.map +1 -0
  171. package/dist/rules/UserConfigurableRule.js +16 -0
  172. package/dist/rules/UserConfigurableRule.js.map +1 -0
  173. package/dist/rules/index.d.ts +11 -18
  174. package/dist/rules/index.d.ts.map +1 -1
  175. package/dist/rules/index.js +47 -7
  176. package/dist/rules/index.js.map +1 -1
  177. package/dist/tests/Section17_Functions/misra_config.json +10 -0
  178. package/dist/tests/Section21-StandardLibraries/misra_config.json +88 -0
  179. package/dist/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
  180. package/dist/tests/utils.d.ts +6 -3
  181. package/dist/tests/utils.d.ts.map +1 -1
  182. package/dist/tests/utils.js +33 -7
  183. package/dist/tests/utils.js.map +1 -1
  184. package/dist/utils/CallUtils.d.ts +15 -0
  185. package/dist/utils/CallUtils.d.ts.map +1 -0
  186. package/dist/utils/CallUtils.js +34 -0
  187. package/dist/utils/CallUtils.js.map +1 -0
  188. package/dist/utils/CommentUtils.d.ts +21 -0
  189. package/dist/utils/CommentUtils.d.ts.map +1 -0
  190. package/dist/utils/CommentUtils.js +27 -0
  191. package/dist/utils/CommentUtils.js.map +1 -0
  192. package/dist/utils/FileUtils.d.ts +67 -0
  193. package/dist/utils/FileUtils.d.ts.map +1 -0
  194. package/dist/utils/FileUtils.js +144 -0
  195. package/dist/utils/FileUtils.js.map +1 -0
  196. package/dist/utils/FunctionUtils.d.ts +47 -0
  197. package/dist/utils/FunctionUtils.d.ts.map +1 -0
  198. package/dist/utils/FunctionUtils.js +87 -0
  199. package/dist/utils/FunctionUtils.js.map +1 -0
  200. package/dist/utils/IdentifierUtils.d.ts +63 -0
  201. package/dist/utils/IdentifierUtils.d.ts.map +1 -0
  202. package/dist/utils/IdentifierUtils.js +133 -0
  203. package/dist/utils/IdentifierUtils.js.map +1 -0
  204. package/dist/utils/JoinpointUtils.d.ts +36 -0
  205. package/dist/utils/JoinpointUtils.d.ts.map +1 -0
  206. package/dist/utils/JoinpointUtils.js +63 -0
  207. package/dist/utils/JoinpointUtils.js.map +1 -0
  208. package/dist/utils/ProgramUtils.d.ts +39 -0
  209. package/dist/utils/ProgramUtils.d.ts.map +1 -0
  210. package/dist/utils/ProgramUtils.js +97 -0
  211. package/dist/utils/ProgramUtils.js.map +1 -0
  212. package/dist/utils/SwitchUtils.d.ts +21 -0
  213. package/dist/utils/SwitchUtils.d.ts.map +1 -0
  214. package/dist/utils/SwitchUtils.js +47 -0
  215. package/dist/utils/SwitchUtils.js.map +1 -0
  216. package/dist/utils/TypeDeclUtils.d.ts +35 -0
  217. package/dist/utils/TypeDeclUtils.d.ts.map +1 -0
  218. package/dist/utils/TypeDeclUtils.js +78 -0
  219. package/dist/utils/TypeDeclUtils.js.map +1 -0
  220. package/dist/utils/VarUtils.d.ts +51 -0
  221. package/dist/utils/VarUtils.d.ts.map +1 -0
  222. package/dist/utils/VarUtils.js +91 -0
  223. package/dist/utils/VarUtils.js.map +1 -0
  224. package/package.json +16 -7
  225. package/src/MISRA.ts +33 -17
  226. package/src/MISRAContext.ts +128 -30
  227. package/src/MISRARule.ts +61 -29
  228. package/src/MISRATool.ts +126 -42
  229. package/src/StandardGuideline.ts +23 -0
  230. package/src/ast-visitor/Context.ts +16 -0
  231. package/src/ast-visitor/Visit.ts +26 -0
  232. package/src/ast-visitor/VisitWithContext.ts +42 -0
  233. package/src/main.ts +1 -4
  234. package/src/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.ts +114 -0
  235. package/src/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.ts +103 -13
  236. package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +24 -10
  237. package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +17 -8
  238. package/src/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.ts +20 -12
  239. package/src/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.ts +23 -12
  240. package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +44 -13
  241. package/src/rules/Section17_Functions/Rule_17_3_ImplicitFunction.ts +153 -104
  242. package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +114 -44
  243. package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +27 -10
  244. package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +20 -12
  245. package/src/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.ts +317 -0
  246. package/src/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.ts +30 -0
  247. package/src/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.ts +35 -0
  248. package/src/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.ts +30 -0
  249. package/src/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.ts +30 -0
  250. package/src/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.ts +29 -0
  251. package/src/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.ts +36 -0
  252. package/src/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.ts +30 -0
  253. package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +14 -29
  254. package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +33 -19
  255. package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +33 -20
  256. package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +90 -45
  257. package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +27 -8
  258. package/src/rules/Section5_Identifiers/IdentifierRenameRule.ts +63 -0
  259. package/src/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.ts +52 -0
  260. package/src/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.ts +62 -0
  261. package/src/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.ts +61 -0
  262. package/src/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.ts +47 -0
  263. package/src/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.ts +47 -0
  264. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.ts +118 -0
  265. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.ts +89 -0
  266. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.ts +65 -0
  267. package/src/rules/UserConfigurableRule.ts +60 -0
  268. package/src/rules/index.ts +45 -7
  269. package/src/tests/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.test.ts +114 -0
  270. package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +7 -5
  271. package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +40 -13
  272. package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +10 -12
  273. package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +5 -5
  274. package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +5 -5
  275. package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +5 -5
  276. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions.test.ts +68 -40
  277. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_MissingConfig.test.ts +98 -0
  278. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_ProblematicConfig.test.ts +71 -0
  279. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +103 -49
  280. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +7 -7
  281. package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -7
  282. package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +25 -21
  283. package/src/tests/Section17_Functions/misra_config.json +4 -3
  284. package/src/tests/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.test.ts +62 -0
  285. package/src/tests/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.test.ts +67 -0
  286. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.test.ts +84 -0
  287. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_MissingConfig.test.ts +33 -0
  288. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_ProblematicConfig.test.ts +71 -0
  289. package/src/tests/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.test.ts +63 -0
  290. package/src/tests/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.test.ts +91 -0
  291. package/src/tests/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.test.ts +65 -0
  292. package/src/tests/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.test.ts +89 -0
  293. package/src/tests/Section21-StandardLibraries/misra_config.json +88 -0
  294. package/src/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
  295. package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +148 -113
  296. package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +243 -163
  297. package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +32 -20
  298. package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +36 -30
  299. package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -8
  300. package/src/tests/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.test.ts +78 -0
  301. package/src/tests/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.test.ts +120 -0
  302. package/src/tests/Section5_Identifiers/Rule_5_7_UniqueTagNames.test.ts +51 -0
  303. package/src/tests/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.test.ts +73 -0
  304. package/src/tests/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.test.ts +97 -0
  305. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.test.ts +160 -0
  306. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.test.ts +46 -0
  307. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.test.ts +69 -0
  308. package/src/tests/utils.ts +32 -7
  309. package/src/utils/CallUtils.ts +37 -0
  310. package/src/utils/CommentUtils.ts +29 -0
  311. package/src/utils/FileUtils.ts +169 -0
  312. package/src/utils/FunctionUtils.ts +97 -0
  313. package/src/utils/IdentifierUtils.ts +142 -0
  314. package/src/utils/JoinpointUtils.ts +70 -0
  315. package/src/utils/ProgramUtils.ts +107 -0
  316. package/src/utils/SwitchUtils.ts +52 -0
  317. package/src/utils/TypeDeclUtils.ts +88 -0
  318. package/src/utils/VarUtils.ts +102 -0
  319. package/tsconfig.json +2 -1
  320. package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +0 -120
  321. package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +0 -36
  322. package/src/utils/utils.ts +0 -280
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Key-value storage to share data between visits
3
+ *
4
+ * @template T Type of the stored values
5
+ */
6
+ export default class Context<T> {
7
+ protected storage: Map<string, T> = new Map();
8
+
9
+ put(key: string, value: T) {
10
+ this.storage.set(key, value);
11
+ }
12
+
13
+ get(key: string): T | undefined {
14
+ return this.storage.get(key);
15
+ }
16
+ }
@@ -0,0 +1,26 @@
1
+ import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
2
+
3
+ /**
4
+ * Common interface for AST transformations applied to a single node
5
+ *
6
+ * Need to implement:
7
+ * - apply($jp)
8
+ *
9
+ * @template T Type of data stored in the shared context
10
+ * @template C Type of the context (default is Context<T>)
11
+ */
12
+ export default abstract class Visit {
13
+ /**
14
+ * Applies the transformation to the given node
15
+ * @param $jp The node to transform
16
+ * @returns Transformation result
17
+ */
18
+ abstract apply($jp: LaraJoinPoint): unknown;
19
+
20
+ /**
21
+ * @returns List of dependent visits, which is empty by default
22
+ */
23
+ get dependencies(): Visit[] {
24
+ return [];
25
+ }
26
+ }
@@ -0,0 +1,42 @@
1
+ import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
2
+ import Context from "./Context.js";
3
+ import Visit from "./Visit.js";
4
+
5
+ /**
6
+ * Visit with a shared context to enable communication between visits
7
+ *
8
+ * Need to implement:
9
+ * - apply($jp)
10
+ * - initialValue()
11
+ */
12
+ export default abstract class VisitWithContext<T, C extends Context<T> = Context<T>> extends Visit {
13
+ protected context: C;
14
+
15
+ /**
16
+ * @param context Shared context object
17
+ */
18
+ constructor(context: C) {
19
+ super();
20
+ this.context = context;
21
+ this.context.put(this.name, this.initialValue());
22
+ }
23
+
24
+ /**
25
+ * @return Visit name, defaults to class name
26
+ */
27
+ get name(): string {
28
+ return this.constructor.name;
29
+ }
30
+
31
+ /**
32
+ * @returns Initial value stored in the shared context
33
+ */
34
+ abstract initialValue(): T;
35
+
36
+ /**
37
+ * Applies the transformation to the given node
38
+ * @param $jp The node to transform
39
+ * @returns Transformation result
40
+ */
41
+ abstract apply($jp: LaraJoinPoint): unknown;
42
+ }
package/src/main.ts CHANGED
@@ -1,7 +1,4 @@
1
- import VisualizationTool from "@specs-feup/clava-visualization/api/VisualizationTool.js";
2
1
  import MISRATool from "./MISRATool.js";
3
2
 
4
3
  MISRATool.checkCompliance();
5
- MISRATool.applyCorrections();
6
-
7
- //await VisualizationTool.visualize();
4
+ MISRATool.correctViolations();
@@ -0,0 +1,114 @@
1
+ import { BinaryOp, Call, FileJp, Joinpoint, ParenExpr, UnaryExprOrType, UnaryOp, VariableArrayType, Varref } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
4
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
5
+ import { getVolatileVarRefs } from "../../utils/VarUtils.js";
6
+ import { isValidFile } from "../../utils/FileUtils.js";
7
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
8
+
9
+ /**
10
+ * MISRA-C Rule 13.6: The operand of the sizeof operator shall not contain any expression which has potential side effects
11
+ */
12
+ export default class Rule_13_6_SafeSizeOfOperand extends MISRARule {
13
+ /**
14
+ * Scope of analysis
15
+ */
16
+ analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
17
+
18
+ #modifyingExpressions: (UnaryOp | BinaryOp)[] = [];
19
+ #functionCalls: Call[] = [];
20
+ #volatileRefs: Varref[] = [];
21
+
22
+ /**
23
+ * @returns Rule identifier according to MISRA-C:2012
24
+ */
25
+ override get name(): string {
26
+ return "13.6";
27
+ }
28
+
29
+ private operandIsVariableArrayType($jp: UnaryExprOrType) {
30
+ return $jp.argType != undefined && $jp.argType instanceof VariableArrayType;
31
+ }
32
+
33
+ /**
34
+ *
35
+ * @param $jp - Joinpoint to analyze
36
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
37
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
38
+ */
39
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
40
+ if (!($jp instanceof UnaryExprOrType && $jp.kind === "sizeof")) {
41
+ return false;
42
+ }
43
+
44
+ this.#functionCalls = Query.searchFromInclusive($jp, Call).get();
45
+ this.#volatileRefs = this.operandIsVariableArrayType($jp) ? getVolatileVarRefs(($jp.argType as VariableArrayType).sizeExpr) : [];
46
+ this.#modifyingExpressions = [
47
+ ...Query.searchFromInclusive($jp, UnaryOp, {kind: /(post_inc)|(post_dec)|(pre_inc)|(pre_dec)/}).get(),
48
+ ...Query.searchFromInclusive($jp, BinaryOp, {kind: /(assign)|(add_assign)|(sub_assign)|(mul_assign)|(div_assign)|(rem_assign)|(shl_assign)|(shr_assign)|(and_assign)|(xor_assign)|(or_assign)/}).get()
49
+ ];
50
+
51
+ const isNonCompliant = this.#functionCalls.length > 0 || this.#modifyingExpressions.length > 0 || this.#volatileRefs.length > 0;
52
+
53
+ if (isNonCompliant && logErrors) {
54
+ this.#functionCalls.forEach(call => {
55
+ this.logMISRAError(call, `Function call '${call.name}' in sizeof is not allowed because it has no effect.`);
56
+ });
57
+
58
+ this.#modifyingExpressions.forEach(expr => {
59
+ this.logMISRAError(expr, `Modifying expression '${expr.code}' in sizeof is not allowed because it has no effect.`);
60
+ });
61
+
62
+ this.#volatileRefs.forEach(ref => {
63
+ this.logMISRAError(ref, `Access to volatile object ${ref.name} in sizeof is not allowed.`);
64
+ });
65
+ }
66
+
67
+ return isNonCompliant;
68
+ }
69
+
70
+ apply($jp: Joinpoint): MISRATransformationReport {
71
+ if (!this.match($jp)) {
72
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
73
+ }
74
+
75
+ if (!this.operandIsVariableArrayType($jp as UnaryExprOrType)) {
76
+ for (const callJp of this.#functionCalls) {
77
+ const callAncestor = callJp.getAncestor("call");
78
+ if (callAncestor === undefined || callAncestor.depth < $jp.depth) {
79
+ const functionType = callJp.functionType.returnType;
80
+ const fileJp = callJp.getAncestor("file") as FileJp;
81
+ const tempJp = fileJp.lastChild.insertAfter(ClavaJoinPoints.stmtLiteral(`static int _temp_misra_var = sizeof(${functionType.code});`));
82
+ const jpIndex = Query.searchFrom(fileJp, UnaryExprOrType).get().length;
83
+
84
+ let newSizeOf = isValidFile(fileJp, UnaryExprOrType, jpIndex) as UnaryExprOrType;
85
+ newSizeOf = $jp.replaceWith(newSizeOf) as UnaryExprOrType;
86
+ newSizeOf.setArgType(functionType);
87
+ tempJp.detach();
88
+ return new MISRATransformationReport(MISRATransformationType.Replacement, newSizeOf);
89
+ }
90
+ }
91
+
92
+ for (const expr of this.#modifyingExpressions) {
93
+ let varRef = expr instanceof BinaryOp ?
94
+ expr.left : Query.searchFrom(expr, Varref).get()[0];
95
+ expr.replaceWith(varRef);
96
+ }
97
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
98
+ }
99
+ else {
100
+ this.#functionCalls.forEach(call => {
101
+ this.logMISRAError(call, `Function call '${call.name}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
102
+ });
103
+
104
+ this.#modifyingExpressions.forEach(expr => {
105
+ this.logMISRAError(expr, `Modifying expression '${expr.code}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
106
+ });
107
+
108
+ this.#volatileRefs.forEach(ref => {
109
+ this.logMISRAError(ref,`Access to volatile object '${ref.name}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
110
+ });
111
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
112
+ }
113
+ }
114
+ }
@@ -1,21 +1,39 @@
1
- import { Case, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
1
+ import { Break, Case, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
2
2
  import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
3
  import Query from "@specs-feup/lara/api/weaver/Query.js";
5
- import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
4
+ import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
5
 
7
6
  /**
8
- * MISRA Rule 16.2: A switch label shall only be used when the most closely-enclosing
9
- compound statement is the body of a switch statement
7
+ * MISRA-C Rule 16.2: A switch label shall only be used when the most closely-enclosing compound statement is the body of a switch statement
10
8
  */
11
- export default class Rule_16_2_TopLevelSwitch extends MISRARule {
12
- priority = 2;
13
- #misplacedCases: Case[] = [];
9
+ export default class Rule_16_2_TopLevelSwitch extends MISRARule {
10
+ /**
11
+ * Scope of analysis
12
+ */
13
+ readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
14
+
15
+ /**
16
+ * A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
17
+ */
18
+ readonly priority = 4;
14
19
 
15
- constructor(context: MISRAContext) {
16
- super("16.2", context);
20
+ #misplacedCases: Case[] = [];
21
+
22
+ /**
23
+ * @returns Rule identifier according to MISRA-C:2012
24
+ */
25
+ override get name(): string {
26
+ return "16.2";
17
27
  }
18
28
 
29
+ /**
30
+ * Checks if the given joinpoint is a switch statement with any misplaced case labels.
31
+ * A case label is considered misplaced if it is not a direct child of the switch body.
32
+ *
33
+ * @param $jp - Joinpoint to analyze
34
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
35
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
36
+ */
19
37
  match($jp: Joinpoint, logErrors: boolean = false): boolean {
20
38
  if (!($jp instanceof Switch)) return false;
21
39
 
@@ -30,12 +48,84 @@ export default class Rule_16_2_TopLevelSwitch extends MISRARule {
30
48
  return this.#misplacedCases.length > 0;
31
49
  }
32
50
 
33
- transform($jp: Joinpoint): MISRATransformationReport {
34
- if (!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
51
+ /**
52
+ * Transforms the joinpoint if it represents a switch with any misplaced case labels.
53
+ * For that, each case label is moved to a new location within the switch.
54
+ *
55
+ * @param $jp - Joinpoint to transform
56
+ * @returns Report detailing the transformation result
57
+ */
58
+ apply($jp: Joinpoint): MISRATransformationReport {
59
+ if (!this.match($jp))
60
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
35
61
 
36
62
  for (const caseLabel of this.#misplacedCases) {
37
- caseLabel.detach();
63
+ this.changeCaseLocation(caseLabel);
38
64
  }
39
65
  return new MISRATransformationReport(MISRATransformationType.DescendantChange);
40
66
  }
67
+
68
+
69
+ /**
70
+ * Relocates a inner case to a new position while preserving control flow.
71
+ * First, copies the instructions to be executed (direct siblings and fall-through code).
72
+ * Then, moves the case to the new position and finally appends the copied instructions after the case.
73
+ *
74
+ * @param caseLabel The inner case to relocate
75
+ */
76
+ private changeCaseLocation(caseLabel: Case) {
77
+ // Collect instructions that follow the given case
78
+ const instructions = caseLabel.siblingsRight.map(sibling => sibling.deepCopy());
79
+
80
+ // If direct instruction do not have a break statement, find additional statements from higher scopes that will be executed
81
+ if (!instructions.some(instruction => instruction instanceof Break)) {
82
+ let lastScope: Joinpoint = caseLabel;
83
+ do {
84
+ lastScope = lastScope.parent;
85
+ const rightStmts = lastScope.siblingsRight;
86
+ for (const rightStmt of rightStmts) {
87
+ if (rightStmt.currentRegion instanceof Switch && rightStmt instanceof Case) {
88
+ break;
89
+ }
90
+ instructions.push(rightStmt.deepCopy());
91
+ }
92
+ } while(!(lastScope.currentRegion instanceof Switch));
93
+ }
94
+
95
+ // Locate target position
96
+ const caseAncestor = this.getCaseAncestor(caseLabel);
97
+ const caseAncestorRightSiblings = caseAncestor.siblingsRight;
98
+ const nextCaseIndex = caseAncestorRightSiblings.findIndex(jp => jp instanceof Case);
99
+ const targetStmt = nextCaseIndex != -1 ? caseAncestorRightSiblings[nextCaseIndex] : caseAncestorRightSiblings[caseAncestorRightSiblings.length - 1];
100
+
101
+ // Move case label to the new position
102
+ caseLabel.detach();
103
+ if (targetStmt instanceof Case) {
104
+ targetStmt.insertBefore(caseLabel);
105
+ } else {
106
+ targetStmt.insertAfter(caseLabel);
107
+ }
108
+
109
+ // Add instructions after caseLabel
110
+ let lastStmt: Joinpoint = caseLabel;
111
+ for (const instruction of instructions) {
112
+ lastStmt.insertAfter(instruction);
113
+ lastStmt = instruction;
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Retrieves the top-level case that contains a given inner case label.
119
+ *
120
+ * @param caseLabel - The inner case joinpoint
121
+ * @returns The ancestor case that contains the given inner case
122
+ */
123
+ private getCaseAncestor(caseLabel: Case): Case {
124
+ let stmt: Joinpoint = caseLabel;
125
+ while (!(stmt.currentRegion instanceof Switch)) {
126
+ stmt = stmt.parent;
127
+ }
128
+ const caseAncestor = stmt.siblingsLeft.reverse().find(jp => jp instanceof Case);
129
+ return caseAncestor!;
130
+ }
41
131
  }
@@ -1,19 +1,33 @@
1
- import { Break, Joinpoint, Statement, Switch, Case } from "@specs-feup/clava/api/Joinpoints.js";
1
+ import { Break, Joinpoint, Switch, Case } from "@specs-feup/clava/api/Joinpoints.js";
2
2
  import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
- import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
- import { getLastStmtOfCase } from "../../utils/utils.js";
3
+ import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
4
  import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
5
+ import { getLastStmtOfCase } from "../../utils/SwitchUtils.js";
7
6
 
8
7
  /**
9
- * MISRA Rule 16.3: An unconditional break statement shall terminate every switch-clause
8
+ * MISRA-C Rule 16.3: An unconditional break statement shall terminate every switch-clause
10
9
  */
11
10
  export default class Rule_16_3_UnconditionalBreak extends MISRARule {
12
- priority = 2;
13
- #statementsNeedingBreakAfter: Joinpoint[] = [];
11
+ /**
12
+ * Scope of analysis
13
+ */
14
+ readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
14
15
 
15
- constructor(context: MISRAContext) {
16
- super("16.3", context);
16
+ /**
17
+ * A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
18
+ */
19
+ readonly priority = 3;
20
+
21
+ /**
22
+ * List of statements that require a `break` statement as their last sibling
23
+ */
24
+ #statementsNeedingBreakAfter: Joinpoint[] = [];
25
+
26
+ /**
27
+ * @returns Rule identifier according to MISRA-C:2012
28
+ */
29
+ override get name(): string {
30
+ return "16.3";
17
31
  }
18
32
 
19
33
  match($jp: Joinpoint, logErrors: boolean = false): boolean {
@@ -54,7 +68,7 @@ export default class Rule_16_3_UnconditionalBreak extends MISRARule {
54
68
  lastStmt.insertAfter(ClavaJoinPoints.breakStmt());
55
69
  }
56
70
 
57
- transform($jp: Joinpoint): MISRATransformationReport {
71
+ apply($jp: Joinpoint): MISRATransformationReport {
58
72
  if (!this.match($jp))
59
73
  return new MISRATransformationReport(MISRATransformationType.NoChange);
60
74
 
@@ -1,16 +1,22 @@
1
1
  import { Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
2
2
  import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
- import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
3
+ import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
4
  import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
6
- import { getNumOfSwitchClauses, switchHasBooleanCondition, switchHasConditionalBreak } from "../../utils/utils.js";
7
5
 
8
6
  /**
9
- * MISRA Rule 16.4: Every switch statement shall have a default label
7
+ * MISRA-C Rule 16.4: Every switch statement shall have a default label
10
8
  */
11
9
  export default class Rule_16_4_SwitchHasDefault extends MISRARule {
12
- constructor(context: MISRAContext) {
13
- super("16.4", context);
10
+ /**
11
+ * Scope of analysis
12
+ */
13
+ readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
14
+
15
+ /**
16
+ * @returns Rule identifier according to MISRA-C:2012
17
+ */
18
+ override get name(): string {
19
+ return "16.4";
14
20
  }
15
21
 
16
22
  /**
@@ -29,13 +35,16 @@ export default class Rule_16_4_SwitchHasDefault extends MISRARule {
29
35
  return noDefaultCase;
30
36
  }
31
37
 
32
- transform($jp: Joinpoint): MISRATransformationReport {
33
- if (!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
38
+ apply($jp: Joinpoint): MISRATransformationReport {
39
+ if (!this.match($jp))
40
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
34
41
 
35
42
  $jp.children[1].lastChild
36
43
  .insertAfter(ClavaJoinPoints.defaultStmt())
37
44
  .insertAfter(ClavaJoinPoints.emptyStmt())
38
45
  .insertAfter(ClavaJoinPoints.breakStmt());
46
+
47
+ this.context.addRuleResult(this.ruleID, $jp, MISRATransformationType.DescendantChange);
39
48
  return new MISRATransformationReport(MISRATransformationType.DescendantChange);
40
49
  }
41
50
  }
@@ -1,17 +1,22 @@
1
- import {Case, Comment, Joinpoint, Statement, Switch, WrapperStmt } from "@specs-feup/clava/api/Joinpoints.js";
1
+ import {Case, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
2
2
  import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
- import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
- import { isCommentStmt } from "../../utils/utils.js";
3
+ import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
4
+ import { isCommentStmt } from "../../utils/CommentUtils.js";
6
5
 
7
6
  /**
8
- * MISRA Rule 16.5: A default label shall appear as either the first or the last switch label of
9
- a switch statement
7
+ * MISRA-C Rule 16.5: A default label shall appear as either the first or the last switch label of a switch statement
10
8
  */
11
9
  export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
10
+ /**
11
+ * Scope of analysis
12
+ */
13
+ readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
12
14
 
13
- constructor(context: MISRAContext) {
14
- super("16.5", context);
15
+ /**
16
+ * @returns Rule identifier according to MISRA-C:2012
17
+ */
18
+ override get name(): string {
19
+ return "16.5";
15
20
  }
16
21
 
17
22
  /**
@@ -24,7 +29,7 @@ export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
24
29
  private getConsecutiveRightCases($jp: Case): Joinpoint[] {
25
30
  const cases = [];
26
31
  for (const stmt of $jp.siblingsRight) {
27
- if (!(stmt instanceof Case || isCommentStmt($jp)))
32
+ if (!(stmt instanceof Case || isCommentStmt(stmt)))
28
33
  break;
29
34
  cases.push(stmt);
30
35
  }
@@ -67,7 +72,7 @@ export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
67
72
  return false;
68
73
  }
69
74
  if (logErrors) {
70
- this.logMISRAError($jp, "The default case of a switch statement must be the first or last label.")
75
+ this.logMISRAError(currentCase, "The default case of a switch statement must be the first or last label.")
71
76
  }
72
77
  return true;
73
78
  }
@@ -82,8 +87,11 @@ export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
82
87
  * @param $jp - Joinpoint to transform
83
88
  * @returns Report detailing the transformation result
84
89
  */
85
- transform($jp: Joinpoint): MISRATransformationReport {
86
- if (!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
90
+ apply($jp: Joinpoint): MISRATransformationReport {
91
+ const previousResult = $jp instanceof Switch ? this.context.getRuleResult("16.4", $jp) : undefined;
92
+ if (previousResult === MISRATransformationType.DescendantChange || !this.match($jp)) {
93
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
94
+ }
87
95
 
88
96
  const defaultCase = ($jp as Switch).getDefaultCase;
89
97
  const rightStatements = defaultCase.siblingsRight.filter(sibling => !isCommentStmt(sibling));
@@ -1,17 +1,27 @@
1
- import {Break, Case, Joinpoint, Statement, Expression, Switch } from "@specs-feup/clava/api/Joinpoints.js";
1
+ import {Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
2
2
  import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
- import { MISRASwitchConverter, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
- import { getNumOfSwitchClauses, switchHasConditionalBreak } from "../../utils/utils.js";
3
+ import { AnalysisType, MISRASwitchConverter, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
4
+ import { countSwitchClauses, hasConditionalBreak } from "../../utils/SwitchUtils.js";
6
5
 
7
6
  /**
8
- * MISRA Rule 16.6: Every switch statement shall have at least two switch-clauses.
7
+ * MISRA-C Rule 16.6: Every switch statement shall have at least two switch-clauses.
9
8
  */
10
9
  export default class Rule_16_6_SwitchMinTwoClauses extends MISRARule {
11
- priority = 3;
10
+ /**
11
+ * A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
12
+ */
13
+ readonly priority = 5;
12
14
 
13
- constructor(context: MISRAContext) {
14
- super("16.6", context);
15
+ /**
16
+ * Scope of analysis
17
+ */
18
+ readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
19
+
20
+ /**
21
+ * @returns Rule identifier according to MISRA-C:2012
22
+ */
23
+ override get name(): string {
24
+ return "16.6";
15
25
  }
16
26
 
17
27
  /**
@@ -23,7 +33,7 @@ export default class Rule_16_6_SwitchMinTwoClauses extends MISRARule {
23
33
  match($jp: Joinpoint, logErrors: boolean = false): boolean {
24
34
  if (!($jp instanceof Switch)) return false;
25
35
 
26
- const nonCompliant = getNumOfSwitchClauses($jp) < 2;
36
+ const nonCompliant = countSwitchClauses($jp) < 2;
27
37
  if (nonCompliant && logErrors) {
28
38
  this.logMISRAError($jp, "Switch statements should have at least two clauses.")
29
39
  }
@@ -37,11 +47,12 @@ export default class Rule_16_6_SwitchMinTwoClauses extends MISRARule {
37
47
  * @param $jp - Joinpoint to transform
38
48
  * @returns Report detailing the transformation result
39
49
  */
40
- transform($jp: Joinpoint): MISRATransformationReport {
41
- if (!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
50
+ apply($jp: Joinpoint): MISRATransformationReport {
51
+ if (!this.match($jp))
52
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
42
53
 
43
54
  const switchJp = $jp as Switch;
44
- if (switchHasConditionalBreak(switchJp)) {
55
+ if (hasConditionalBreak(switchJp)) {
45
56
  if (switchJp.hasDefaultCase) {
46
57
  this.logMISRAError($jp, "Switch statement must have at least two clauses and cannot be transformed due to a conditional break statement.")
47
58
  }
@@ -1,16 +1,46 @@
1
- import { BuiltinType, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
1
+ import { BinaryOp, BuiltinType, Joinpoint, Switch, UnaryOp } from "@specs-feup/clava/api/Joinpoints.js";
2
2
  import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
- import { MISRASwitchConverter, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
- import { switchHasBooleanCondition, switchHasConditionalBreak } from "../../utils/utils.js";
3
+ import { AnalysisType, MISRASwitchConverter, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
4
+ import { hasConditionalBreak } from "../../utils/SwitchUtils.js";
5
+ import { hasDefinedType } from "../../utils/JoinpointUtils.js";
6
6
 
7
7
  /**
8
- * MISRA Rule 16.7: A switch-expression shall not have essentially Boolean type.
8
+ * MISRA-C Rule 16.7: A switch-expression shall not have essentially Boolean type.
9
9
  */
10
10
  export default class Rule_16_7_NonBooleanSwitchCondition extends MISRARule {
11
- priority = 3;
12
- constructor(context: MISRAContext) {
13
- super("16.7", context);
11
+ /**
12
+ * A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
13
+ */
14
+ readonly priority = 5;
15
+
16
+ /**
17
+ * Scope of analysis
18
+ */
19
+ readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
20
+
21
+ /**
22
+ * @returns Rule identifier according to MISRA-C:2012
23
+ */
24
+ override get name(): string {
25
+ return "16.7";
26
+ }
27
+
28
+ /**
29
+ * Checks if the provided switch statement has a Boolean condition
30
+ * @param switchStmt The switch statement to check
31
+ * @returns Returns true if the switch statement has a Boolean condition, otherwise false
32
+ */
33
+ switchHasBooleanCondition(switchStmt: Switch): boolean {
34
+ const switchCondition = switchStmt.condition;
35
+
36
+ if (switchCondition instanceof BinaryOp || switchCondition instanceof UnaryOp) {
37
+ const logicalOps = new Set(["lt", "gt", "le", "ge", "eq", "ne", "not", "l_not", "and", "or"]);
38
+ return logicalOps.has(switchCondition.kind);
39
+ }
40
+
41
+ return hasDefinedType(switchCondition) &&
42
+ switchCondition.type instanceof BuiltinType &&
43
+ switchCondition.type.builtinKind === "Bool";
14
44
  }
15
45
 
16
46
  /**
@@ -22,9 +52,9 @@ export default class Rule_16_7_NonBooleanSwitchCondition extends MISRARule {
22
52
  match($jp: Joinpoint, logErrors: boolean = false): boolean {
23
53
  if (!($jp instanceof Switch)) return false;
24
54
 
25
- const booleanCondition = switchHasBooleanCondition($jp);
55
+ const booleanCondition = this.switchHasBooleanCondition($jp);
26
56
  if (booleanCondition && logErrors) {
27
- this.logMISRAError($jp, `Switch statement controlling expression ${$jp.condition.code} must not have essentially boolean type.`)
57
+ this.logMISRAError($jp, `Switch statement controlling expression '${$jp.condition.code}' must not have essentially boolean type.`)
28
58
  }
29
59
  return booleanCondition;
30
60
  }
@@ -36,10 +66,11 @@ export default class Rule_16_7_NonBooleanSwitchCondition extends MISRARule {
36
66
  * @param $jp - Joinpoint to transform
37
67
  * @returns Report detailing the transformation result
38
68
  */
39
- transform($jp: Joinpoint): MISRATransformationReport {
40
- if (!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
69
+ apply($jp: Joinpoint): MISRATransformationReport {
70
+ if (!this.match($jp))
71
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
41
72
 
42
- if (switchHasConditionalBreak($jp as Switch)) {
73
+ if (hasConditionalBreak($jp as Switch)) {
43
74
  this.logMISRAError($jp, `The switch statement's controlling expression ${($jp as Switch).condition.code} must not be of a boolean type and cannot be transformed due to a conditional break statement.`)
44
75
  return new MISRATransformationReport(MISRATransformationType.NoChange);
45
76
  }