@specs-feup/clava-misra 1.0.0 → 1.0.2

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 (352) hide show
  1. package/.gitignore +117 -0
  2. package/README.md +70 -15
  3. package/dist/MISRA.d.ts +129 -0
  4. package/dist/MISRA.d.ts.map +1 -0
  5. package/dist/MISRA.js +245 -0
  6. package/dist/MISRA.js.map +1 -0
  7. package/dist/MISRAContext.d.ts +21 -0
  8. package/dist/MISRAContext.d.ts.map +1 -0
  9. package/dist/MISRAContext.js +75 -0
  10. package/dist/MISRAContext.js.map +1 -0
  11. package/dist/MISRARule.d.ts +56 -0
  12. package/dist/MISRARule.d.ts.map +1 -0
  13. package/dist/MISRARule.js +45 -0
  14. package/dist/MISRARule.js.map +1 -0
  15. package/dist/MISRATool.d.ts +12 -0
  16. package/dist/MISRATool.d.ts.map +1 -0
  17. package/dist/MISRATool.js +84 -0
  18. package/dist/MISRATool.js.map +1 -0
  19. package/dist/foo.d.ts +2 -0
  20. package/dist/foo.d.ts.map +1 -0
  21. package/{src/foo.ts → dist/foo.js} +3 -2
  22. package/dist/foo.js.map +1 -0
  23. package/dist/main.d.ts +2 -0
  24. package/dist/main.d.ts.map +1 -0
  25. package/dist/main.js +5 -0
  26. package/dist/main.js.map +1 -0
  27. package/dist/misra/MISRAAnalyser.d.ts +14 -0
  28. package/dist/misra/MISRAAnalyser.d.ts.map +1 -0
  29. package/{src/misra/MISRAAnalyser.ts → dist/misra/MISRAAnalyser.js} +13 -23
  30. package/dist/misra/MISRAAnalyser.js.map +1 -0
  31. package/dist/misra/MISRAPass.d.ts +27 -0
  32. package/dist/misra/MISRAPass.d.ts.map +1 -0
  33. package/dist/misra/MISRAPass.js +60 -0
  34. package/dist/misra/MISRAPass.js.map +1 -0
  35. package/dist/misra/MISRAPassResult.d.ts +13 -0
  36. package/dist/misra/MISRAPassResult.d.ts.map +1 -0
  37. package/dist/misra/MISRAPassResult.js +11 -0
  38. package/dist/misra/MISRAPassResult.js.map +1 -0
  39. package/dist/misra/MISRAReporter.d.ts +20 -0
  40. package/dist/misra/MISRAReporter.d.ts.map +1 -0
  41. package/dist/misra/MISRAReporter.js +43 -0
  42. package/dist/misra/MISRAReporter.js.map +1 -0
  43. package/dist/misra/passes/S10_EssentialTypePass.d.ts +42 -0
  44. package/dist/misra/passes/S10_EssentialTypePass.d.ts.map +1 -0
  45. package/dist/misra/passes/S10_EssentialTypePass.js +370 -0
  46. package/dist/misra/passes/S10_EssentialTypePass.js.map +1 -0
  47. package/dist/misra/passes/S12_ExpressionPass.d.ts +18 -0
  48. package/dist/misra/passes/S12_ExpressionPass.d.ts.map +1 -0
  49. package/dist/misra/passes/S12_ExpressionPass.js +72 -0
  50. package/dist/misra/passes/S12_ExpressionPass.js.map +1 -0
  51. package/dist/misra/passes/S13_SideEffectPass.d.ts +18 -0
  52. package/dist/misra/passes/S13_SideEffectPass.d.ts.map +1 -0
  53. package/dist/misra/passes/S13_SideEffectPass.js +105 -0
  54. package/dist/misra/passes/S13_SideEffectPass.js.map +1 -0
  55. package/dist/misra/passes/S15_ControlFlowPass.d.ts +19 -0
  56. package/dist/misra/passes/S15_ControlFlowPass.d.ts.map +1 -0
  57. package/dist/misra/passes/S15_ControlFlowPass.js +94 -0
  58. package/dist/misra/passes/S15_ControlFlowPass.js.map +1 -0
  59. package/dist/misra/passes/S16_SwitchStatementPass.d.ts +17 -0
  60. package/dist/misra/passes/S16_SwitchStatementPass.d.ts.map +1 -0
  61. package/dist/misra/passes/S16_SwitchStatementPass.js +152 -0
  62. package/dist/misra/passes/S16_SwitchStatementPass.js.map +1 -0
  63. package/dist/misra/passes/S17_FunctionPass.d.ts +12 -0
  64. package/dist/misra/passes/S17_FunctionPass.d.ts.map +1 -0
  65. package/dist/misra/passes/S17_FunctionPass.js +38 -0
  66. package/dist/misra/passes/S17_FunctionPass.js.map +1 -0
  67. package/dist/misra/passes/S18_PointersArraysPass.d.ts +17 -0
  68. package/dist/misra/passes/S18_PointersArraysPass.d.ts.map +1 -0
  69. package/dist/misra/passes/S18_PointersArraysPass.js +115 -0
  70. package/dist/misra/passes/S18_PointersArraysPass.js.map +1 -0
  71. package/dist/misra/passes/S19_OverlappingStoragePass.d.ts +11 -0
  72. package/dist/misra/passes/S19_OverlappingStoragePass.d.ts.map +1 -0
  73. package/dist/misra/passes/S19_OverlappingStoragePass.js +20 -0
  74. package/dist/misra/passes/S19_OverlappingStoragePass.js.map +1 -0
  75. package/dist/misra/passes/S21_StandardLibPass.d.ts +20 -0
  76. package/dist/misra/passes/S21_StandardLibPass.d.ts.map +1 -0
  77. package/dist/misra/passes/S21_StandardLibPass.js +77 -0
  78. package/dist/misra/passes/S21_StandardLibPass.js.map +1 -0
  79. package/dist/misra/passes/S3_CommentPass.d.ts +12 -0
  80. package/dist/misra/passes/S3_CommentPass.d.ts.map +1 -0
  81. package/dist/misra/passes/S3_CommentPass.js +27 -0
  82. package/dist/misra/passes/S3_CommentPass.js.map +1 -0
  83. package/dist/misra/passes/S5_IdentifierPass.d.ts +13 -0
  84. package/dist/misra/passes/S5_IdentifierPass.d.ts.map +1 -0
  85. package/dist/misra/passes/S5_IdentifierPass.js +60 -0
  86. package/dist/misra/passes/S5_IdentifierPass.js.map +1 -0
  87. package/dist/misra/passes/S6_TypePass.d.ts +11 -0
  88. package/dist/misra/passes/S6_TypePass.d.ts.map +1 -0
  89. package/dist/misra/passes/S6_TypePass.js +25 -0
  90. package/dist/misra/passes/S6_TypePass.js.map +1 -0
  91. package/dist/misra/passes/S7_LiteralsConstantsPass.d.ts +14 -0
  92. package/dist/misra/passes/S7_LiteralsConstantsPass.d.ts.map +1 -0
  93. package/dist/misra/passes/S7_LiteralsConstantsPass.js +71 -0
  94. package/dist/misra/passes/S7_LiteralsConstantsPass.js.map +1 -0
  95. package/dist/misra/passes/S8_DeclDefPass.d.ts +18 -0
  96. package/dist/misra/passes/S8_DeclDefPass.d.ts.map +1 -0
  97. package/dist/misra/passes/S8_DeclDefPass.js +127 -0
  98. package/dist/misra/passes/S8_DeclDefPass.js.map +1 -0
  99. package/dist/misra/sections/Section10_EssentialTypeModel.d.ts +33 -0
  100. package/dist/misra/sections/Section10_EssentialTypeModel.d.ts.map +1 -0
  101. package/{src/misra/sections/Section10_EssentialTypeModel.ts → dist/misra/sections/Section10_EssentialTypeModel.js} +58 -73
  102. package/dist/misra/sections/Section10_EssentialTypeModel.js.map +1 -0
  103. package/dist/misra/sections/Section11_PointerTypeConversions.d.ts +12 -0
  104. package/dist/misra/sections/Section11_PointerTypeConversions.d.ts.map +1 -0
  105. package/{src/misra/sections/Section11_PointerTypeConversions.ts → dist/misra/sections/Section11_PointerTypeConversions.js} +16 -27
  106. package/dist/misra/sections/Section11_PointerTypeConversions.js.map +1 -0
  107. package/dist/misra/sections/Section12_Expressions.d.ts +15 -0
  108. package/dist/misra/sections/Section12_Expressions.d.ts.map +1 -0
  109. package/dist/misra/sections/Section12_Expressions.js +70 -0
  110. package/dist/misra/sections/Section12_Expressions.js.map +1 -0
  111. package/dist/misra/sections/Section13_SideEffects.d.ts +14 -0
  112. package/dist/misra/sections/Section13_SideEffects.d.ts.map +1 -0
  113. package/dist/misra/sections/Section13_SideEffects.js +90 -0
  114. package/dist/misra/sections/Section13_SideEffects.js.map +1 -0
  115. package/dist/misra/sections/Section14_ControlStmtExprs.d.ts +8 -0
  116. package/dist/misra/sections/Section14_ControlStmtExprs.d.ts.map +1 -0
  117. package/{src/misra/sections/Section14_ControlStmtExprs.ts → dist/misra/sections/Section14_ControlStmtExprs.js} +8 -10
  118. package/dist/misra/sections/Section14_ControlStmtExprs.js.map +1 -0
  119. package/dist/misra/sections/Section15_ControlFlow.d.ts +14 -0
  120. package/dist/misra/sections/Section15_ControlFlow.d.ts.map +1 -0
  121. package/dist/misra/sections/Section15_ControlFlow.js +97 -0
  122. package/dist/misra/sections/Section15_ControlFlow.js.map +1 -0
  123. package/dist/misra/sections/Section16_SwitchStatements.d.ts +13 -0
  124. package/dist/misra/sections/Section16_SwitchStatements.d.ts.map +1 -0
  125. package/{src/misra/sections/Section16_SwitchStatements.ts → dist/misra/sections/Section16_SwitchStatements.js} +49 -74
  126. package/dist/misra/sections/Section16_SwitchStatements.js.map +1 -0
  127. package/dist/misra/sections/Section17_Functions.d.ts +9 -0
  128. package/dist/misra/sections/Section17_Functions.d.ts.map +1 -0
  129. package/{src/misra/sections/Section17_Functions.ts → dist/misra/sections/Section17_Functions.js} +10 -13
  130. package/dist/misra/sections/Section17_Functions.js.map +1 -0
  131. package/dist/misra/sections/Section18_PointersAndArrays.d.ts +13 -0
  132. package/dist/misra/sections/Section18_PointersAndArrays.d.ts.map +1 -0
  133. package/{src/misra/sections/Section18_PointersAndArrays.ts → dist/misra/sections/Section18_PointersAndArrays.js} +36 -40
  134. package/dist/misra/sections/Section18_PointersAndArrays.js.map +1 -0
  135. package/dist/misra/sections/Section19_OverlappingStorage.d.ts +8 -0
  136. package/dist/misra/sections/Section19_OverlappingStorage.d.ts.map +1 -0
  137. package/dist/misra/sections/Section19_OverlappingStorage.js +16 -0
  138. package/dist/misra/sections/Section19_OverlappingStorage.js.map +1 -0
  139. package/dist/misra/sections/Section20_PreprocessingDirectives.d.ts +8 -0
  140. package/dist/misra/sections/Section20_PreprocessingDirectives.d.ts.map +1 -0
  141. package/{src/misra/sections/Section20_PreprocessingDirectives.ts → dist/misra/sections/Section20_PreprocessingDirectives.js} +7 -9
  142. package/dist/misra/sections/Section20_PreprocessingDirectives.js.map +1 -0
  143. package/dist/misra/sections/Section21_StandardLibraries.d.ts +17 -0
  144. package/dist/misra/sections/Section21_StandardLibraries.d.ts.map +1 -0
  145. package/dist/misra/sections/Section21_StandardLibraries.js +54 -0
  146. package/dist/misra/sections/Section21_StandardLibraries.js.map +1 -0
  147. package/dist/misra/sections/Section2_UnusedCode.d.ts +9 -0
  148. package/dist/misra/sections/Section2_UnusedCode.d.ts.map +1 -0
  149. package/{src/misra/sections/Section2_UnusedCode.ts → dist/misra/sections/Section2_UnusedCode.js} +11 -16
  150. package/dist/misra/sections/Section2_UnusedCode.js.map +1 -0
  151. package/dist/misra/sections/Section3_Comments.d.ts +9 -0
  152. package/dist/misra/sections/Section3_Comments.d.ts.map +1 -0
  153. package/{src/misra/sections/Section3_Comments.ts → dist/misra/sections/Section3_Comments.js} +7 -10
  154. package/dist/misra/sections/Section3_Comments.js.map +1 -0
  155. package/dist/misra/sections/Section5_Identifiers.d.ts +12 -0
  156. package/dist/misra/sections/Section5_Identifiers.d.ts.map +1 -0
  157. package/dist/misra/sections/Section5_Identifiers.js +139 -0
  158. package/dist/misra/sections/Section5_Identifiers.js.map +1 -0
  159. package/dist/misra/sections/Section6_Types.d.ts +8 -0
  160. package/dist/misra/sections/Section6_Types.d.ts.map +1 -0
  161. package/dist/misra/sections/Section6_Types.js +23 -0
  162. package/dist/misra/sections/Section6_Types.js.map +1 -0
  163. package/dist/misra/sections/Section7_LiteralsConstants.d.ts +11 -0
  164. package/dist/misra/sections/Section7_LiteralsConstants.d.ts.map +1 -0
  165. package/{src/misra/sections/Section7_LiteralsConstants.ts → dist/misra/sections/Section7_LiteralsConstants.js} +18 -25
  166. package/dist/misra/sections/Section7_LiteralsConstants.js.map +1 -0
  167. package/dist/misra/sections/Section8_DeclarationsDefinitions.d.ts +15 -0
  168. package/dist/misra/sections/Section8_DeclarationsDefinitions.d.ts.map +1 -0
  169. package/{src/misra/sections/Section8_DeclarationsDefinitions.ts → dist/misra/sections/Section8_DeclarationsDefinitions.js} +18 -33
  170. package/dist/misra/sections/Section8_DeclarationsDefinitions.js.map +1 -0
  171. package/dist/misra/tests/utils.d.ts +10 -0
  172. package/dist/misra/tests/utils.d.ts.map +1 -0
  173. package/dist/misra/tests/utils.js +33 -0
  174. package/dist/misra/tests/utils.js.map +1 -0
  175. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts +15 -0
  176. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts.map +1 -0
  177. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js +33 -0
  178. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js.map +1 -0
  179. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts +16 -0
  180. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts.map +1 -0
  181. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js +60 -0
  182. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js.map +1 -0
  183. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts +19 -0
  184. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts.map +1 -0
  185. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js +42 -0
  186. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js.map +1 -0
  187. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts +43 -0
  188. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts.map +1 -0
  189. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js +103 -0
  190. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js.map +1 -0
  191. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts +26 -0
  192. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts.map +1 -0
  193. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js +49 -0
  194. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js.map +1 -0
  195. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts +26 -0
  196. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts.map +1 -0
  197. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js +49 -0
  198. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js.map +1 -0
  199. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts +31 -0
  200. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts.map +1 -0
  201. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js +71 -0
  202. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js.map +1 -0
  203. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts +27 -0
  204. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts.map +1 -0
  205. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js +58 -0
  206. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js.map +1 -0
  207. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts +28 -0
  208. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts.map +1 -0
  209. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js +44 -0
  210. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js.map +1 -0
  211. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.d.ts +55 -0
  212. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.d.ts.map +1 -0
  213. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.js +108 -0
  214. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.js.map +1 -0
  215. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts +43 -0
  216. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts.map +1 -0
  217. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js +68 -0
  218. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js.map +1 -0
  219. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts +29 -0
  220. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts.map +1 -0
  221. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js +53 -0
  222. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js.map +1 -0
  223. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts +15 -0
  224. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts.map +1 -0
  225. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js +35 -0
  226. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js.map +1 -0
  227. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts +13 -0
  228. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts.map +1 -0
  229. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js +53 -0
  230. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js.map +1 -0
  231. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts +13 -0
  232. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts.map +1 -0
  233. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js +32 -0
  234. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js.map +1 -0
  235. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.d.ts +10 -0
  236. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.d.ts.map +1 -0
  237. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.js +26 -0
  238. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.js.map +1 -0
  239. package/dist/rules/index.d.ts +20 -0
  240. package/dist/rules/index.d.ts.map +1 -0
  241. package/dist/rules/index.js +38 -0
  242. package/dist/rules/index.js.map +1 -0
  243. package/dist/tests/Section17_Functions/misra_config.json +10 -0
  244. package/dist/tests/utils.d.ts +10 -0
  245. package/dist/tests/utils.d.ts.map +1 -0
  246. package/dist/tests/utils.js +29 -0
  247. package/dist/tests/utils.js.map +1 -0
  248. package/dist/utils/utils.d.ts +102 -0
  249. package/dist/utils/utils.d.ts.map +1 -0
  250. package/dist/utils/utils.js +202 -0
  251. package/dist/utils/utils.js.map +1 -0
  252. package/jest.config.js +6 -6
  253. package/package.json +44 -8
  254. package/src/MISRA.ts +276 -0
  255. package/src/MISRAContext.ts +84 -0
  256. package/src/MISRARule.ts +64 -0
  257. package/src/MISRATool.ts +95 -0
  258. package/src/main.ts +4 -33
  259. package/src/misra-old/MISRAAnalyser.ts +60 -0
  260. package/src/misra-old/MISRAAnalyserResult.ts +16 -0
  261. package/src/misra-old/sections/Section10_EssentialTypeModel.ts +377 -0
  262. package/src/misra-old/sections/Section11_PointerTypeConversions.ts +104 -0
  263. package/src/{misra → misra-old}/sections/Section12_Expressions.ts +7 -7
  264. package/src/{misra → misra-old}/sections/Section13_SideEffects.ts +15 -15
  265. package/src/misra-old/sections/Section14_ControlStmtExprs.ts +27 -0
  266. package/src/{misra → misra-old}/sections/Section15_ControlFlow.ts +10 -10
  267. package/src/misra-old/sections/Section18_PointersAndArrays.ts +108 -0
  268. package/src/{misra → misra-old}/sections/Section19_OverlappingStorage.ts +4 -4
  269. package/src/misra-old/sections/Section20_PreprocessingDirectives.ts +22 -0
  270. package/src/misra-old/sections/Section21_StandardLibraries.ts +99 -0
  271. package/src/{misra → misra-old}/sections/Section5_Identifiers.ts +16 -15
  272. package/src/{misra → misra-old}/sections/Section6_Types.ts +4 -4
  273. package/src/misra-old/sections/Section7_LiteralsConstants.ts +76 -0
  274. package/src/misra-old/sections/Section8_DeclarationsDefinitions.ts +133 -0
  275. package/src/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.ts +41 -0
  276. package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +70 -0
  277. package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +41 -0
  278. package/src/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.ts +113 -0
  279. package/src/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.ts +61 -0
  280. package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +57 -0
  281. package/src/rules/Section17_Functions/Rule_17_3_ImplicitFunction.ts +180 -0
  282. package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +91 -0
  283. package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +68 -0
  284. package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +49 -0
  285. package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +120 -0
  286. package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +78 -0
  287. package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +61 -0
  288. package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +47 -0
  289. package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +67 -0
  290. package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +41 -0
  291. package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +36 -0
  292. package/src/rules/index.ts +44 -0
  293. package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +55 -0
  294. package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +70 -0
  295. package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +128 -0
  296. package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +132 -0
  297. package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +146 -0
  298. package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +102 -0
  299. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions.test.ts +79 -0
  300. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +98 -0
  301. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +77 -0
  302. package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -0
  303. package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +44 -0
  304. package/src/tests/Section17_Functions/misra_config.json +19 -0
  305. package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +175 -0
  306. package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +219 -0
  307. package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +49 -0
  308. package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +55 -0
  309. package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -0
  310. package/src/tests/utils.ts +51 -0
  311. package/src/utils/utils.ts +280 -0
  312. package/tsconfig.json +4 -3
  313. package/typedoc.config.js +1 -1
  314. package/CxxSources/lib.cpp +0 -3
  315. package/CxxSources/lib.h +0 -8
  316. package/CxxSources/main.cpp +0 -40
  317. package/TODO.md +0 -1
  318. package/consumer_order.txt +0 -2
  319. package/enum_integer_type.txt +0 -0
  320. package/is_temporary.txt +0 -0
  321. package/omp.txt +0 -0
  322. package/src/misra/passes/S16_SwitchStatementPass.ts +0 -168
  323. package/src/misra/passes/S3_CommentPass.ts +0 -40
  324. package/src/misra/sections/Section21_StandardLibraries.ts +0 -65
  325. package/src/misra/tests/S10_EssentialTypes.test.ts +0 -253
  326. package/src/misra/tests/S12_Expressions.test.ts +0 -43
  327. package/src/misra/tests/S13_SideEffects.test.ts +0 -77
  328. package/src/misra/tests/S15_ControlFlow.test.ts +0 -144
  329. package/src/misra/tests/S16_SwitchStatements.test.ts +0 -164
  330. package/src/misra/tests/S17_Functions.test.ts +0 -46
  331. package/src/misra/tests/S18_PointersArrays.test.ts +0 -167
  332. package/src/misra/tests/S19_OverlappingStorage.test.ts +0 -38
  333. package/src/misra/tests/S3_Comments.test.ts +0 -36
  334. package/src/misra/tests/S6_Types.test.ts +0 -36
  335. package/src/misra/tests/S7_LiteralsConstants.test.ts +0 -48
  336. package/src/misra/tests/utils.ts +0 -47
  337. package/types_with_templates.txt +0 -0
  338. /package/src/{misra → misra-old}/MISRAPass.ts +0 -0
  339. /package/src/{misra → misra-old}/MISRAPassResult.ts +0 -0
  340. /package/src/{misra → misra-old}/MISRAReporter.ts +0 -0
  341. /package/src/{misra → misra-old}/passes/S10_EssentialTypePass.ts +0 -0
  342. /package/src/{misra → misra-old}/passes/S12_ExpressionPass.ts +0 -0
  343. /package/src/{misra → misra-old}/passes/S13_SideEffectPass.ts +0 -0
  344. /package/src/{misra → misra-old}/passes/S15_ControlFlowPass.ts +0 -0
  345. /package/src/{misra → misra-old}/passes/S17_FunctionPass.ts +0 -0
  346. /package/src/{misra → misra-old}/passes/S18_PointersArraysPass.ts +0 -0
  347. /package/src/{misra → misra-old}/passes/S19_OverlappingStoragePass.ts +0 -0
  348. /package/src/{misra → misra-old}/passes/S21_StandardLibPass.ts +0 -0
  349. /package/src/{misra → misra-old}/passes/S5_IdentifierPass.ts +0 -0
  350. /package/src/{misra → misra-old}/passes/S6_TypePass.ts +0 -0
  351. /package/src/{misra → misra-old}/passes/S7_LiteralsConstantsPass.ts +0 -0
  352. /package/src/{misra → misra-old}/passes/S8_DeclDefPass.ts +0 -0
