@specs-feup/clava-misra 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.gitignore +8 -0
  2. package/README.md +53 -19
  3. package/dist/MISRA.d.ts +28 -10
  4. package/dist/MISRA.d.ts.map +1 -1
  5. package/dist/MISRA.js +30 -10
  6. package/dist/MISRA.js.map +1 -1
  7. package/dist/MISRAContext.d.ts +65 -11
  8. package/dist/MISRAContext.d.ts.map +1 -1
  9. package/dist/MISRAContext.js +131 -35
  10. package/dist/MISRAContext.js.map +1 -1
  11. package/dist/MISRARule.d.ts +38 -25
  12. package/dist/MISRARule.d.ts.map +1 -1
  13. package/dist/MISRARule.js +40 -18
  14. package/dist/MISRARule.js.map +1 -1
  15. package/dist/MISRATool.d.ts +39 -5
  16. package/dist/MISRATool.d.ts.map +1 -1
  17. package/dist/MISRATool.js +102 -46
  18. package/dist/MISRATool.js.map +1 -1
  19. package/dist/StandardGuideline.d.ts +22 -0
  20. package/dist/StandardGuideline.d.ts.map +1 -0
  21. package/dist/StandardGuideline.js +12 -0
  22. package/dist/StandardGuideline.js.map +1 -0
  23. package/dist/ast-visitor/Context.d.ts +11 -0
  24. package/dist/ast-visitor/Context.d.ts.map +1 -0
  25. package/dist/ast-visitor/Context.js +15 -0
  26. package/dist/ast-visitor/Context.js.map +1 -0
  27. package/dist/ast-visitor/Visit.d.ts +23 -0
  28. package/dist/ast-visitor/Visit.d.ts.map +1 -0
  29. package/dist/ast-visitor/Visit.js +18 -0
  30. package/dist/ast-visitor/Visit.js.map +1 -0
  31. package/dist/ast-visitor/VisitWithContext.d.ts +32 -0
  32. package/dist/ast-visitor/VisitWithContext.d.ts.map +1 -0
  33. package/dist/ast-visitor/VisitWithContext.js +26 -0
  34. package/dist/ast-visitor/VisitWithContext.js.map +1 -0
  35. package/dist/main.js +1 -1
  36. package/dist/main.js.map +1 -1
  37. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts +27 -0
  38. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts.map +1 -0
  39. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js +98 -0
  40. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js.map +1 -0
  41. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts +45 -6
  42. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts.map +1 -1
  43. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js +91 -8
  44. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js.map +1 -1
  45. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts +15 -5
  46. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts.map +1 -1
  47. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js +20 -6
  48. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js.map +1 -1
  49. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts +11 -5
  50. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts.map +1 -1
  51. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js +13 -10
  52. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js.map +1 -1
  53. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts +11 -6
  54. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts.map +1 -1
  55. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js +19 -11
  56. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js.map +1 -1
  57. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts +15 -5
  58. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts.map +1 -1
  59. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js +24 -10
  60. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js.map +1 -1
  61. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts +22 -6
  62. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts.map +1 -1
  63. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js +37 -10
  64. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js.map +1 -1
  65. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts +66 -0
  66. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts.map +1 -0
  67. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js +209 -0
  68. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js.map +1 -0
  69. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts +37 -12
  70. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts.map +1 -1
  71. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js +112 -39
  72. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js.map +1 -1
  73. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts +15 -5
  74. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts.map +1 -1
  75. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js +21 -7
  76. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js.map +1 -1
  77. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts +11 -6
  78. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts.map +1 -1
  79. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js +17 -8
  80. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js.map +1 -1
  81. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts +105 -0
  82. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts.map +1 -0
  83. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js +258 -0
  84. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js.map +1 -0
  85. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts +25 -0
  86. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts.map +1 -0
  87. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js +27 -0
  88. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js.map +1 -0
  89. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts +29 -0
  90. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts.map +1 -0
  91. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js +31 -0
  92. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js.map +1 -0
  93. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts +25 -0
  94. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts.map +1 -0
  95. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js +27 -0
  96. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js.map +1 -0
  97. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts +25 -0
  98. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts.map +1 -0
  99. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js +27 -0
  100. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js.map +1 -0
  101. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts +25 -0
  102. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts.map +1 -0
  103. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js +27 -0
  104. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js.map +1 -0
  105. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts +30 -0
  106. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts.map +1 -0
  107. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js +32 -0
  108. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js.map +1 -0
  109. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts +25 -0
  110. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts.map +1 -0
  111. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js +27 -0
  112. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js.map +1 -0
  113. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts +6 -14
  114. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts.map +1 -1
  115. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js +17 -27
  116. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js.map +1 -1
  117. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts +13 -7
  118. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts.map +1 -1
  119. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js +31 -17
  120. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js.map +1 -1
  121. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts +26 -7
  122. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts.map +1 -1
  123. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js +32 -14
  124. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js.map +1 -1
  125. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts +48 -6
  126. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts.map +1 -1
  127. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js +84 -34
  128. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js.map +1 -1
  129. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts +24 -5
  130. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts.map +1 -1
  131. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js +27 -7
  132. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js.map +1 -1
  133. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts +46 -0
  134. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts.map +1 -0
  135. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js +40 -0
  136. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js.map +1 -0
  137. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts +25 -0
  138. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts.map +1 -0
  139. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js +46 -0
  140. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js.map +1 -0
  141. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts +26 -0
  142. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts.map +1 -0
  143. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js +54 -0
  144. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js.map +1 -0
  145. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts +27 -0
  146. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts.map +1 -0
  147. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js +55 -0
  148. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js.map +1 -0
  149. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts +24 -0
  150. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts.map +1 -0
  151. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js +42 -0
  152. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js.map +1 -0
  153. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts +24 -0
  154. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts.map +1 -0
  155. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js +42 -0
  156. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js.map +1 -0
  157. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts +35 -0
  158. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts.map +1 -0
  159. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js +98 -0
  160. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js.map +1 -0
  161. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts +35 -0
  162. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts.map +1 -0
  163. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js +76 -0
  164. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js.map +1 -0
  165. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts +32 -0
  166. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts.map +1 -0
  167. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js +57 -0
  168. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js.map +1 -0
  169. package/dist/rules/UserConfigurableRule.d.ts +55 -0
  170. package/dist/rules/UserConfigurableRule.d.ts.map +1 -0
  171. package/dist/rules/UserConfigurableRule.js +16 -0
  172. package/dist/rules/UserConfigurableRule.js.map +1 -0
  173. package/dist/rules/index.d.ts +11 -18
  174. package/dist/rules/index.d.ts.map +1 -1
  175. package/dist/rules/index.js +47 -7
  176. package/dist/rules/index.js.map +1 -1
  177. package/dist/tests/Section17_Functions/misra_config.json +10 -0
  178. package/dist/tests/Section21-StandardLibraries/misra_config.json +88 -0
  179. package/dist/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
  180. package/dist/tests/utils.d.ts +6 -3
  181. package/dist/tests/utils.d.ts.map +1 -1
  182. package/dist/tests/utils.js +33 -7
  183. package/dist/tests/utils.js.map +1 -1
  184. package/dist/utils/CallUtils.d.ts +15 -0
  185. package/dist/utils/CallUtils.d.ts.map +1 -0
  186. package/dist/utils/CallUtils.js +34 -0
  187. package/dist/utils/CallUtils.js.map +1 -0
  188. package/dist/utils/CommentUtils.d.ts +21 -0
  189. package/dist/utils/CommentUtils.d.ts.map +1 -0
  190. package/dist/utils/CommentUtils.js +27 -0
  191. package/dist/utils/CommentUtils.js.map +1 -0
  192. package/dist/utils/FileUtils.d.ts +51 -0
  193. package/dist/utils/FileUtils.d.ts.map +1 -0
  194. package/dist/utils/FileUtils.js +121 -0
  195. package/dist/utils/FileUtils.js.map +1 -0
  196. package/dist/utils/FunctionUtils.d.ts +25 -0
  197. package/dist/utils/FunctionUtils.d.ts.map +1 -0
  198. package/dist/utils/FunctionUtils.js +65 -0
  199. package/dist/utils/FunctionUtils.js.map +1 -0
  200. package/dist/utils/IdentifierUtils.d.ts +14 -0
  201. package/dist/utils/IdentifierUtils.d.ts.map +1 -0
  202. package/dist/utils/IdentifierUtils.js +87 -0
  203. package/dist/utils/IdentifierUtils.js.map +1 -0
  204. package/dist/utils/JoinpointUtils.d.ts +19 -0
  205. package/dist/utils/JoinpointUtils.d.ts.map +1 -0
  206. package/dist/utils/JoinpointUtils.js +46 -0
  207. package/dist/utils/JoinpointUtils.js.map +1 -0
  208. package/dist/utils/ProgramUtils.d.ts +14 -0
  209. package/dist/utils/ProgramUtils.d.ts.map +1 -0
  210. package/dist/utils/ProgramUtils.js +72 -0
  211. package/dist/utils/ProgramUtils.js.map +1 -0
  212. package/dist/utils/SwitchUtils.d.ts +21 -0
  213. package/dist/utils/SwitchUtils.d.ts.map +1 -0
  214. package/dist/utils/SwitchUtils.js +47 -0
  215. package/dist/utils/SwitchUtils.js.map +1 -0
  216. package/dist/utils/TypeDeclUtils.d.ts +35 -0
  217. package/dist/utils/TypeDeclUtils.d.ts.map +1 -0
  218. package/dist/utils/TypeDeclUtils.js +78 -0
  219. package/dist/utils/TypeDeclUtils.js.map +1 -0
  220. package/dist/utils/VarUtils.d.ts +19 -0
  221. package/dist/utils/VarUtils.d.ts.map +1 -0
  222. package/dist/utils/VarUtils.js +59 -0
  223. package/dist/utils/VarUtils.js.map +1 -0
  224. package/package.json +16 -6
  225. package/src/MISRA.ts +33 -17
  226. package/src/MISRAContext.ts +128 -30
  227. package/src/MISRARule.ts +61 -29
  228. package/src/MISRATool.ts +108 -42
  229. package/src/StandardGuideline.ts +23 -0
  230. package/src/ast-visitor/Context.ts +16 -0
  231. package/src/ast-visitor/Visit.ts +26 -0
  232. package/src/ast-visitor/VisitWithContext.ts +42 -0
  233. package/src/main.ts +1 -1
  234. package/src/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.ts +114 -0
  235. package/src/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.ts +103 -13
  236. package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +24 -10
  237. package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +17 -8
  238. package/src/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.ts +20 -12
  239. package/src/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.ts +23 -12
  240. package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +44 -13
  241. package/src/rules/Section17_Functions/Rule_17_3_ImplicitFunction.ts +153 -104
  242. package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +114 -44
  243. package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +27 -10
  244. package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +20 -12
  245. package/src/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.ts +317 -0
  246. package/src/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.ts +30 -0
  247. package/src/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.ts +35 -0
  248. package/src/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.ts +30 -0
  249. package/src/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.ts +30 -0
  250. package/src/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.ts +29 -0
  251. package/src/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.ts +36 -0
  252. package/src/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.ts +30 -0
  253. package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +14 -29
  254. package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +33 -19
  255. package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +33 -20
  256. package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +90 -45
  257. package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +27 -8
  258. package/src/rules/Section5_Identifiers/IdentifierRenameRule.ts +63 -0
  259. package/src/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.ts +52 -0
  260. package/src/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.ts +62 -0
  261. package/src/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.ts +61 -0
  262. package/src/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.ts +47 -0
  263. package/src/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.ts +47 -0
  264. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.ts +118 -0
  265. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.ts +89 -0
  266. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.ts +65 -0
  267. package/src/rules/UserConfigurableRule.ts +60 -0
  268. package/src/rules/index.ts +45 -7
  269. package/src/tests/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.test.ts +114 -0
  270. package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +7 -5
  271. package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +40 -13
  272. package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +10 -12
  273. package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +5 -5
  274. package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +5 -5
  275. package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +5 -5
  276. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions.test.ts +68 -40
  277. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_MissingConfig.test.ts +98 -0
  278. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_ProblematicConfig.test.ts +71 -0
  279. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +103 -49
  280. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +7 -7
  281. package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -7
  282. package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +25 -21
  283. package/src/tests/Section17_Functions/misra_config.json +4 -3
  284. package/src/tests/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.test.ts +62 -0
  285. package/src/tests/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.test.ts +67 -0
  286. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.test.ts +84 -0
  287. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_MissingConfig.test.ts +33 -0
  288. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_ProblematicConfig.test.ts +71 -0
  289. package/src/tests/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.test.ts +63 -0
  290. package/src/tests/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.test.ts +91 -0
  291. package/src/tests/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.test.ts +65 -0
  292. package/src/tests/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.test.ts +89 -0
  293. package/src/tests/Section21-StandardLibraries/misra_config.json +88 -0
  294. package/src/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
  295. package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +148 -113
  296. package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +243 -163
  297. package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +32 -20
  298. package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +36 -30
  299. package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -8
  300. package/src/tests/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.test.ts +78 -0
  301. package/src/tests/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.test.ts +120 -0
  302. package/src/tests/Section5_Identifiers/Rule_5_7_UniqueTagNames.test.ts +51 -0
  303. package/src/tests/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.test.ts +73 -0
  304. package/src/tests/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.test.ts +97 -0
  305. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.test.ts +160 -0
  306. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.test.ts +46 -0
  307. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.test.ts +69 -0
  308. package/src/tests/utils.ts +32 -7
  309. package/src/utils/CallUtils.ts +40 -0
  310. package/src/utils/CommentUtils.ts +29 -0
  311. package/src/utils/FileUtils.ts +141 -0
  312. package/src/utils/FunctionUtils.ts +75 -0
  313. package/src/utils/IdentifierUtils.ts +94 -0
  314. package/src/utils/JoinpointUtils.ts +53 -0
  315. package/src/utils/ProgramUtils.ts +83 -0
  316. package/src/utils/SwitchUtils.ts +52 -0
  317. package/src/utils/TypeDeclUtils.ts +89 -0
  318. package/src/utils/VarUtils.ts +70 -0
  319. package/tsconfig.json +2 -1
  320. package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +0 -120
  321. package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +0 -36
  322. package/src/utils/utils.ts +0 -280
