@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
package/src/MISRA.ts ADDED
@@ -0,0 +1,276 @@
1
+ import { BinaryOp, Break, Case, Expression, If, Joinpoint, Program, 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
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
5
+ import Clava from "@specs-feup/clava/api/clava/Clava.js";
6
+
7
+ export enum MISRATransformationType {
8
+ NoChange,
9
+ DescendantChange,
10
+ Replacement,
11
+ Removal
12
+ }
13
+
14
+ /**
15
+ * Represents an error in MISRA compliance, including the rule ID, the joinpoint where the violation occurred, and a descriptive message.
16
+ */
17
+ export class MISRAError {
18
+ /**
19
+ * Represents the specific MISRA-C rule that was violated
20
+ */
21
+ public ruleID: string;
22
+ /**
23
+ * The joinpoint where the error was detected
24
+ */
25
+ public $jp: Joinpoint;
26
+ /**
27
+ * Explanation of the violation
28
+ */
29
+ public message: string;
30
+
31
+ /**
32
+ *
33
+ * @param ruleID - specific MISRA rule that was violated
34
+ * @param $jp - joinpoint where the error was detected
35
+ * @param message - description of the error
36
+ */
37
+ constructor(ruleID: string, $jp: Joinpoint, message: string) {
38
+ this.ruleID = ruleID;
39
+ this.$jp = $jp;
40
+ this.message = message;
41
+ }
42
+
43
+ /**
44
+ * Checks if two instances of MISRAError are equal based on all properties
45
+ * @param other
46
+ * @returns Returns `true` if the errors are the same, `false` otherwise
47
+ */
48
+ equals(other: MISRAError): boolean {
49
+ return this.ruleID === other.ruleID &&
50
+ this.$jp.astId === other.$jp.astId &&
51
+ this.message === other.message;
52
+ }
53
+
54
+ /**
55
+ *
56
+ */
57
+ isActiveError(): boolean {
58
+ return (Query.root() as Joinpoint).contains(this.$jp);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * A report of a MISRA transformation, including the transformation type and an optional new joinpoint node.
64
+ *
65
+ * If the transformation type is `Replacement`, the `newNode` must be provided to indicate the new joinpoint.
66
+ */
67
+ export class MISRATransformationReport {
68
+ /**
69
+ * The type of the MISRA transformation
70
+ */
71
+ type: MISRATransformationType;
72
+ /**
73
+ * An optional new joinpoint node, provided if the transformation involves a replacement
74
+ */
75
+ newNode?: Joinpoint;
76
+
77
+ /**
78
+ *
79
+ * @param type The type of the MISRA transformation
80
+ * @param newNode The new joinpoint node resulting from the transformation. Required if the transformation type is `Replacement`.
81
+ */
82
+ constructor(type: MISRATransformationType, newNode?: Joinpoint) {
83
+ this.type = type;
84
+ if (type === MISRATransformationType.Replacement && !newNode) {
85
+ throw new Error("newNode must be provided when a 'Replacement' transformation is performed");
86
+ }
87
+ this.newNode = newNode;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Converts a switch statement into either consecutive statements or if statements
93
+ * - If the switch has only one clause and a default case, it is converted to consecutive statements
94
+ * - Otherwise, it is converted to if statements
95
+ */
96
+ export class MISRASwitchConverter {
97
+ /**
98
+ * Converts a switch statement to consecutive statements or if statements
99
+ *
100
+ * @param switchStmt - The switch statement to convert
101
+ * @returns The converted statements or `undefined` if no statements remain
102
+ */
103
+ static convert(switchStmt: Switch): Statement | undefined {
104
+ if (switchStmt.hasDefaultCase && getNumOfSwitchClauses(switchStmt) < 2) { // The statements will always be executed
105
+ return this.convertToConsecutiveStmts(switchStmt);
106
+ } else {
107
+ return this.convertToIfStatements(switchStmt);
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Converts a switch with only one clause and a default case into consecutive statements
113
+ *
114
+ * @param switchStmt - The switch statement to convert
115
+ * @returns The first statement or `undefined` if no statements remain
116
+ */
117
+ static convertToConsecutiveStmts(switchStmt: Switch): Statement | undefined {
118
+ const scope = switchStmt.children[1] as Scope;
119
+ this.removeBreakStmts(scope);
120
+ this.removeCases(scope);
121
+
122
+ // If there are no statements except break and comments, the switch can be removed
123
+ if (scope.children.length === 0 || scope.children.every(stmt => isCommentStmt(stmt))) {
124
+ switchStmt.detach();
125
+ return undefined;
126
+ }
127
+
128
+ let firstStmt, lastStmt;
129
+ const stmts = scope.children as Statement[];
130
+ for (let i = 0; i < stmts.length; i++) {
131
+ const stmt = stmts[i];
132
+ stmt.detach();
133
+
134
+ if (!firstStmt) {
135
+ firstStmt = stmt;
136
+ switchStmt.replaceWith(firstStmt);
137
+ lastStmt = stmt;
138
+ continue;
139
+ }
140
+ lastStmt!.insertAfter(stmt);
141
+ lastStmt = stmt;
142
+ }
143
+ return firstStmt as Statement;
144
+ }
145
+
146
+ /**
147
+ * Converts a switch statement into a series of if statements
148
+ *
149
+ * @param switchStmt - The switch statement to convert
150
+ * @returns The first if statement created
151
+ */
152
+ static convertToIfStatements(switchStmt: Switch): If {
153
+ const scope = switchStmt.children[1] as Scope;
154
+ const consecutiveCases = this.consecutiveCases(switchStmt);
155
+ this.removeBreakStmts(scope);
156
+
157
+ let ifStmt: If;
158
+ let lastIfStmt: If | undefined;
159
+ for (let i = 0; i < consecutiveCases.length; i++) {
160
+ const cases = consecutiveCases[i];
161
+
162
+ if (cases.some(caseStmt => caseStmt.isDefault)) { // Has default case
163
+ lastIfStmt!.setElse(ClavaJoinPoints.scope(...cases[cases.length-1].instructions));
164
+ } else {
165
+ lastIfStmt = this.createIfStatement(switchStmt.condition, cases, i, lastIfStmt)
166
+ if (i === 0) {
167
+ ifStmt = lastIfStmt;
168
+ }
169
+ }
170
+ }
171
+ switchStmt.replaceWith(ifStmt!);
172
+ return ifStmt!;
173
+ }
174
+
175
+ /**
176
+ * Creates an if statement for the given consecutive cases
177
+ *
178
+ * @param condition - The switch condition
179
+ * @param cases - A list of consecutive cases
180
+ * @param index - The index of the current case group
181
+ * @param lastIfStmt - The last if statement, used to chain else
182
+ * @returns The new if statement
183
+ */
184
+ private static createIfStatement(condition: Expression, cases: Case[], index: number, lastIfStmt: If | undefined): If {
185
+ const conditionExpr = this.equivalentCondition(condition, cases);
186
+ const thenBody = ClavaJoinPoints.scope(...cases[cases.length - 1].instructions);
187
+ const newIfStmt = ClavaJoinPoints.ifStmt(conditionExpr, thenBody);
188
+
189
+ if (index === 0) {
190
+ return newIfStmt;
191
+ } else {
192
+ lastIfStmt!.setElse(newIfStmt);
193
+ return newIfStmt;
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Creates the equivalent condition for an if statement based on the case values
199
+ *
200
+ * @param condition - The switch condition
201
+ * @param cases - A list of case` statements
202
+ * @returns The combined condition
203
+ */
204
+ private static equivalentCondition(condition: Expression, cases: Case[]): Expression {
205
+ let lastBinaryOp: BinaryOp;
206
+
207
+ for (let i = 0; i < cases.length; i++) {
208
+ const caseStmt = cases[i];
209
+ const newBinaryOp = ClavaJoinPoints.binaryOp("==", condition, caseStmt.values[0]);
210
+
211
+ if (i === 0) {
212
+ lastBinaryOp = newBinaryOp;
213
+ continue;
214
+ }
215
+ lastBinaryOp = ClavaJoinPoints.binaryOp("||", lastBinaryOp!, newBinaryOp);
216
+ }
217
+ return lastBinaryOp!;
218
+ }
219
+
220
+ /**
221
+ * Removes all break statements from the given scope
222
+ * @param scope - The scope from which the break statements will be removed
223
+ */
224
+ private static removeBreakStmts(scope: Scope) {
225
+ const breakStmts = scope.children.filter(child => child instanceof Break);
226
+ breakStmts.forEach(stmt => stmt.detach());
227
+ }
228
+
229
+ /**
230
+ * Removes all case statements from the given scope
231
+ * @param scope - The scope from which the case statements will be removed
232
+ */
233
+ private static removeCases(scope: Scope) {
234
+ const cases = scope.children.filter(child => child instanceof Case);
235
+ cases.forEach(caseStmt => caseStmt.detach());
236
+ }
237
+
238
+ /**
239
+ * Groups case statements into consecutive blocks, ensuring the block with the default case is last
240
+ *
241
+ * @param switchStmt - The switch statement
242
+ * @returns The grouped case statements
243
+ */
244
+ private static consecutiveCases(switchStmt: Switch): Case[][] {
245
+ let caseGroups: Case[][] = [];
246
+ let currentList: Case[] = [];
247
+
248
+ for (const caseStmt of switchStmt.cases) {
249
+ currentList.push(caseStmt);
250
+
251
+ if (caseStmt.instructions.length !== 0) { // Has no consecutive case
252
+ caseGroups.push(currentList);
253
+ currentList = [];
254
+ }
255
+ }
256
+
257
+ // Ensure the block containing the default case is placed at the last position
258
+ return this.organizeCaseGroups(caseGroups);
259
+ }
260
+
261
+ /**
262
+ * Organizes case groups such that the group with default case is placed last.
263
+ *
264
+ * @param caseGroups - The groups of case statements
265
+ * @returns The organized case groups
266
+ */
267
+ private static organizeCaseGroups(caseGroups: Case[][]): Case[][] {
268
+ const nonDefaultGroups = caseGroups.filter(block => !block.some(caseStmt => caseStmt.isDefault));
269
+ const defaultBlock = caseGroups.find(block => block.some(caseStmt => caseStmt.isDefault));
270
+
271
+ if (defaultBlock) {
272
+ nonDefaultGroups.push(defaultBlock);
273
+ }
274
+ return nonDefaultGroups;
275
+ }
276
+ }
@@ -0,0 +1,84 @@
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
+ /**
16
+ * Configuration provided by the user to assist in rule corrections
17
+ */
18
+ #config: Map<string, any> | undefined = undefined;
19
+
20
+ #varCounter = 0;
21
+ #funcCounter = 0;
22
+ #headerCounter = 0;
23
+
24
+ #varPrefix = "__misra_var_";
25
+ #funcPrefix = "__misra_func_";
26
+ #headerPrefix = "misra_hdr_";
27
+
28
+ get errors(): MISRAError[] {
29
+ return this.#misraErrors;
30
+ }
31
+
32
+ get activeErrors(): MISRAError[] {
33
+ return this.#misraErrors.filter(error => error.isActiveError());
34
+ }
35
+
36
+ get config(): Map<string, any> | undefined {
37
+ return this.#config;
38
+ }
39
+
40
+ set config(configFilePath: string) {
41
+ if (fs.existsSync(configFilePath)) {
42
+ const data = fs.readFileSync(configFilePath, 'utf-8');
43
+ this.#config = new Map(Object.entries(JSON.parse(data)));
44
+ } else {
45
+ console.error(`[Clava-MISRATool] Provided configuration file was not found.`);
46
+ process.exit(1);
47
+ }
48
+ }
49
+
50
+ generateVarName() {
51
+ return `${this.#varPrefix}${this.#varCounter++}`;
52
+ }
53
+
54
+ generateFuncName() {
55
+ return `${this.#funcPrefix}${this.#funcCounter++}`;
56
+ }
57
+
58
+ generateHeaderFilename() {
59
+ return `${this.#headerPrefix}${this.#headerCounter++}.h`;
60
+ }
61
+
62
+ addMISRAError(ruleID: string, $jp: Joinpoint, message: string) {
63
+ const newError = new MISRAError(ruleID, $jp, message);
64
+
65
+ if (!this.#misraErrors.some(error => error.equals(newError))) {
66
+ this.#misraErrors.push(newError);
67
+ }
68
+ }
69
+
70
+ private printError(error: MISRAError): void {
71
+ console.log(`MISRA-C Rule ${error.ruleID} violation at ${error.$jp.filepath}@${error.$jp.line}:${error.$jp.column}: ${error.message}\n`);
72
+ }
73
+
74
+ public printAllErrors(): void {
75
+ this.#misraErrors.forEach(error => this.printError(error));
76
+ }
77
+
78
+ public printActiveErrors(): void {
79
+ this.#misraErrors
80
+ .filter(error => error.isActiveError())
81
+ .forEach(error => this.printError(error));
82
+ }
83
+
84
+ }
@@ -0,0 +1,64 @@
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
+ * Priority of the rule which is low by default.
20
+ */
21
+ readonly priority: number = 4;
22
+
23
+ /**
24
+ * MISRA context for error tracking and rule transformations state
25
+ */
26
+ protected context: MISRAContext;
27
+
28
+ /**
29
+ *
30
+ * @param ruleID - Unique identifier for the MISRA-C rule
31
+ * @param context - MISRA context for error tracking and rule transformations state
32
+ */
33
+ constructor(ruleID: string, context: MISRAContext) {
34
+ this.ruleID = ruleID;
35
+ this.context = context;
36
+ }
37
+
38
+ /**
39
+ * Checks if the joinpoint violates the rule
40
+ *
41
+ * @param $jp - Joinpoint to analyze
42
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
43
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
44
+ */
45
+ abstract match($jp: Joinpoint, logErrors: boolean): boolean;
46
+
47
+ /**
48
+ * Transforms the joinpoint to comply with the MISRA-C rule
49
+ *
50
+ * @param $jp - Joinpoint to transform
51
+ * @returns Report detailing the transformation result
52
+ */
53
+ abstract transform($jp: Joinpoint): MISRATransformationReport;
54
+
55
+ /**
56
+ * Logs a MISRA-C rule violation error
57
+ *
58
+ * @param $jp - The joinpoint where the violation occurred
59
+ * @param msg - Description of the violation
60
+ */
61
+ protected logMISRAError($jp: Joinpoint, msg:string): void {
62
+ this.context.addMISRAError(this.ruleID, $jp, msg);
63
+ }
64
+ }
@@ -0,0 +1,95 @@
1
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
2
+ import { Call, FileJp, Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
3
+ import MISRARule from "./MISRARule.js";
4
+ import sortRules from "./rules/index.js";
5
+ import MISRAContext from "./MISRAContext.js";
6
+ import { MISRAError, MISRATransformationType } from "./MISRA.js";
7
+ import { isCallToImplicitFunction } from "./utils/utils.js";
8
+
9
+ export default class MISRATool {
10
+ static #misraRules: MISRARule[];
11
+ static #context: MISRAContext;
12
+
13
+ private static init(startingPoint: FileJp | Program) {
14
+ this.validateStdVersion(startingPoint);
15
+ this.#context = new MISRAContext();
16
+ this.#misraRules = sortRules(this.#context);
17
+ }
18
+
19
+ private static validateStdVersion(startingPoint: FileJp | Program) {
20
+ const allowedVersions = ["c90", "c99", "c11"];
21
+ const stdVersion = startingPoint instanceof Program ? startingPoint.standard : (startingPoint.root as Program).standard;
22
+
23
+ if (!allowedVersions.includes(stdVersion)) {
24
+ console.error(`[Clava-MISRATool] Invalid --std value. Allowed values: ${allowedVersions.join(", ")}`);
25
+ process.exit(1);
26
+ }
27
+ }
28
+
29
+ public static checkCompliance(startingPoint: Program | FileJp = Query.root() as Program) {
30
+ this.init(startingPoint);
31
+
32
+ const nodes = [startingPoint, ...startingPoint.descendants];
33
+ for (const node of nodes) {
34
+ for (const rule of this.#misraRules) {
35
+ rule.match(node, true);
36
+ }
37
+ }
38
+ if (this.#context.errors.length > 0) {
39
+ this.#context.printAllErrors();
40
+ } else {
41
+ console.log("[Clava-MISRATool] No MISRA-C violations detected.");
42
+ }
43
+ }
44
+
45
+ public static applyCorrections(configFilePath?: string) {
46
+ this.init(Query.root() as Program);
47
+ if (configFilePath) {
48
+ this.#context.config = configFilePath;
49
+ }
50
+
51
+ let iteration = 0;
52
+ let modified = false;
53
+ do {
54
+ console.log(`[Clava-MISRATool] Iteration #${++iteration}: Applying MISRA-C transformations...`);
55
+ modified = this.transformAST(Query.root() as Program);
56
+ } while(modified);
57
+
58
+ if (this.#context.errors.length === 0) {
59
+ console.log("[Clava-MISRATool] All detected violations were corrected.");
60
+ } else {
61
+ console.log("\n[Clava-MISRATool] Remaining MISRA-C violations:");
62
+ this.#context.printActiveErrors();
63
+ }
64
+ }
65
+
66
+ private static transformAST($jp: Joinpoint): boolean {
67
+ let modified = false;
68
+
69
+ for (const rule of this.#misraRules) {
70
+ const transformReport = rule.transform($jp);
71
+
72
+ if (transformReport.type !== MISRATransformationType.NoChange) {
73
+ modified = true;
74
+ if (transformReport.type === MISRATransformationType.Removal)
75
+ return modified;
76
+ else if (transformReport.type === MISRATransformationType.Replacement)
77
+ $jp = transformReport.newNode as Joinpoint;
78
+ }
79
+ }
80
+
81
+ for (const child of $jp.children) {
82
+ if (this.transformAST(child))
83
+ modified = true;
84
+ }
85
+ return modified;
86
+ }
87
+
88
+ public static getErrorCount(): number {
89
+ return this.#context.errors.length;
90
+ }
91
+
92
+ public static getActiveErrorCount(): number {
93
+ return this.#context.activeErrors.length;
94
+ }
95
+ }
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
+ }