@specs-feup/clava-misra 1.0.0 → 1.0.1

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 (350) 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 +40 -8
  254. package/src/MISRA.ts +266 -0
  255. package/src/MISRAContext.ts +91 -0
  256. package/src/MISRARule.ts +77 -0
  257. package/src/MISRATool.ts +96 -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 +40 -0
  276. package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +69 -0
  277. package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +46 -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 +57 -0
  280. package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +56 -0
  281. package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +78 -0
  282. package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +68 -0
  283. package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +47 -0
  284. package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +120 -0
  285. package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +75 -0
  286. package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +60 -0
  287. package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +46 -0
  288. package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +65 -0
  289. package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +41 -0
  290. package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +36 -0
  291. package/src/rules/index.ts +40 -0
  292. package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +55 -0
  293. package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +70 -0
  294. package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +128 -0
  295. package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +132 -0
  296. package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +146 -0
  297. package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +102 -0
  298. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +85 -0
  299. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +77 -0
  300. package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -0
  301. package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +44 -0
  302. package/src/tests/Section17_Functions/misra_config.json +10 -0
  303. package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +175 -0
  304. package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +219 -0
  305. package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +49 -0
  306. package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +55 -0
  307. package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -0
  308. package/src/tests/utils.ts +39 -0
  309. package/src/utils/utils.ts +221 -0
  310. package/tsconfig.json +4 -3
  311. package/typedoc.config.js +1 -1
  312. package/CxxSources/lib.cpp +0 -3
  313. package/CxxSources/lib.h +0 -8
  314. package/CxxSources/main.cpp +0 -40
  315. package/TODO.md +0 -1
  316. package/consumer_order.txt +0 -2
  317. package/enum_integer_type.txt +0 -0
  318. package/is_temporary.txt +0 -0
  319. package/omp.txt +0 -0
  320. package/src/misra/passes/S16_SwitchStatementPass.ts +0 -168
  321. package/src/misra/passes/S3_CommentPass.ts +0 -40
  322. package/src/misra/sections/Section21_StandardLibraries.ts +0 -65
  323. package/src/misra/tests/S10_EssentialTypes.test.ts +0 -253
  324. package/src/misra/tests/S12_Expressions.test.ts +0 -43
  325. package/src/misra/tests/S13_SideEffects.test.ts +0 -77
  326. package/src/misra/tests/S15_ControlFlow.test.ts +0 -144
  327. package/src/misra/tests/S16_SwitchStatements.test.ts +0 -164
  328. package/src/misra/tests/S17_Functions.test.ts +0 -46
  329. package/src/misra/tests/S18_PointersArrays.test.ts +0 -167
  330. package/src/misra/tests/S19_OverlappingStorage.test.ts +0 -38
  331. package/src/misra/tests/S3_Comments.test.ts +0 -36
  332. package/src/misra/tests/S6_Types.test.ts +0 -36
  333. package/src/misra/tests/S7_LiteralsConstants.test.ts +0 -48
  334. package/src/misra/tests/utils.ts +0 -47
  335. package/types_with_templates.txt +0 -0
  336. /package/src/{misra → misra-old}/MISRAPass.ts +0 -0
  337. /package/src/{misra → misra-old}/MISRAPassResult.ts +0 -0
  338. /package/src/{misra → misra-old}/MISRAReporter.ts +0 -0
  339. /package/src/{misra → misra-old}/passes/S10_EssentialTypePass.ts +0 -0
  340. /package/src/{misra → misra-old}/passes/S12_ExpressionPass.ts +0 -0
  341. /package/src/{misra → misra-old}/passes/S13_SideEffectPass.ts +0 -0
  342. /package/src/{misra → misra-old}/passes/S15_ControlFlowPass.ts +0 -0
  343. /package/src/{misra → misra-old}/passes/S17_FunctionPass.ts +0 -0
  344. /package/src/{misra → misra-old}/passes/S18_PointersArraysPass.ts +0 -0
  345. /package/src/{misra → misra-old}/passes/S19_OverlappingStoragePass.ts +0 -0
  346. /package/src/{misra → misra-old}/passes/S21_StandardLibPass.ts +0 -0
  347. /package/src/{misra → misra-old}/passes/S5_IdentifierPass.ts +0 -0
  348. /package/src/{misra → misra-old}/passes/S6_TypePass.ts +0 -0
  349. /package/src/{misra → misra-old}/passes/S7_LiteralsConstantsPass.ts +0 -0
  350. /package/src/{misra → misra-old}/passes/S8_DeclDefPass.ts +0 -0