@@ -0,0 +1,89 @@
1
+ import { Joinpoint, TypedefDecl, DeclStmt, TypedefType, ElaboratedType, TagType, FileJp, EnumDecl, EnumeratorDecl, Varref } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
3
+ import { getBaseType } from "./JoinpointUtils.js";
4
+ import { isTagDecl, TagDecl } from "./JoinpointUtils.js";
5
+ import { findFilesReferencingHeader, getIncludesOfFile } from "./FileUtils.js";
6
+
7
+ /**
8
+ * Retrieves the typedef declaration for the provided joinpoint, if available
9
+ * @param $jp The joinpoint to analyze
10
+ * @returns The typedef declaration if found, or undefined if not
11
+ */
12
+ export function getTypeDefDecl($jp: Joinpoint): TypedefDecl | undefined {
13
+ if ($jp instanceof DeclStmt && $jp.children.length === 1 && $jp.children[0] instanceof TypedefDecl)
14
+ return $jp.children[0];
15
+
16
+ if (isTagDecl($jp)) {
17
+ const typeDecls = Query.searchFrom($jp, TypedefDecl).get();
18
+ if (typeDecls.length === 1)
19
+ return typeDecls[0];
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Checks if the provided joinpoint declares a type (typedef)
25
+ * @param $jp The joinpoint to check
26
+ * @returns Returns true if the joinpoint declares a typedef, otherwise false
27
+ */
28
+ export function hasTypeDefDecl($jp: Joinpoint): boolean {
29
+ return getTypeDefDecl($jp) !== undefined;
30
+ }
31
+
32
+
33
+ /**
34
+ * Checks if a given joinpoint uses the specified typedef declaration.
35
+ * @param jp - The joinpoint to check
36
+ * @param typeDecl - The typedef declaration to check against
37
+ * @returns Returns true if the joinpoint uses the given typedef declaration, false otherwise
38
+ */
39
+ export function jpUsesTypedef(jp: Joinpoint, typeDecl: TypedefDecl): boolean {
40
+ const jpType = getBaseType(jp);
41
+
42
+ return !jpType?.isBuiltin && (
43
+ (jpType instanceof TypedefType &&jpType.decl.astId === typeDecl.astId) ||
44
+ (jpType instanceof ElaboratedType && jpType.namedType instanceof TypedefType &&jpType.namedType.decl.astId === typeDecl.astId)
45
+ );
46
+ }
47
+
48
+ /**
49
+ * Checks if a given joinpoint uses the specified tag declaration
50
+ * @param $jp The joinpoint to analyze
51
+ * @param tag The tag to check against
52
+ * @returns Returns true if the joinpoint uses the given tag, false otherwise
53
+ */
54
+ export function jpUsesTag($jp: Joinpoint, tag: TagDecl): boolean {
55
+ if (tag instanceof EnumDecl && $jp instanceof Varref && getTypeDefDecl(tag) === undefined) {
56
+ const enumeratorsIDs = tag.enumerators.map(enumerator => enumerator.astId);
57
+ const decl = $jp.getValue("decl");
58
+ if (decl instanceof EnumeratorDecl && enumeratorsIDs.includes(decl.astId)) {
59
+ return true;
60
+ }
61
+ }
62
+
63
+ const jpType = getBaseType($jp);
64
+ return jpType instanceof ElaboratedType &&
65
+ jpType.namedType instanceof TagType &&
66
+ jpType.namedType.decl.astId === tag.astId &&
67
+ $jp.astId !== getTypeDefDecl(tag)?.astId
68
+ }
69
+
70
+ /**
71
+ * Checks if the provided typedef or tag declaration is used in any part of the program
72
+ * @param decl - typedef or tag declaration to verify
73
+ * @returns Returns true if the declaration is used, false otherwise
74
+ */
75
+ export function isTypeDeclUsed(decl: TypedefDecl | TagDecl): boolean {
76
+ const fileJp = decl.getAncestor("file") as FileJp;
77
+ let jps: Joinpoint[] = [];
78
+
79
+ if (fileJp.isHeader) {
80
+ const referencingFiles = findFilesReferencingHeader(fileJp.name);
81
+ jps = [...fileJp.descendants, ...referencingFiles.flatMap(file => file.descendants)];
82
+ } else {
83
+ jps = fileJp.descendants;
84
+ }
85
+
86
+ return decl instanceof TypedefDecl ?
87
+ jps.some(jp => jpUsesTypedef(jp, decl)) :
88
+ jps.some(jp => jpUsesTag(jp, decl));
89
+ }
@@ -0,0 +1,70 @@
1
+ import { FileJp, FunctionJp, Joinpoint, QualType, StorageClass, Vardecl, Varref } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
3
+ import { getIdentifierName, isExternalLinkageIdentifier } from "./IdentifierUtils.js";
4
+ import { getExternalLinkageIdentifiers, getExternalLinkageVars, getExternalVarRefs } from "./ProgramUtils.js";
5
+ import { findFilesReferencingHeader } from "./FileUtils.js";
6
+
7
+ /**
8
+ * Retrieves all variable references qualified as "volatile" starting from the given joinpoint
9
+ * @param $jp Starting joinpoint
10
+ * @returns Array of variable references qualified as volatile
11
+ */
12
+ export function getVolatileVarRefs($jp: Joinpoint): Varref[] {
13
+ return Query.searchFromInclusive($jp, Varref, (ref) => {
14
+ try {
15
+ return ref.type instanceof QualType && ref.type.qualifiers?.includes("volatile")
16
+ } catch (error) {
17
+ return false;
18
+ }
19
+ }).get();
20
+ }
21
+
22
+ /**
23
+ * Retrieves all external references of the given variable.
24
+ * @param $varDecl variable to match by name.
25
+ * @returns Array of external references with the same name as the given variable.
26
+ */
27
+ export function findExternalVarRefs($varDecl: Vardecl): Vardecl[] {
28
+ return getExternalVarRefs().filter(ref => ref.name === $varDecl.name);
29
+ }
30
+
31
+ export function findReferencingFunctions($jp: Vardecl): FunctionJp[] {
32
+ const fileJp = $jp.getAncestor("file");
33
+ const functionsJp = Query.searchFrom(fileJp, FunctionJp).get();
34
+
35
+ return functionsJp
36
+ .filter(funcJp =>
37
+ Query.searchFrom(funcJp, Varref, {decl: (declJp) => declJp?.astId === $jp.astId}).get().length > 0
38
+ );
39
+ }
40
+
41
+ export function findDuplicateVarDefinition($jp: Vardecl): Vardecl[] {
42
+ return getExternalLinkageVars().filter((varDeclJp) => varDeclJp.astId !== $jp.astId && isSameVarDecl(varDeclJp, $jp));
43
+ }
44
+
45
+ export function isSameVarDecl($jp1: Joinpoint, $jp2: Joinpoint): boolean {
46
+ return $jp1 instanceof Vardecl && $jp2 instanceof Vardecl &&
47
+ isExternalLinkageIdentifier($jp1) && isExternalLinkageIdentifier($jp2) &&
48
+ getIdentifierName($jp1) === getIdentifierName($jp2) &&
49
+ $jp1.type.code === $jp2.type.code
50
+ }
51
+
52
+ export function hasMultipleExternalLinkDeclarations($jp: Vardecl): boolean {
53
+ return getExternalLinkageIdentifiers().some(identifier =>
54
+ isSameVarDecl(identifier, $jp) && identifier.getAncestor("file").ast !== $jp.getAncestor("file").ast
55
+ );
56
+ }
57
+
58
+ export function isVarUsed(varDecl: Vardecl): boolean {
59
+ const fileJp = varDecl.getAncestor("file") as FileJp;
60
+ let referencingFiles: FileJp[];
61
+
62
+ if (fileJp.isHeader) {
63
+ const filesWithInclude = findFilesReferencingHeader(fileJp.name);
64
+ referencingFiles = [fileJp, ...filesWithInclude];
65
+ } else {
66
+ referencingFiles = [fileJp];
67
+ }
68
+
69
+ return referencingFiles.some(fileJp => Query.searchFrom(fileJp, Varref, {name: varDecl.name, decl: (declJp) => declJp?.astId === varDecl.astId}).get().length > 0)
70
+ }
package/tsconfig.json CHANGED
@@ -13,7 +13,8 @@
13
13
  "sourceMap": true,
14
14
  "declarationMap": true,
15
15
  "allowSyntheticDefaultImports": true,
16
- "resolveJsonModule": true
16
+ "resolveJsonModule": true,
17
+ "isolatedModules": true,
17
18
  //"esModuleInterop": true
18
19
  }
19
20
  }