@@ -0,0 +1,68 @@
1
+ import { AdjustedType, ArrayType, FunctionJp, Joinpoint, Param } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
5
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
+ import { getParamReferences } from "../../utils/utils.js";
7
+
8
+ /**
9
+ * MISRA Rule 17.6: The declaration of an array parameter shall not contain the static keyword between the [ ]
10
+ */
11
+ export default class Rule_17_6_StaticArraySizeParam extends MISRARule {
12
+ #invalidParams: Param[] = [];
13
+ constructor(context: MISRAContext) {
14
+ super("17.6", context);
15
+ }
16
+
17
+ /**
18
+ * Checks if the given joinpoint represents a function with any array parameter containing the 'static' keyword between the [ ].
19
+ *
20
+ * @param $jp - Joinpoint to analyze
21
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
22
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
23
+ */
24
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
25
+ if (!($jp instanceof FunctionJp) || $jp.root.standard === "c90") return false;
26
+
27
+ this.#invalidParams = $jp.params.filter(paramJp => paramJp.type instanceof AdjustedType &&
28
+ paramJp.type.originalType instanceof ArrayType &&
29
+ paramJp.type.originalType.arraySize !== -1 &&
30
+ /\[\s*static\s+\d+\s*\]/.test(paramJp.code)
31
+ );
32
+
33
+ if (logErrors) {
34
+ for (const invalidParam of this.#invalidParams) {
35
+ this.logMISRAError(invalidParam, `The 'static' keyword cannot appear inside the square brackets ('[]') in array parameter declarations.`)
36
+ }
37
+ }
38
+ return this.#invalidParams.length > 0;
39
+ }
40
+
41
+ /**
42
+ * Transforms the joinpoint if it represents a function with any array parameter containing the 'static' keyword between the square brackets.
43
+ *
44
+ * @param $jp - Joinpoint to transform
45
+ * @returns Report detailing the transformation result
46
+ */
47
+ transform($jp: Joinpoint): MISRATransformationReport {
48
+ if (!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
49
+
50
+ for (const invalidParam of this.#invalidParams) {
51
+ const paramRefs = getParamReferences(invalidParam, $jp);
52
+
53
+ // Replace the parameter with a new array parameter whose size is variant
54
+ const originalType = (invalidParam.type as AdjustedType).originalType;
55
+ const newJp = ClavaJoinPoints.param(
56
+ invalidParam.name,
57
+ ClavaJoinPoints.incompleteArrayType((originalType as ArrayType).elementType)
58
+ );
59
+ const newParam = invalidParam.replaceWith(newJp) as Param;
60
+
61
+ // Replace all references to the invalid parameter with the new one
62
+ for (const ref of paramRefs) {
63
+ ref.replaceWith(newParam.varref());
64
+ }
65
+ }
66
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
67
+ }
68
+ }
@@ -0,0 +1,49 @@
1
+ import { BuiltinType, Call, ExprStmt, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
5
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
+ import { isCallToImplicitFunction } from "../../utils/utils.js";
7
+
8
+ /**
9
+ * MISRA Rule 17.7: The value returned by a function having non-void return type shall be
10
+ used
11
+ */
12
+ export default class Rule_17_7_UnusedReturnValue extends MISRARule {
13
+ constructor(context: MISRAContext) {
14
+ super("17.7", context);
15
+ }
16
+
17
+ /**
18
+ * Checks if the given joinpoint represents a non-void function call with an unused return value.
19
+ *
20
+ * @param $jp - Joinpoint to analyze
21
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
22
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
23
+ */
24
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
25
+ if (!($jp instanceof Call)) return false;
26
+
27
+ if ($jp.returnType instanceof BuiltinType && $jp.returnType.isVoid) return false;
28
+
29
+ if ($jp.parent instanceof ExprStmt && logErrors) {
30
+ this.logMISRAError($jp,`Return value of ${$jp.signature} must be used. It can be discarded with an explicit cast to void.`);
31
+ }
32
+ return $jp.parent instanceof ExprStmt;
33
+ }
34
+
35
+ /**
36
+ * Transforms the joinpoint if it represents a non-void function call, whose return type is unused.
37
+ * It ensures that the return value is explicitly cast to void.
38
+ *
39
+ * @param $jp - Joinpoint to transform
40
+ * @returns Report detailing the transformation result
41
+ */
42
+ transform($jp: Joinpoint): MISRATransformationReport {
43
+ if (!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
44
+
45
+ const callJp = $jp as Call;
46
+ const newJp = ClavaJoinPoints.cStyleCast(ClavaJoinPoints.type("void"), callJp);
47
+ return new MISRATransformationReport(MISRATransformationType.Replacement, $jp.replaceWith(newJp));
48
+ }
49
+ }
@@ -0,0 +1,120 @@
1
+ import { FileJp, Include, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
6
+ import * as path from 'path';
7
+
8
+ /**
9
+ * MISRA Rule 20.2: The ', " or \ characters and the /* or // character sequences shall not occur in a header filename
10
+ */
11
+ export default class Rule_20_2_InvalidHeaderFileName extends MISRARule {
12
+ constructor(context: MISRAContext) {
13
+ super("20.2", context);
14
+ }
15
+
16
+ /**
17
+ * Checks if the given joinpoint is a header file whose name includes invalid characters.
18
+ *
19
+ * @param $jp - Joinpoint to analyze
20
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
21
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
22
+ */
23
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
24
+ if (!($jp instanceof FileJp && $jp.isHeader)) return false;
25
+
26
+ const isNonCompliant = /.*('|"|\\|\/\*|\/\/).*/.test($jp.name);
27
+ if (isNonCompliant && logErrors) {
28
+ this.logMISRAError($jp, `Invalid characters in header filename. Invalid characters are ', ", \\, and the sequences /* and //.`)
29
+ }
30
+ return isNonCompliant;
31
+ }
32
+
33
+ /**
34
+ * Renames a header file to ensure it contains only valid characters and updates all related includes accordingly.
35
+ *
36
+ * @param $jp - Joinpoint to transform
37
+ * @returns Report detailing the transformation result
38
+ */
39
+ transform($jp: Joinpoint): MISRATransformationReport {
40
+ if (!this.match($jp)) {
41
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
42
+ }
43
+
44
+ const fileJp = $jp as FileJp;
45
+ const includesOfHeader = this.getMatchingIncludes(fileJp);
46
+ const newFilename = this.context.generateHeaderFilename();
47
+
48
+ fileJp.setName(newFilename);
49
+ this.updateIncludes(includesOfHeader, newFilename);
50
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
51
+ }
52
+
53
+ /**
54
+ * Finds all include joinpoints that reference a specific header file
55
+ *
56
+ * @param headerFileJp - The header file joinpoint
57
+ * @returns List of matching include statements
58
+ */
59
+ private getMatchingIncludes(headerFileJp: FileJp): Include[] {
60
+ return Query.search(Include).get().filter(includeJp =>
61
+ path.basename(includeJp.name) === headerFileJp.name &&
62
+ this.getHeaderFilePath(includeJp) === headerFileJp.path);
63
+ }
64
+
65
+ /**
66
+ * Computes the full path to the header file based on the include statement
67
+ *
68
+ * @param includeJp The include joinpoint
69
+ * @returns Resolved path to the header file
70
+ */
71
+ private getHeaderFilePath(includeJp: Include): string {
72
+ try {
73
+ if (includeJp.name.startsWith("../")) {
74
+ return includeJp.relativeFolderpath;
75
+ } else {
76
+ const relativeDir = path.dirname(includeJp.name);
77
+ const fileJp = includeJp.getAncestor("file") as FileJp | undefined;
78
+ return path.resolve(fileJp!.path, relativeDir);
79
+ }
80
+ } catch (error) {
81
+ return "";
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Updates the provided include joinpoints to reference the new header file name
87
+ *
88
+ * @param includesOfHeader List of include joinpoints to update
89
+ * @param newFilename The new filename for the header file
90
+ */
91
+ private updateIncludes(includesOfHeader: Include[], newFilename: string): void {
92
+ for (const includeJp of includesOfHeader) {
93
+ const fileJp = includeJp.getAncestor("file") as FileJp | undefined;
94
+
95
+ const newIncludeJpName = this.getNewIncludeName(includeJp, newFilename);
96
+ fileJp!.addInclude(newIncludeJpName);
97
+
98
+ const tempInclude = Query.searchFrom(fileJp!, Include, {name: includeName => path.normalize(includeName) === newIncludeJpName}).first();
99
+
100
+ if (tempInclude) {
101
+ includeJp.replaceWith(tempInclude.deepCopy());
102
+ tempInclude.detach();
103
+ }
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Computes the new include path with the updated header file name
109
+ *
110
+ * @param includeJp - Original include statement
111
+ * @param newHeaderFileName - New header file name
112
+ * @returns The updated include path
113
+ */
114
+ private getNewIncludeName(includeJp: Include, newHeaderFileName: string): string {
115
+ const isFile = path.extname(includeJp.name) !== '';
116
+ const baseDir = isFile ? path.dirname(includeJp.name) : includeJp.name;
117
+
118
+ return path.join(baseDir, newHeaderFileName);
119
+ }
120
+ }
@@ -0,0 +1,78 @@
1
+ import { EnumDecl, Joinpoint,RecordJp,TypedefDecl, TypedefType } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
+ import { getBaseType, getTagUses, getTypeDecl, getTypedJps } from "../../utils/utils.js";
6
+
7
+ /**
8
+ * MISRA-C Rule 2.3: A project should not contain unused type declarations.
9
+ */
10
+ export default class Rule_2_3_UnusedTypeDecl extends MISRARule {
11
+ priority = 3;
12
+
13
+ constructor(context: MISRAContext) {
14
+ super("2.3", context);
15
+ }
16
+
17
+ /**
18
+ * Checks if a given joinpoint uses the specified typedef declaration.
19
+ * @param jp - The joinpoint to check
20
+ * @param typeDecl - The typedef declaration to check against
21
+ * @returns Returns true if the joinpoint uses the given typedef declaration, false otherwise
22
+ */
23
+ private isTypedefUsed(jp: Joinpoint, typeDecl: TypedefDecl): boolean {
24
+ const jpType = getBaseType(jp);
25
+ return !jpType?.isBuiltin && jpType instanceof TypedefType && jpType.decl.astId === typeDecl.astId;
26
+ }
27
+
28
+ /**
29
+ * Retrieves all joinpoints that use the specified typedef declaration
30
+ *
31
+ * @param typeDecl - The typedef declaration to search for in the joinpoints
32
+ * @returns Array of joinpoints that use the given typedef declaration
33
+ */
34
+ private getTypeDefUses(typeDecl: TypedefDecl): Joinpoint[] {
35
+ return getTypedJps().filter(jp => this.isTypedefUsed(jp, typeDecl));
36
+ }
37
+
38
+ /**
39
+ * Checks if the given joinpoint represents an unused type declaration
40
+ * @param $jp - Joinpoint to analyze
41
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
42
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
43
+ */
44
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
45
+ const typeDecl = getTypeDecl($jp);
46
+ if (typeDecl === undefined) return false;
47
+
48
+ const isUnused = this.getTypeDefUses(typeDecl).length === 0;
49
+ if (logErrors && isUnused) {
50
+ this.logMISRAError($jp, `Type declaration ${typeDecl.name} is declared but not used.`)
51
+ }
52
+ return isUnused;
53
+ }
54
+
55
+ /**
56
+ * Transforms the joinpoint if it represents an unused type declaration
57
+ *
58
+ * - If the joinpoint defines a tag (named struct, enum or union) that is referenced elsewhere in the code,
59
+ * the joinpoint is replaced by the tag
60
+ * - Otherwise, the joinpoint is simply removed from the AST
61
+ *
62
+ * @param $jp - Joinpoint to transform
63
+ * @returns Report detailing the transformation result
64
+ */
65
+ transform($jp: Joinpoint): MISRATransformationReport {
66
+ if (!this.match($jp))
67
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
68
+
69
+ if (($jp instanceof RecordJp || $jp instanceof EnumDecl) && $jp.name && getTagUses($jp).length > 0) {
70
+ $jp.lastChild.detach();
71
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
72
+ } else {
73
+ $jp.detach();
74
+ return new MISRATransformationReport(MISRATransformationType.Removal);
75
+ }
76
+
77
+ }
78
+ }
@@ -0,0 +1,61 @@
1
+ import { Joinpoint, RecordJp, EnumDecl, TagType, ElaboratedType } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
+ import { getTagUses, hasTypeDecl } from "../../utils/utils.js";
6
+
7
+ /**
8
+ * MISRA-C Rule 2.4: A project should not contain unused tag declarations.
9
+ */
10
+ export default class Rule_2_4_UnusedTagDecl extends MISRARule {
11
+ priority = 3;
12
+
13
+ constructor(context: MISRAContext) {
14
+ super("2.4", context);
15
+ }
16
+
17
+ /**
18
+ * Checks if the given joinpoint is an unused tag declaration
19
+ * A tag is considered to be unused if it has no references in the code or is only used within a typedef
20
+ *
21
+ * @param $jp - Joinpoint to analyze
22
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
23
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
24
+ */
25
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
26
+ if (!($jp instanceof RecordJp || $jp instanceof EnumDecl)) return false;
27
+
28
+ const containsTypeDecl = hasTypeDecl($jp);
29
+ const jpName = $jp.name;
30
+ if (containsTypeDecl && jpName === undefined || jpName === null || (jpName as string).trim().length === 0) {
31
+ return false;
32
+ }
33
+
34
+ const isUnused = getTagUses($jp).length === 0;
35
+ if (isUnused && logErrors) {
36
+ this.logMISRAError($jp,
37
+ containsTypeDecl ? `The tag '${$jp.name}' is declared but only used in a typedef.` : `The tag '${$jp.name}' is declared but not used.`);
38
+ }
39
+ return isUnused;
40
+ }
41
+
42
+ /**
43
+ * Transforms the joinpoint if it is an unused tag declaration
44
+ * - If the joinpoint is a tag declared in a typedef, it removes the name.
45
+ * - Otherwise, the joinpoint is detached.
46
+ *
47
+ * @param $jp - Joinpoint to transform
48
+ * @returns Report detailing the transformation result
49
+ */
50
+ transform($jp: Joinpoint): MISRATransformationReport {
51
+ if (!this.match($jp))
52
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
53
+
54
+ if (hasTypeDecl($jp)) {
55
+ ($jp as RecordJp | EnumDecl).setName('');
56
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
57
+ }
58
+ $jp.detach();
59
+ return new MISRATransformationReport(MISRATransformationType.Removal);
60
+ }
61
+ }
@@ -0,0 +1,47 @@
1
+ import { GotoStmt, FunctionJp, Joinpoint, LabelStmt } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
5
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
+
7
+ /**
8
+ * Rule 2.6: Unused Labels.
9
+ * Checks for labels within a function that are not used.
10
+ */
11
+ export default class Rule_2_6_UnusedLabels extends MISRARule {
12
+ priority = 3;
13
+
14
+ constructor(context: MISRAContext) {
15
+ super("2.6", context);
16
+ }
17
+
18
+ private getUnusedLabels(func: FunctionJp): LabelStmt[] {
19
+ return Query.searchFrom(func, LabelStmt).get().filter(label =>
20
+ Query.searchFrom(func, GotoStmt, { label: jp => jp.astId === label.decl.astId }).get().length === 0
21
+ );
22
+ }
23
+
24
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
25
+ if (!($jp instanceof FunctionJp))
26
+ return false;
27
+
28
+ const unusedLabels = this.getUnusedLabels($jp);
29
+ if (logErrors) {
30
+ unusedLabels.forEach(label =>
31
+ this.logMISRAError(label, `Label ${label.decl.name} is unused in function ${$jp.name}.`)
32
+ )
33
+ }
34
+ return unusedLabels.length > 0;
35
+ }
36
+
37
+ transform($jp: Joinpoint): MISRATransformationReport {
38
+ if(!this.match($jp))
39
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
40
+
41
+ const unusedLabels = this.getUnusedLabels($jp as FunctionJp);
42
+ for (const label of unusedLabels) {
43
+ label.detach();
44
+ }
45
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
46
+ }
47
+ }
@@ -0,0 +1,67 @@
1
+ import { FunctionJp, Joinpoint, Param, Varref, Call } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
5
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
+ import { getParamReferences } from "../../utils/utils.js";
7
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
8
+
9
+ export default class Rule_2_7_UnusedParameters extends MISRARule {
10
+ priority = 3;
11
+
12
+ constructor(context: MISRAContext) {
13
+ super("2.7", context);
14
+ }
15
+
16
+ private getUnusedParams(func: FunctionJp): Param[] {
17
+ return func.params.filter(param => getParamReferences(param, func).length === 0);
18
+ }
19
+
20
+ private getUsedParams(func: FunctionJp): Param[] {
21
+ return func.params.filter(param => getParamReferences(param, func).length > 0);
22
+ }
23
+
24
+ private getUsedParamsPositions(func: FunctionJp): number[] {
25
+ let result = [];
26
+ for (let i = 0; i < func.params.length; i++) {
27
+ const param = func.params[i];
28
+ if (Query.searchFrom(func, Varref, { decl: jp => jp?.astId === param.astId }).get().length > 0) {
29
+ result.push(i);
30
+ }
31
+ }
32
+ return result;
33
+ }
34
+
35
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
36
+ if (!($jp instanceof FunctionJp && $jp.isImplementation)) return false;
37
+
38
+ const unusedParams = this.getUnusedParams($jp);
39
+ if (logErrors) {
40
+ unusedParams.forEach(param =>
41
+ this.logMISRAError(param, `Parameter '${param.name}' is unused in function ${$jp.name}.`)
42
+ )
43
+ }
44
+ return unusedParams.length > 0;
45
+ }
46
+
47
+ transform($jp: Joinpoint): MISRATransformationReport {
48
+ if(!this.match($jp)) return new MISRATransformationReport(MISRATransformationType.NoChange);
49
+
50
+ const functionJp = $jp as FunctionJp;
51
+ const usedParams = this.getUsedParams(functionJp);
52
+ const usedParamsPositions = this.getUsedParamsPositions(functionJp);
53
+ const calls = Query.search(Call, {function: jp => jp.astId === $jp.astId}).get();
54
+
55
+ functionJp.setParams(usedParams);
56
+ for (const funcDecl of functionJp.declarationJps) {
57
+ funcDecl.setParams(usedParams);
58
+ }
59
+
60
+ for (const call of calls) {
61
+ const newArgs = usedParamsPositions.map(i => call.args[i]);
62
+ const newCall = functionJp.newCall(newArgs)
63
+ call.replaceWith(newCall);
64
+ }
65
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
66
+ }
67
+ }
@@ -0,0 +1,41 @@
1
+ import { Comment, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import { isInlineComment, getComments } from "../../utils/utils.js";
5
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
+
7
+ /**
8
+ * MISRA Rule 3.1:
9
+ */
10
+ export default class Rule_3_1_CommentSequences extends MISRARule {
11
+
12
+ constructor(context: MISRAContext) {
13
+ super("3.1", context);
14
+ }
15
+
16
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
17
+ const invalidComments = getComments($jp).filter(comment =>
18
+ (isInlineComment(comment) && /(\/\*)/g.test(comment.text)) ||
19
+ (!isInlineComment(comment) && /(\/\/|\/\*)/g.test(comment.text)));
20
+
21
+ if (logErrors) {
22
+ invalidComments.forEach(comment =>
23
+ this.logMISRAError(comment, `Comment \'${comment.text}\' contains invalid character sequences.`)
24
+ )
25
+ }
26
+ return invalidComments.length > 0;
27
+ }
28
+
29
+ transform($jp: Joinpoint): MISRATransformationReport {
30
+ if (!this.match($jp))
31
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
32
+
33
+ const comments = getComments($jp);
34
+ for (const comment of comments) {
35
+ const invalidSymbols = isInlineComment(comment) ? /(\/\*)/g : /(\/\/|\/\*)/g;
36
+ const newText = comment.text.replace(invalidSymbols, '');
37
+ comment.setText(newText);
38
+ }
39
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);;
40
+ }
41
+ }
@@ -0,0 +1,36 @@
1
+ import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import MISRAContext from "../../MISRAContext.js";
4
+ import { isInlineComment, getComments } from "../../utils/utils.js";
5
+ import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
+
7
+ export default class Rule_3_2_LineSplicing extends MISRARule {
8
+
9
+ constructor(context: MISRAContext) {
10
+ super("3.2", context);
11
+ }
12
+
13
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
14
+ const invalidComments = getComments($jp).filter(comment =>
15
+ (isInlineComment(comment) && /\/\n/g.test(comment.text)));
16
+
17
+ if (logErrors) {
18
+ invalidComments.forEach(comment =>
19
+ this.logMISRAError(comment, `Comment ${comment.text} contains invalid character sequences.`)
20
+ )
21
+ }
22
+ return invalidComments.length > 0;
23
+ }
24
+
25
+ transform($jp: Joinpoint): MISRATransformationReport {
26
+ if (!this.match($jp))
27
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
28
+
29
+ const comments = getComments($jp);
30
+ for (const comment of comments) {
31
+ const newText = comment.text.replace(/\/\n/g, '');
32
+ comment.setText(newText);
33
+ }
34
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
35
+ }
36
+ }
@@ -0,0 +1,44 @@
1
+ import MISRAContext from "../MISRAContext.js";
2
+ import MISRARule from "../MISRARule.js";
3
+ import Rule_16_2_TopLevelSwitch from "./Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js";
4
+ import Rule_16_3_UnconditionalBreak from "./Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js";
5
+ import Rule_16_4_SwitchHasDefault from "./Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js";
6
+ import Rule_16_5_DefaultFirstOrLast from "./Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js";
7
+ import Rule_16_6_SwitchMinTwoClauses from "./Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js";
8
+ import Rule_16_7_NonBooleanSwitchCondition from "./Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js";
9
+ import Rule_17_3_ImplicitFunction from "./Section17_Functions/Rule_17_3_ImplicitFunction.js";
10
+ import Rule_17_4_NonVoidReturn from "./Section17_Functions/Rule_17_4_NonVoidReturn.js";
11
+ import Rule_17_6_StaticArraySizeParam from "./Section17_Functions/Rule_17_6_StaticArraySizeParam.js";
12
+ import Rule_17_7_UnusedReturnValue from "./Section17_Functions/Rule_17_7_UnusedReturnValue.js";
13
+ import Rule_2_3_UnusedTypeDecl from "./Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js";
14
+ import Rule_2_4_UnusedTagDecl from "./Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js";
15
+ import Rule_2_6_UnusedLabels from "./Section2_UnusedCode/Rule_2_6_UnusedLabels.js";
16
+ import Rule_2_7_UnusedParameters from "./Section2_UnusedCode/Rule_2_7_UnusedParameters.js";
17
+ import Rule_3_1_CommentSequences from "./Section3_Comments/Rule_3_1_CommentSequences.js";
18
+ import Rule_3_2_CommentSequences from "./Section3_Comments/Rule_3_2_LineSplicing.js";
19
+
20
+ export function sortRules(context: MISRAContext) {
21
+
22
+ const rules: MISRARule[] = [
23
+ new Rule_2_3_UnusedTypeDecl(context),
24
+ new Rule_2_4_UnusedTagDecl(context),
25
+ new Rule_2_6_UnusedLabels(context),
26
+ new Rule_2_7_UnusedParameters(context),
27
+ new Rule_3_1_CommentSequences(context),
28
+ new Rule_3_2_CommentSequences(context),
29
+ new Rule_16_2_TopLevelSwitch(context),
30
+ new Rule_16_3_UnconditionalBreak(context),
31
+ new Rule_16_4_SwitchHasDefault(context),
32
+ new Rule_16_5_DefaultFirstOrLast(context),
33
+ new Rule_16_6_SwitchMinTwoClauses(context),
34
+ new Rule_16_7_NonBooleanSwitchCondition(context),
35
+ new Rule_17_3_ImplicitFunction(context),
36
+ new Rule_17_4_NonVoidReturn(context),
37
+ new Rule_17_6_StaticArraySizeParam(context),
38
+ new Rule_17_7_UnusedReturnValue(context),
39
+ ];
40
+
41
+ return rules.sort((ruleA, ruleB) => ruleA.priority - ruleB.priority);
42
+ }
43
+
44
+ export default sortRules;
@@ -0,0 +1,55 @@
1
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
2
+ import { countErrorsAfterCorrection, countMISRAErrors, registerSourceCode, TestFile } from "../utils.js";
3
+ import { FileJp } from "@specs-feup/clava/api/Joinpoints.js";
4
+
5
+ const passingCode =
6
+ `void foo1( void ) {
7
+ int x, y;
8
+ switch ( x )
9
+ {
10
+ case 1:
11
+ if ( y == 1 ) {
12
+ x = 1;
13
+ }
14
+ break;
15
+ default:
16
+ break;
17
+ }
18
+ }`;
19
+
20
+ const failingCode =
21
+ `void foo2( void ) {
22
+ int x, y;
23
+ switch ( x )
24
+ {
25
+ case 1: /* Compliant */
26
+ if ( y == 1 )
27
+ {
28
+ case 2: /* Non-compliant */
29
+ x = 1;
30
+ }
31
+ break;
32
+ default:
33
+ break;
34
+ }
35
+ }`;
36
+
37
+ const files: TestFile[] = [
38
+ { name: "bad.c", code: failingCode },
39
+ { name: "good.c", code: passingCode }
40
+ ];
41
+
42
+ describe("Rule 16.2", () => {
43
+ registerSourceCode(files);
44
+
45
+ it("should detect errors in bad.c", () => {
46
+ expect(countMISRAErrors()).toBe(1);
47
+
48
+ expect(countMISRAErrors(Query.search(FileJp, {name: "bad.c"}).first()!)).toBe(1);
49
+ expect(countMISRAErrors(Query.search(FileJp, {name: "good.c"}).first()!)).toBe(0);
50
+ });
51
+
52
+ it("should correct errors in bad.c", () => {
53
+ expect(countErrorsAfterCorrection()).toBe(0);
54
+ });
55
+ });