package/src/MISRA.ts ADDED
@@ -0,0 +1,266 @@
1
+ import { BinaryOp, Break, Case, Expression, If, Joinpoint, Scope, Statement, Switch } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import { getNumOfSwitchClauses, isCommentStmt } from "./utils/utils.js";
3
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
4
+
5
+ export enum MISRATransformationType {
6
+ NoChange,
7
+ DescendantChange,
8
+ Replacement,
9
+ Removal
10
+ }
11
+
12
+ /**
13
+ * Represents an error in MISRA compliance, including the rule ID, the joinpoint where the violation occurred, and a descriptive message.
14
+ */
15
+ export class MISRAError {
16
+ /**
17
+ * Represents the specific MISRA rule that was violated
18
+ */
19
+ public ruleID: string;
20
+ /**
21
+ * The joinpoint where the error was detected
22
+ */
23
+ public $jp: Joinpoint;
24
+ /**
25
+ * Explanation of the violation
26
+ */
27
+ public message: string;
28
+
29
+ /**
30
+ *
31
+ * @param ruleID - specific MISRA rule that was violated
32
+ * @param $jp - joinpoint where the error was detected
33
+ * @param message - description of the error
34
+ */
35
+ constructor(ruleID: string, $jp: Joinpoint, message: string) {
36
+ this.ruleID = ruleID;
37
+ this.$jp = $jp;
38
+ this.message = message;
39
+ }
40
+
41
+ /**
42
+ * Checks if two instances of MISRAError are equal based on all properties
43
+ * @param other
44
+ * @returns Returns `true` if the errors are the same, `false` otherwise
45
+ */
46
+ equals(other: MISRAError): boolean {
47
+ return this.ruleID === other.ruleID &&
48
+ this.$jp.astId === other.$jp.astId &&
49
+ this.message === other.message;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * A report of a MISRA transformation, including the transformation type and an optional new joinpoint node.
55
+ *
56
+ * If the transformation type is `Replacement`, the `newNode` must be provided to indicate the new joinpoint.
57
+ */
58
+ export class MISRATransformationReport {
59
+ /**
60
+ * The type of the MISRA transformation
61
+ */
62
+ type: MISRATransformationType;
63
+ /**
64
+ * An optional new joinpoint node, provided if the transformation involves a replacement
65
+ */
66
+ newNode?: Joinpoint;
67
+
68
+ /**
69
+ *
70
+ * @param type The type of the MISRA transformation
71
+ * @param newNode The new joinpoint node resulting from the transformation. Required if the transformation type is `Replacement`.
72
+ */
73
+ constructor(type: MISRATransformationType, newNode?: Joinpoint) {
74
+ this.type = type;
75
+ if (type === MISRATransformationType.Replacement && !newNode) {
76
+ throw new Error("newNode must be provided when a 'Replacement' transformation is performed");
77
+ }
78
+ this.newNode = newNode;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Converts a switch statement into either consecutive statements or if statements
84
+ * - If the switch has only one clause and a default case, it is converted to consecutive statements
85
+ * - Otherwise, it is converted to if statements
86
+ */
87
+ export class MISRASwitchConverter {
88
+ /**
89
+ * Converts a switch statement to consecutive statements or if statements
90
+ *
91
+ * @param switchStmt - The switch statement to convert
92
+ * @returns The converted statements or `undefined` if no statements remain
93
+ */
94
+ static convert(switchStmt: Switch): Statement | undefined {
95
+ if (switchStmt.hasDefaultCase && getNumOfSwitchClauses(switchStmt) < 2) { // The statements will always be executed
96
+ return this.convertToConsecutiveStmts(switchStmt);
97
+ } else {
98
+ return this.convertToIfStatements(switchStmt);
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Converts a switch with only one clause and a default case into consecutive statements
104
+ *
105
+ * @param switchStmt - The switch statement to convert
106
+ * @returns The first statement or `undefined` if no statements remain
107
+ */
108
+ static convertToConsecutiveStmts(switchStmt: Switch): Statement | undefined {
109
+ const scope = switchStmt.children[1] as Scope;
110
+ this.removeBreakStmts(scope);
111
+ this.removeCases(scope);
112
+
113
+ // If there are no statements except break and comments, the switch can be removed
114
+ if (scope.children.length === 0 || scope.children.every(stmt => isCommentStmt(stmt))) {
115
+ switchStmt.detach();
116
+ return undefined;
117
+ }
118
+
119
+ let firstStmt, lastStmt;
120
+ const stmts = scope.children as Statement[];
121
+ for (let i = 0; i < stmts.length; i++) {
122
+ const stmt = stmts[i];
123
+ stmt.detach();
124
+
125
+ if (!firstStmt) {
126
+ firstStmt = stmt;
127
+ switchStmt.replaceWith(firstStmt);
128
+ lastStmt = stmt;
129
+ continue;
130
+ }
131
+ lastStmt!.insertAfter(stmt);
132
+ lastStmt = stmt;
133
+ }
134
+ return firstStmt as Statement;
135
+ }
136
+
137
+ /**
138
+ * Converts a switch statement into a series of if statements
139
+ *
140
+ * @param switchStmt - The switch statement to convert
141
+ * @returns The first if statement created
142
+ */
143
+ static convertToIfStatements(switchStmt: Switch): If {
144
+ const scope = switchStmt.children[1] as Scope;
145
+ const consecutiveCases = this.consecutiveCases(switchStmt);
146
+ this.removeBreakStmts(scope);
147
+
148
+ let ifStmt: If;
149
+ let lastIfStmt: If | undefined;
150
+ for (let i = 0; i < consecutiveCases.length; i++) {
151
+ const cases = consecutiveCases[i];
152
+
153
+ if (cases.some(caseStmt => caseStmt.isDefault)) { // Has default case
154
+ lastIfStmt!.setElse(ClavaJoinPoints.scope(...cases[cases.length-1].instructions));
155
+ } else {
156
+ lastIfStmt = this.createIfStatement(switchStmt.condition, cases, i, lastIfStmt)
157
+ if (i === 0) {
158
+ ifStmt = lastIfStmt;
159
+ }
160
+ }
161
+ }
162
+ switchStmt.replaceWith(ifStmt!);
163
+ return ifStmt!;
164
+ }
165
+
166
+ /**
167
+ * Creates an if statement for the given consecutive cases
168
+ *
169
+ * @param condition - The switch condition
170
+ * @param cases - A list of consecutive cases
171
+ * @param index - The index of the current case group
172
+ * @param lastIfStmt - The last if statement, used to chain else
173
+ * @returns The new if statement
174
+ */
175
+ private static createIfStatement(condition: Expression, cases: Case[], index: number, lastIfStmt: If | undefined): If {
176
+ const conditionExpr = this.equivalentCondition(condition, cases);
177
+ const thenBody = ClavaJoinPoints.scope(...cases[cases.length - 1].instructions);
178
+ const newIfStmt = ClavaJoinPoints.ifStmt(conditionExpr, thenBody);
179
+
180
+ if (index === 0) {
181
+ return newIfStmt;
182
+ } else {
183
+ lastIfStmt!.setElse(newIfStmt);
184
+ return newIfStmt;
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Creates the equivalent condition for an if statement based on the case values
190
+ *
191
+ * @param condition - The switch condition
192
+ * @param cases - A list of case` statements
193
+ * @returns The combined condition
194
+ */
195
+ private static equivalentCondition(condition: Expression, cases: Case[]): Expression {
196
+ let lastBinaryOp: BinaryOp;
197
+
198
+ for (let i = 0; i < cases.length; i++) {
199
+ const caseStmt = cases[i];
200
+ const newBinaryOp = ClavaJoinPoints.binaryOp("==", condition, caseStmt.values[0]);
201
+
202
+ if (i === 0) {
203
+ lastBinaryOp = newBinaryOp;
204
+ continue;
205
+ }
206
+ lastBinaryOp = ClavaJoinPoints.binaryOp("||", lastBinaryOp!, newBinaryOp);
207
+ }
208
+ return lastBinaryOp!;
209
+ }
210
+
211
+ /**
212
+ * Removes all break statements from the given scope
213
+ * @param scope - The scope from which the break statements will be removed
214
+ */
215
+ private static removeBreakStmts(scope: Scope) {
216
+ const breakStmts = scope.children.filter(child => child instanceof Break);
217
+ breakStmts.forEach(stmt => stmt.detach());
218
+ }
219
+
220
+ /**
221
+ * Removes all case statements from the given scope
222
+ * @param scope - The scope from which the case statements will be removed
223
+ */
224
+ private static removeCases(scope: Scope) {
225
+ const cases = scope.children.filter(child => child instanceof Case);
226
+ cases.forEach(caseStmt => caseStmt.detach());
227
+ }
228
+
229
+ /**
230
+ * Groups case statements into consecutive blocks, ensuring the block with the default case is last
231
+ *
232
+ * @param switchStmt - The switch statement
233
+ * @returns The grouped case statements
234
+ */
235
+ private static consecutiveCases(switchStmt: Switch): Case[][] {
236
+ let caseGroups: Case[][] = [];
237
+ let currentList: Case[] = [];
238
+
239
+ for (const caseStmt of switchStmt.cases) {
240
+ currentList.push(caseStmt);
241
+
242
+ if (caseStmt.instructions.length !== 0) { // Has no consecutive case
243
+ caseGroups.push(currentList);
244
+ currentList = [];
245
+ }
246
+ }
247
+
248
+ // Ensure the block containing the default case is placed at the last position
249
+ return this.organizeCaseGroups(caseGroups);
250
+ }
251
+
252
+ /**
253
+ * Organizes case groups such that the group with default case is placed last.
254
+ *
255
+ * @param caseGroups - The groups of case statements
256
+ * @returns The organized case groups
257
+ */
258
+ private static organizeCaseGroups(caseGroups: Case[][]): Case[][] {
259
+ const nonDefaultGroups = caseGroups.filter(block => !block.some(caseStmt => caseStmt.isDefault));
260
+ const defaultBlock = caseGroups.find(block => block.some(caseStmt => caseStmt.isDefault));
261
+ if (defaultBlock) {
262
+ nonDefaultGroups.push(defaultBlock);
263
+ }
264
+ return nonDefaultGroups;
265
+ }
266
+ }
@@ -0,0 +1,91 @@
1
+ import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import { MISRAError } from "./MISRA.js";
3
+ import * as fs from 'fs';
4
+
5
+ /**
6
+ * Tracks MISRA errors and warnings during the analysis and/or transformation of the code.
7
+ * Also generated unique variable and function names.
8
+ */
9
+ export default class MISRAContext {
10
+ /**
11
+ * List of MISRA errors, that could not be resolved during the transformation process
12
+ */
13
+ #misraErrors: MISRAError[] = [];
14
+ /**
15
+ * List of MISRA warnings generated by transformations that may alter the program's behavior
16
+ */
17
+ #misraWarnings: MISRAError[] = [];
18
+
19
+ /**
20
+ * Configuration provided by the user to assist in rule corrections
21
+ */
22
+ #config: Map<string, any> | undefined = undefined;
23
+
24
+ #varCounter = 0;
25
+ #funcCounter = 0;
26
+ #headerCounter = 0;
27
+
28
+ #varPrefix = "__misra_var_";
29
+ #funcPrefix = "__misra_func_";
30
+ #headerPrefix = "misra_hdr_";
31
+
32
+ get errors(): MISRAError[] {
33
+ return this.#misraErrors;
34
+ }
35
+
36
+ get warnings(): MISRAError[] {
37
+ return this.#misraWarnings;
38
+ }
39
+
40
+ get config(): Map<string, any> | undefined {
41
+ return this.#config;
42
+ }
43
+
44
+ set config(configFilePath: string) {
45
+ if (fs.existsSync(configFilePath)) {
46
+ const data = fs.readFileSync(configFilePath, 'utf-8');
47
+ this.#config = new Map(Object.entries(JSON.parse(data)));
48
+ } else {
49
+ console.error(`[Clava-MISRATool] Provided configuration file was not found.`);
50
+ process.exit(1);
51
+ }
52
+ }
53
+
54
+ generateVarName() {
55
+ return `${this.#varPrefix}${this.#varCounter++}`;
56
+ }
57
+
58
+ generateFuncName() {
59
+ return `${this.#funcPrefix}${this.#funcCounter++}`;
60
+ }
61
+
62
+ generateHeaderFilename() {
63
+ return `${this.#headerPrefix}${this.#headerCounter++}.h`;
64
+ }
65
+
66
+ addMISRAError(ruleID: string, $jp: Joinpoint, message: string) {
67
+ const newError = new MISRAError(ruleID, $jp, message);
68
+
69
+ if (!this.#misraErrors.some(error => error.equals(newError))) {
70
+ this.#misraErrors.push(newError);
71
+ }
72
+ }
73
+
74
+ addMISRAWarning(ruleID: string, $jp: Joinpoint, message: string) {
75
+ const newWarning = new MISRAError(ruleID, $jp, message);
76
+
77
+ if (!this.#misraWarnings.some(warning => warning.equals(newWarning))) {
78
+ this.#misraWarnings.push(newWarning);
79
+ }
80
+ }
81
+
82
+ printErrors() {
83
+ this.#misraErrors.forEach(error => console.log(error.message));
84
+ console.log('\n');
85
+ }
86
+
87
+ printWarnings() {
88
+ this.#misraWarnings.forEach(warning => console.log(warning.message));
89
+ console.log('\n');
90
+ }
91
+ }
@@ -0,0 +1,77 @@
1
+ import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRAContext from "./MISRAContext.js";
3
+ import { MISRATransformationReport } from "./MISRA.js";
4
+
5
+ /**
6
+ * Represents a MISRA Rule that detects and corrects violations in the code according to MISRA standards.
7
+ *
8
+ * Need to implement:
9
+ * - match($jp, logErrors)
10
+ * - transform($jp)
11
+ */
12
+ export default abstract class MISRARule {
13
+ /**
14
+ * Unique identifier for the MISRA rule.
15
+ */
16
+ readonly ruleID: string;
17
+
18
+ /**
19
+ * MISRA context for error tracking and rule transformations state
20
+ */
21
+ protected context: MISRAContext;
22
+
23
+ /**
24
+ *
25
+ * @param ruleID - Unique identifier for the MISRA-C rule
26
+ * @param context - MISRA context for error tracking and rule transformations state
27
+ */
28
+ constructor(ruleID: string, context: MISRAContext) {
29
+ this.ruleID = ruleID;
30
+ this.context = context;
31
+ }
32
+
33
+ /**
34
+ * Checks if the joinpoint violates the rule
35
+ *
36
+ * @param $jp - Joinpoint to analyze
37
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
38
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
39
+ */
40
+ abstract match($jp: Joinpoint, logErrors: boolean): boolean;
41
+
42
+ /**
43
+ * Transforms the joinpoint to comply with the MISRA-C rule
44
+ *
45
+ * @param $jp - Joinpoint to transform
46
+ * @returns Report detailing the transformation result
47
+ */
48
+ abstract transform($jp: Joinpoint): MISRATransformationReport;
49
+
50
+ /**
51
+ * Logs a MISRA-C rule violation error
52
+ *
53
+ * @param $jp - The joinpoint where the violation occurred
54
+ * @param msg - Description of the violation
55
+ */
56
+ protected logMISRAError($jp: Joinpoint, msg:string): void {
57
+ this.context.addMISRAError(
58
+ this.ruleID,
59
+ $jp,
60
+ `MISRA-C Rule ${this.ruleID} violation at ${$jp.filepath}@${$jp.line}:${$jp.column}: ${msg}`
61
+ )
62
+ }
63
+
64
+ /**
65
+ * Logs a warning from automatic MISRA-C correction, which may change the program's behavior
66
+ *
67
+ * @param $jp - The joinpoint where the correction was applied
68
+ * @param msg - Description of the warning
69
+ */
70
+ protected logMISRAWarning($jp: Joinpoint, msg:string): void {
71
+ this.context.addMISRAWarning(
72
+ this.ruleID,
73
+ $jp,
74
+ `Warning: MISRA-C Rule ${this.ruleID} correction at ${$jp.filepath}@${$jp.line}:${$jp.column}: ${msg}.`
75
+ )
76
+ }
77
+ }
@@ -0,0 +1,96 @@
1
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
2
+ import { FileJp, Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
3
+ import MISRARule from "./MISRARule.js";
4
+ import misraRules from "./rules/index.js";
5
+ import MISRAContext from "./MISRAContext.js";
6
+ import { MISRAError, MISRATransformationType } from "./MISRA.js";
7
+
8
+ export default class MISRATool {
9
+ static #misraRules: MISRARule[];
10
+ static #context: MISRAContext;
11
+
12
+ private static init(startingPoint: FileJp | Program) {
13
+ this.validateStdVersion(startingPoint);
14
+ this.#context = new MISRAContext();
15
+ this.#misraRules = misraRules(this.#context);
16
+ }
17
+
18
+ private static validateStdVersion(startingPoint: FileJp | Program) {
19
+ const allowedVersions = ["c90", "c99", "c11"];
20
+ const stdVersion = startingPoint instanceof Program ? startingPoint.standard : (startingPoint.root as Program).standard;
21
+
22
+ if (!allowedVersions.includes(stdVersion)) {
23
+ console.error(`[Clava-MISRATool] Invalid --std value. Allowed values: ${allowedVersions.join(", ")}`);
24
+ process.exit(1);
25
+ }
26
+ }
27
+
28
+ public static checkCompliance(startingPoint: Program | FileJp = Query.root() as Program) {
29
+ this.init(startingPoint);
30
+
31
+ const nodes = startingPoint.descendants;
32
+ for (const node of nodes) {
33
+ for (const rule of this.#misraRules) {
34
+ rule.match(node, true);
35
+ }
36
+ }
37
+ if (this.#context.errors.length > 0) {
38
+ this.#context.printErrors();
39
+ } else {
40
+ console.log("[Clava-MISRATool] No MISRA-C violations detected.");
41
+ }
42
+ }
43
+
44
+ public static applyCorrections(configFilePath?: string, startingPoint: Program | FileJp = Query.root() as Program) {
45
+ this.init(startingPoint);
46
+ if (configFilePath) {
47
+ this.#context.config = configFilePath;
48
+ }
49
+
50
+ let iteration = 0;
51
+ let modified = false;
52
+ do {
53
+ console.log(`[Clava-MISRATool] Iteration #${++iteration}: Applying MISRA-C transformations...`);
54
+ modified = this.transformAST(startingPoint);
55
+ } while(modified);
56
+
57
+ if (this.#context.errors.length === 0 && this.#context.warnings.length === 0) {
58
+ console.log("[Clava-MISRATool] All detected violations were corrected.");
59
+ } else {
60
+ if (this.#context.warnings.length > 0) {
61
+ console.log("\n[Clava-MISRATool] Warnings from automatic MISRA-C corrections (these may change the program's behavior):");
62
+ this.#context.printWarnings();
63
+ }
64
+ if (this.#context.errors.length > 0) {
65
+ console.log("\n[Clava-MISRATool] Remaining MISRA-C violations:");
66
+ this.#context.printErrors();
67
+ }
68
+ }
69
+ }
70
+
71
+ private static transformAST($jp: Joinpoint): boolean {
72
+ let modified = false;
73
+
74
+ for (const rule of this.#misraRules) {
75
+ const transformReport = rule.transform($jp);
76
+
77
+ if (transformReport.type !== MISRATransformationType.NoChange) {
78
+ modified = true;
79
+ if (transformReport.type === MISRATransformationType.Removal)
80
+ return modified;
81
+ else if (transformReport.type === MISRATransformationType.Replacement)
82
+ $jp = transformReport.newNode as Joinpoint;
83
+ }
84
+ }
85
+
86
+ for (const child of $jp.children) {
87
+ if (this.transformAST(child))
88
+ modified = true;
89
+ }
90
+ return modified;
91
+ }
92
+
93
+ public static getMISRAErrors(): MISRAError[] {
94
+ return this.#context.errors;
95
+ }
96
+ }
package/src/main.ts CHANGED
@@ -1,36 +1,7 @@
1
- import Query from "@specs-feup/lara/api/weaver/Query.js";
2
- import { FunctionJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
3
- import { foo } from "./foo.js";
4
- import S16_SwitchStatementPass from "./misra/passes/S16_SwitchStatementPass.js";
5
- import S15_ControlFlowPass from "./misra/passes/S15_ControlFlowPass.js";
6
- import MISRAReporter from "./misra/MISRAReporter.js";
7
- import S10_EssentialTypePass from "./misra/passes/S10_EssentialTypePass.js";
8
- import AggregatePassResult from "@specs-feup/lara/api/lara/pass/results/AggregatePassResult.js";
9
- import MISRAPassResult from "./misra/MISRAPassResult.js";
10
- import S12_ExpressionPass from "./misra/passes/S12_ExpressionPass.js";
11
- import S17_FunctionPass from "./misra/passes/S17_FunctionPass.js";
12
- import S13_SideEffectPass from "./misra/passes/S13_SideEffectPass.js";
13
- import S18_PointersArraysPass from "./misra/passes/S18_PointersArraysPass.js";
14
-
15
1
  import VisualizationTool from "@specs-feup/clava-visualization/api/VisualizationTool.js";
2
+ import MISRATool from "./MISRATool.js";
16
3
 
17
- const pass = new S16_SwitchStatementPass(true, [1, 6, 7]);
18
- const reporter = new MISRAReporter();
19
-
20
- console.log(Query.root().dump);
21
-
22
- const result = reporter.applyPass(
23
- pass,
24
- Query.root() as Joinpoint
25
- ) as AggregatePassResult;
26
- if (result) {
27
- result.results.forEach((res) => {
28
- const reports = (res as MISRAPassResult).reports;
29
- console.log(reports);
30
- //reports.forEach(rep => rep.fix?.execute());
31
- });
32
- }
33
-
34
- console.log("GADASDSAD");
4
+ MISRATool.checkCompliance();
5
+ MISRATool.applyCorrections();
35
6
 
36
- await VisualizationTool.visualize();
7
+ //await VisualizationTool.visualize();
@@ -0,0 +1,60 @@
1
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
2
+ import Analyser from "@specs-feup/clava/api/clava/analysis/Analyser.js";
3
+ import AnalyserResult from "@specs-feup/clava/api/clava/analysis/AnalyserResult.js";
4
+ import { FileJp, Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import ResultFormatManager from "@specs-feup/clava/api/clava/analysis/ResultFormatManager.js"
6
+ import Fix from "@specs-feup/clava/api/clava/analysis/Fix.js";
7
+ import MISRAAnalyserResult from "./MISRAAnalyserResult.js";
8
+
9
+ type T = Program | FileJp;
10
+
11
+ export default abstract class MISRAAnalyser extends Analyser {
12
+ #selectedRules: string[];
13
+ #results: AnalyserResult[] = [];
14
+ #resultFormatManager = new ResultFormatManager();
15
+ protected currentRule: string = "";
16
+ protected abstract ruleMapper: Map<string, (jp: T) => void>;
17
+
18
+ constructor(rules?: string[]) {
19
+ super();
20
+ this.#selectedRules = rules ?? [];
21
+ }
22
+
23
+ public addSelectedRule(ruleID: string) {
24
+ this.#selectedRules.push(ruleID);
25
+ }
26
+
27
+ public setSelectedRules(rules: string[]) {
28
+ this.#selectedRules = rules;
29
+ }
30
+
31
+ protected logMISRAError(ruleID: string, jp: Joinpoint, message: string, fix?: Fix) {
32
+ this.#results.push(
33
+ new MISRAAnalyserResult(
34
+ ruleID,
35
+ `MISRA Rule ${ruleID} violation at ${jp?.filename}@${jp?.line}:${jp?.column}`, jp, message, fix
36
+ )
37
+ );
38
+ }
39
+
40
+ analyse($startNode: T = Query.root() as Program) {
41
+ if (this.#selectedRules.length === 0) {
42
+ this.setSelectedRules(Array.from(this.ruleMapper.keys()));
43
+ }
44
+
45
+ for (const rule of this.#selectedRules) {
46
+ this.currentRule = rule;
47
+ const rulePass = this.ruleMapper.get(rule);
48
+ if (rulePass) {
49
+ rulePass($startNode);
50
+ }
51
+ else {
52
+ throw new Error("Analyser doesn't support rule number " + rule);
53
+ }
54
+ }
55
+
56
+ this.#resultFormatManager.setAnalyserResultList(this.#results);
57
+ const fileResult = this.#resultFormatManager.formatResultList($startNode);
58
+ return fileResult;
59
+ }
60
+ }
@@ -0,0 +1,16 @@
1
+ import AnalyserResult from "@specs-feup/clava/api/clava/analysis/AnalyserResult.js";
2
+ import Fix from "@specs-feup/clava/api/clava/analysis/Fix.js";
3
+ import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
4
+
5
+ export default class MISRAAnalyserResult extends AnalyserResult {
6
+ private violatedRule: string;
7
+
8
+ constructor(rule:string, name: string, node: Joinpoint, message: string, fix?: Fix) {
9
+ super(name, node, message, fix);
10
+ this.violatedRule = rule;
11
+ }
12
+
13
+ getViolatedRule() {
14
+ return this.violatedRule;
15
+ }
16
+ }