@@ -1,120 +0,0 @@
1
- import { FileJp, Include, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
- import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
- import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
5
- import Query from "@specs-feup/lara/api/weaver/Query.js";
6
- import * as path from 'path';
7
-
8
- /**
9
- * MISRA Rule 20.2: The ', " or \ characters and the /* or // character sequences shall not occur in a header filename
10
- */
11
- export default class Rule_20_2_InvalidHeaderFileName extends MISRARule {
12
- constructor(context: MISRAContext) {
13
- super("20.2", context);
14
- }
15
-
16
- /**
17
- * Checks if the given joinpoint is a header file whose name includes invalid characters.
18
- *
19
- * @param $jp - Joinpoint to analyze
20
- * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
21
- * @returns Returns true if the joinpoint violates the rule, false otherwise
22
- */
23
- match($jp: Joinpoint, logErrors: boolean = false): boolean {
24
- if (!($jp instanceof FileJp && $jp.isHeader)) return false;
25
-
26
- const isNonCompliant = /.*('|"|\\|\/\*|\/\/).*/.test($jp.name);
27
- if (isNonCompliant && logErrors) {
28
- this.logMISRAError($jp, `Invalid characters in header filename. Invalid characters are ', ", \\, and the sequences /* and //.`)
29
- }
30
- return isNonCompliant;
31
- }
32
-
33
- /**
34
- * Renames a header file to ensure it contains only valid characters and updates all related includes accordingly.
35
- *
36
- * @param $jp - Joinpoint to transform
37
- * @returns Report detailing the transformation result
38
- */
39
- transform($jp: Joinpoint): MISRATransformationReport {
40
- if (!this.match($jp)) {
41
- return new MISRATransformationReport(MISRATransformationType.NoChange);
42
- }
43
-
44
- const fileJp = $jp as FileJp;
45
- const includesOfHeader = this.getMatchingIncludes(fileJp);
46
- const newFilename = this.context.generateHeaderFilename();
47
-
48
- fileJp.setName(newFilename);
49
- this.updateIncludes(includesOfHeader, newFilename);
50
- return new MISRATransformationReport(MISRATransformationType.DescendantChange);
51
- }
52
-
53
- /**
54
- * Finds all include joinpoints that reference a specific header file
55
- *
56
- * @param headerFileJp - The header file joinpoint
57
- * @returns List of matching include statements
58
- */
59
- private getMatchingIncludes(headerFileJp: FileJp): Include[] {
60
- return Query.search(Include).get().filter(includeJp =>
61
- path.basename(includeJp.name) === headerFileJp.name &&
62
- this.getHeaderFilePath(includeJp) === headerFileJp.path);
63
- }
64
-
65
- /**
66
- * Computes the full path to the header file based on the include statement
67
- *
68
- * @param includeJp The include joinpoint
69
- * @returns Resolved path to the header file
70
- */
71
- private getHeaderFilePath(includeJp: Include): string {
72
- try {
73
- if (includeJp.name.startsWith("../")) {
74
- return includeJp.relativeFolderpath;
75
- } else {
76
- const relativeDir = path.dirname(includeJp.name);
77
- const fileJp = includeJp.getAncestor("file") as FileJp | undefined;
78
- return path.resolve(fileJp!.path, relativeDir);
79
- }
80
- } catch (error) {
81
- return "";
82
- }
83
- }
84
-
85
- /**
86
- * Updates the provided include joinpoints to reference the new header file name
87
- *
88
- * @param includesOfHeader List of include joinpoints to update
89
- * @param newFilename The new filename for the header file
90
- */
91
- private updateIncludes(includesOfHeader: Include[], newFilename: string): void {
92
- for (const includeJp of includesOfHeader) {
93
- const fileJp = includeJp.getAncestor("file") as FileJp | undefined;
94
-
95
- const newIncludeJpName = this.getNewIncludeName(includeJp, newFilename);
96
- fileJp!.addInclude(newIncludeJpName);
97
-
98
- const tempInclude = Query.searchFrom(fileJp!, Include, {name: includeName => path.normalize(includeName) === newIncludeJpName}).first();
99
-
100
- if (tempInclude) {
101
- includeJp.replaceWith(tempInclude.deepCopy());
102
- tempInclude.detach();
103
- }
104
- }
105
- }
106
-
107
- /**
108
- * Computes the new include path with the updated header file name
109
- *
110
- * @param includeJp - Original include statement
111
- * @param newHeaderFileName - New header file name
112
- * @returns The updated include path
113
- */
114
- private getNewIncludeName(includeJp: Include, newHeaderFileName: string): string {
115
- const isFile = path.extname(includeJp.name) !== '';
116
- const baseDir = isFile ? path.dirname(includeJp.name) : includeJp.name;
117
-
118
- return path.join(baseDir, newHeaderFileName);
119
- }
120
- }
@@ -1,36 +0,0 @@
1
- import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
- import MISRARule from "../../MISRARule.js";
3
- import MISRAContext from "../../MISRAContext.js";
4
- import { isInlineComment, getComments } from "../../utils/utils.js";
5
- import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
6
-
7
- export default class Rule_3_2_LineSplicing extends MISRARule {
8
-
9
- constructor(context: MISRAContext) {
10
- super("3.2", context);
11
- }
12
-
13
- match($jp: Joinpoint, logErrors: boolean = false): boolean {
14
- const invalidComments = getComments($jp).filter(comment =>
15
- (isInlineComment(comment) && /\/\n/g.test(comment.text)));
16
-
17
- if (logErrors) {
18
- invalidComments.forEach(comment =>
19
- this.logMISRAError(comment, `Comment ${comment.text} contains invalid character sequences.`)
20
- )
21
- }
22
- return invalidComments.length > 0;
23
- }
24
-
25
- transform($jp: Joinpoint): MISRATransformationReport {
26
- if (!this.match($jp))
27
- return new MISRATransformationReport(MISRATransformationType.NoChange);
28
-
29
- const comments = getComments($jp);
30
- for (const comment of comments) {
31
- const newText = comment.text.replace(/\/\n/g, '');
32
- comment.setText(newText);
33
- }
34
- return new MISRATransformationReport(MISRATransformationType.DescendantChange);
35
- }
36
- }
@@ -1,280 +0,0 @@
1
- import Query from "@specs-feup/lara/api/weaver/Query.js";
2
- import { Comment, Type, Case, Joinpoint, ArrayType, TypedefDecl, DeclStmt, TypedefNameDecl, StorageClass, FunctionJp, Vardecl, FileJp, RecordJp, EnumDecl, PointerType, Switch, BuiltinType, BinaryOp, Break, Scope, Statement, Expression, WrapperStmt, ElaboratedType, TagType, Param, Varref, Program, Include, Call } from "@specs-feup/clava/api/Joinpoints.js";
3
- import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
4
-
5
- /**
6
- * Checks if the comment is an inline comment
7
- * @param $comment - The comment to check
8
- * @returns Returns true if it's an inline comment, otherwise returns false
9
- */
10
- export function isInlineComment($comment: Comment): boolean {
11
- return $comment.astName === "InlineComment";
12
- }
13
-
14
- /**
15
- * Retrieves all comments associated with a given joinpoint
16
- * @param $jp - The joinpoint to retrieve comments from
17
- * @returns Array of comments
18
- */
19
- export function getComments($jp: Joinpoint): Comment[] {
20
- return $jp instanceof Comment ? [$jp] : $jp.inlineComments;
21
- }
22
-
23
- /**
24
- * Checks if a given join point is a comment statement
25
- *
26
- * @param $jp The join point to check
27
- * @returns Returns true if the given join point is a comment statement, otherwise false
28
- */
29
- export function isCommentStmt($jp: Joinpoint): boolean {
30
- return $jp instanceof WrapperStmt && $jp.kind === "comment";
31
- }
32
-
33
- export function getParamReferences($param: Param, $startingPoint: Joinpoint): Varref[] {
34
- return Query.searchFrom($startingPoint, Varref, (ref) => {
35
- try {
36
- return ref.decl && ref.decl.astId === $param.astId;
37
- } catch (error) {
38
- return false;
39
- }
40
- }).get();
41
- }
42
-
43
- /**
44
- * Checks if a storage class has external linkage
45
- * @param $class - The storage class to check
46
- * @returns Returns true if the class has external linkage, otherwise returns false
47
- */
48
- export function hasExternalLinkage($class: StorageClass) {
49
- return $class !== StorageClass.STATIC && $class !== StorageClass.EXTERN;
50
- }
51
-
52
- /**
53
- * Retrieves all variables and functions that can be externed from the files, i.e.,
54
- * elements with storage classes that are not `STATIC` or `EXTERN`
55
- * @returns Array of functions and variables that can be externed
56
- */
57
- export function getExternals(): (FunctionJp | Vardecl)[] {
58
- let result: (FunctionJp | Vardecl)[] = [];
59
-
60
- for (const file of Query.search(FileJp).get()) {
61
- for(const child of file.children) {
62
- if((child instanceof Vardecl || child instanceof FunctionJp) && hasExternalLinkage(child.storageClass)) {
63
- result.push(child);
64
- }
65
- }
66
- }
67
- return result;
68
- }
69
-
70
- /**
71
- * Checks if the provided node has a defined type
72
- * @param $jp The joinpoint to check its type
73
- * @returns true if the joinpoint has a defined type, otherwise false
74
- */
75
- export function hasDefinedType($jp: Joinpoint): boolean {
76
- return $jp.hasType && $jp.type !== null && $jp.type !== undefined;
77
- }
78
-
79
- /**
80
- * Retrieves the base type of the provided joinpoint.
81
- * @param $jp The joinpoint to retrieve its type
82
- * @returns The base type of the joinpoint, or undefined if the joinpoint does not have a type
83
- */
84
- export function getBaseType($jp: Joinpoint): Type | undefined {
85
- if (!hasDefinedType($jp)) return undefined;
86
- let jpType = $jp.type;
87
-
88
- while (jpType instanceof PointerType || jpType instanceof ArrayType) {
89
- jpType = jpType instanceof PointerType ? jpType.pointee : jpType.elementType;
90
- }
91
- return jpType;
92
- }
93
-
94
- /**
95
- * Retrieves the typedef declaration for the provided joinpoint, if available
96
- * @param $jp The joinpoint to analyze
97
- * @returns The typedef declaration if found, or undefined if not
98
- */
99
- export function getTypeDecl($jp: Joinpoint): TypedefDecl | undefined {
100
- if ($jp instanceof DeclStmt && $jp.children.length === 1 && $jp.children[0] instanceof TypedefDecl)
101
- return $jp.children[0];
102
-
103
- if ($jp instanceof RecordJp || $jp instanceof EnumDecl) {
104
- const typeDecls = Query.searchFrom($jp, TypedefDecl).get();
105
- if (typeDecls.length === 1)
106
- return typeDecls[0];
107
- }
108
- }
109
-
110
- /**
111
- * Checks if the provided joinpoint declares a type (typedef)
112
- * @param $jp The joinpoint to check
113
- * @returns Returns true if the joinpoint declares a typedef, otherwise false
114
- */
115
- export function hasTypeDecl($jp: Joinpoint): boolean {
116
- return getTypeDecl($jp) !== undefined;
117
- }
118
-
119
- /**
120
- * Retrieves all joinpoints with a defined type
121
- * @returns Array of joinpoints with a defined type
122
- */
123
- export function getTypedJps(startingPoint?: Joinpoint): Joinpoint[] {
124
- if (startingPoint) {
125
- return Query.searchFrom(startingPoint, Joinpoint, (jp) => hasDefinedType(jp)).get();
126
- }
127
- return Query.search(Joinpoint, (jp) => hasDefinedType(jp)).get();
128
- }
129
-
130
- /**
131
- * Checks if a given joinpoint uses the specified tag declaration
132
- * @param $jp The joinpoint to analyze
133
- * @param tag The tag to check against
134
- * @returns Returns true if the joinpoint uses the given tag, false otherwise
135
- */
136
- export function isTagUsed($jp: Joinpoint, tag: RecordJp | EnumDecl): boolean {
137
- const jpType = getBaseType($jp);
138
- return jpType instanceof ElaboratedType &&
139
- jpType.namedType instanceof TagType &&
140
- jpType.namedType.decl.astId === tag.astId &&
141
- $jp.astId !== getTypeDecl(tag)?.astId
142
- }
143
-
144
- /**
145
- * Retrieves all joinpoints that use the specified tag declaration
146
- *
147
- * @param tag The tag to search for in the joinpoints
148
- * @returns Array of joinpoints that use the specified tag declaration
149
- */
150
- export function getTagUses(tag: RecordJp | EnumDecl): Joinpoint[] {
151
- return getTypedJps().filter(jp => isTagUsed(jp, tag));
152
- }
153
-
154
- /**
155
- * Retrieves the last statement of the given case
156
- * @param $jp - The case to retrieve the last statement from
157
- * @returns The last statement of the case or undefined if there are no statements or it has a consecutive case.
158
- */
159
- export function getLastStmtOfCase($jp: Case): Joinpoint | undefined {
160
- if ($jp.instructions.length === 0) { // Has a consecutive case
161
- return undefined;
162
- }
163
-
164
- let lastStmt: Joinpoint | undefined;
165
- for (const stmt of $jp.siblingsRight) {
166
- if (stmt instanceof Case) {
167
- break;
168
- }
169
- lastStmt = stmt;
170
- }
171
- return lastStmt;
172
- }
173
-
174
- /**
175
- * Retrieves the number of switch clauses with instructions in the provided switch statement
176
- * @param $jp - The switch statement to analyze
177
- * @returns The number of switch clauses with instructions
178
- */
179
- export function getNumOfSwitchClauses($jp: Switch): number {
180
- let firstStatements = []
181
-
182
- for (const caseLabel of $jp.cases) {
183
- if (caseLabel.instructions.length === 0) { // Has a consecutive case
184
- continue;
185
- }
186
- firstStatements.push(caseLabel.instructions[0])
187
- }
188
- return firstStatements.length;
189
- }
190
-
191
- /**
192
- * Checks if the provided switch statement has a Boolean condition
193
- * @param switchStmt The switch statement to check
194
- * @returns Returns true if the switch statement has a Boolean condition, otherwise false
195
- */
196
- export function switchHasBooleanCondition(switchStmt: Switch): boolean {
197
- return switchStmt.condition instanceof BinaryOp ||
198
- (hasDefinedType(switchStmt.condition) &&
199
- switchStmt.condition.type instanceof BuiltinType &&
200
- switchStmt.condition.type.builtinKind === "Bool"
201
- );
202
- }
203
-
204
- /**
205
- * Checks if the provided switch statement contains any conditional break
206
- *
207
- * @param switchStmt - The switch statement to analyze
208
- * @returns Returns true if the switch statement contains a conditional break, otherwise false
209
- */
210
- export function switchHasConditionalBreak(switchStmt: Switch): boolean {
211
- return Query.searchFrom(switchStmt, Break, { currentRegion: region => region.astId !== switchStmt.astId, enclosingStmt: jp => jp.astId === switchStmt.astId }).get().length > 0;
212
- }
213
-
214
- /**
215
- * Checks if a file compiles correctly after adding a statement by rebuilding it.
216
- * If rebuilding fails, the file is considered invalid with the new statement.
217
- *
218
- * @param fileJp - The file to validate.
219
- */
220
- export function isValidFile(fileJp: FileJp) : boolean {
221
- const programJp = fileJp.parent as Program;
222
- let copyFile = ClavaJoinPoints.fileWithSource(`temp_misra_${fileJp.name}`, fileJp.code, fileJp.relativeFolderpath);
223
-
224
- copyFile = programJp.addFile(copyFile) as FileJp;
225
- try {
226
- const rebuiltFile = copyFile.rebuild();
227
- const fileToRemove = Query.searchFrom(programJp, FileJp, {filepath: rebuiltFile.filepath}).first();
228
- fileToRemove?.detach();
229
- return true;
230
- } catch(error) {
231
- copyFile.detach();
232
- return false;
233
- }
234
- }
235
-
236
- /**
237
- * Retrieves the list of header files included in the given file
238
- *
239
- * @param fileJp The file join point
240
- * @returns An array of strings with the names of the includes
241
- */
242
- export function getIncludesOfFile(fileJp: FileJp): string[] {
243
- return fileJp.includes.map(includeJp => includeJp.name);
244
- }
245
-
246
- /**
247
- * Removes a specific include directive from the given file, if it exists
248
- *
249
- * @param includeName The name of the include to remove
250
- * @param fileJp The file from which the include should be removed
251
- */
252
- export function removeIncludeFromFile(includeName: string, fileJp: FileJp) {
253
- const include = Query.searchFrom(fileJp, Include, {name: includeName}).first();
254
- include?.detach();
255
- }
256
-
257
- /**
258
- * Check if the given joinpoint represents a call to an implicit function.
259
- *
260
- * @param callJp The call join point to analyze
261
- */
262
- export function isCallToImplicitFunction(callJp: Call): boolean {
263
- return callJp.function.definitionJp === undefined && !callJp.function.isInSystemHeader;
264
- }
265
-
266
- /**
267
- * Returns all files in the program that contain at least one call to an implicit function
268
- *
269
- * @param programJp - The program to analyze
270
- * @returns A list of files with implicit function calls
271
- */
272
- export function getFilesWithCallToImplicitFunction(programJp: Program): FileJp[] {
273
- const files = Query.searchFrom(programJp, FileJp).get();
274
- return files.filter(
275
- (fileJp) =>
276
- Query.searchFrom(fileJp, Call, (callJp) =>
277
- isCallToImplicitFunction(callJp)
278
- ).get().length > 0
279
- );
280
- }