@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.
- package/.gitignore +8 -0
- package/README.md +53 -19
- package/dist/MISRA.d.ts +28 -10
- package/dist/MISRA.d.ts.map +1 -1
- package/dist/MISRA.js +30 -10
- package/dist/MISRA.js.map +1 -1
- package/dist/MISRAContext.d.ts +65 -11
- package/dist/MISRAContext.d.ts.map +1 -1
- package/dist/MISRAContext.js +131 -35
- package/dist/MISRAContext.js.map +1 -1
- package/dist/MISRARule.d.ts +38 -25
- package/dist/MISRARule.d.ts.map +1 -1
- package/dist/MISRARule.js +40 -18
- package/dist/MISRARule.js.map +1 -1
- package/dist/MISRATool.d.ts +39 -5
- package/dist/MISRATool.d.ts.map +1 -1
- package/dist/MISRATool.js +102 -46
- package/dist/MISRATool.js.map +1 -1
- package/dist/StandardGuideline.d.ts +22 -0
- package/dist/StandardGuideline.d.ts.map +1 -0
- package/dist/StandardGuideline.js +12 -0
- package/dist/StandardGuideline.js.map +1 -0
- package/dist/ast-visitor/Context.d.ts +11 -0
- package/dist/ast-visitor/Context.d.ts.map +1 -0
- package/dist/ast-visitor/Context.js +15 -0
- package/dist/ast-visitor/Context.js.map +1 -0
- package/dist/ast-visitor/Visit.d.ts +23 -0
- package/dist/ast-visitor/Visit.d.ts.map +1 -0
- package/dist/ast-visitor/Visit.js +18 -0
- package/dist/ast-visitor/Visit.js.map +1 -0
- package/dist/ast-visitor/VisitWithContext.d.ts +32 -0
- package/dist/ast-visitor/VisitWithContext.d.ts.map +1 -0
- package/dist/ast-visitor/VisitWithContext.js +26 -0
- package/dist/ast-visitor/VisitWithContext.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts +27 -0
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts.map +1 -0
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js +98 -0
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js.map +1 -0
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts +45 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js +91 -8
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts +15 -5
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js +20 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts +11 -5
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js +13 -10
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts +11 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js +19 -11
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts +15 -5
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js +24 -10
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts +22 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js +37 -10
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts +66 -0
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts.map +1 -0
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js +209 -0
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js.map +1 -0
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts +37 -12
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js +112 -39
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts +15 -5
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js +21 -7
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts +11 -6
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js +17 -8
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js.map +1 -1
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts +105 -0
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js +258 -0
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts +29 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js +31 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts +30 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js +32 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js.map +1 -0
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts +6 -14
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js +17 -27
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts +13 -7
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js +31 -17
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts +26 -7
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js +32 -14
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts +48 -6
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js +84 -34
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js.map +1 -1
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts +24 -5
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts.map +1 -1
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js +27 -7
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js.map +1 -1
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts +46 -0
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js +40 -0
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts +25 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js +46 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts +26 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js +54 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts +27 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js +55 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts +24 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js +42 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts +24 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js +42 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts +35 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js +98 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts +35 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js +76 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts +32 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js +57 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js.map +1 -0
- package/dist/rules/UserConfigurableRule.d.ts +55 -0
- package/dist/rules/UserConfigurableRule.d.ts.map +1 -0
- package/dist/rules/UserConfigurableRule.js +16 -0
- package/dist/rules/UserConfigurableRule.js.map +1 -0
- package/dist/rules/index.d.ts +11 -18
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +47 -7
- package/dist/rules/index.js.map +1 -1
- package/dist/tests/Section17_Functions/misra_config.json +10 -0
- package/dist/tests/Section21-StandardLibraries/misra_config.json +88 -0
- package/dist/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
- package/dist/tests/utils.d.ts +6 -3
- package/dist/tests/utils.d.ts.map +1 -1
- package/dist/tests/utils.js +33 -7
- package/dist/tests/utils.js.map +1 -1
- package/dist/utils/CallUtils.d.ts +15 -0
- package/dist/utils/CallUtils.d.ts.map +1 -0
- package/dist/utils/CallUtils.js +34 -0
- package/dist/utils/CallUtils.js.map +1 -0
- package/dist/utils/CommentUtils.d.ts +21 -0
- package/dist/utils/CommentUtils.d.ts.map +1 -0
- package/dist/utils/CommentUtils.js +27 -0
- package/dist/utils/CommentUtils.js.map +1 -0
- package/dist/utils/FileUtils.d.ts +51 -0
- package/dist/utils/FileUtils.d.ts.map +1 -0
- package/dist/utils/FileUtils.js +121 -0
- package/dist/utils/FileUtils.js.map +1 -0
- package/dist/utils/FunctionUtils.d.ts +25 -0
- package/dist/utils/FunctionUtils.d.ts.map +1 -0
- package/dist/utils/FunctionUtils.js +65 -0
- package/dist/utils/FunctionUtils.js.map +1 -0
- package/dist/utils/IdentifierUtils.d.ts +14 -0
- package/dist/utils/IdentifierUtils.d.ts.map +1 -0
- package/dist/utils/IdentifierUtils.js +87 -0
- package/dist/utils/IdentifierUtils.js.map +1 -0
- package/dist/utils/JoinpointUtils.d.ts +19 -0
- package/dist/utils/JoinpointUtils.d.ts.map +1 -0
- package/dist/utils/JoinpointUtils.js +46 -0
- package/dist/utils/JoinpointUtils.js.map +1 -0
- package/dist/utils/ProgramUtils.d.ts +14 -0
- package/dist/utils/ProgramUtils.d.ts.map +1 -0
- package/dist/utils/ProgramUtils.js +72 -0
- package/dist/utils/ProgramUtils.js.map +1 -0
- package/dist/utils/SwitchUtils.d.ts +21 -0
- package/dist/utils/SwitchUtils.d.ts.map +1 -0
- package/dist/utils/SwitchUtils.js +47 -0
- package/dist/utils/SwitchUtils.js.map +1 -0
- package/dist/utils/TypeDeclUtils.d.ts +35 -0
- package/dist/utils/TypeDeclUtils.d.ts.map +1 -0
- package/dist/utils/TypeDeclUtils.js +78 -0
- package/dist/utils/TypeDeclUtils.js.map +1 -0
- package/dist/utils/VarUtils.d.ts +19 -0
- package/dist/utils/VarUtils.d.ts.map +1 -0
- package/dist/utils/VarUtils.js +59 -0
- package/dist/utils/VarUtils.js.map +1 -0
- package/package.json +16 -6
- package/src/MISRA.ts +33 -17
- package/src/MISRAContext.ts +128 -30
- package/src/MISRARule.ts +61 -29
- package/src/MISRATool.ts +108 -42
- package/src/StandardGuideline.ts +23 -0
- package/src/ast-visitor/Context.ts +16 -0
- package/src/ast-visitor/Visit.ts +26 -0
- package/src/ast-visitor/VisitWithContext.ts +42 -0
- package/src/main.ts +1 -1
- package/src/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.ts +114 -0
- package/src/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.ts +103 -13
- package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +24 -10
- package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +17 -8
- package/src/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.ts +20 -12
- package/src/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.ts +23 -12
- package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +44 -13
- package/src/rules/Section17_Functions/Rule_17_3_ImplicitFunction.ts +153 -104
- package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +114 -44
- package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +27 -10
- package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +20 -12
- package/src/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.ts +317 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.ts +30 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.ts +35 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.ts +30 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.ts +30 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.ts +29 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.ts +36 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.ts +30 -0
- package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +14 -29
- package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +33 -19
- package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +33 -20
- package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +90 -45
- package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +27 -8
- package/src/rules/Section5_Identifiers/IdentifierRenameRule.ts +63 -0
- package/src/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.ts +52 -0
- package/src/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.ts +62 -0
- package/src/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.ts +61 -0
- package/src/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.ts +47 -0
- package/src/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.ts +47 -0
- package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.ts +118 -0
- package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.ts +89 -0
- package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.ts +65 -0
- package/src/rules/UserConfigurableRule.ts +60 -0
- package/src/rules/index.ts +45 -7
- package/src/tests/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.test.ts +114 -0
- package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +7 -5
- package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +40 -13
- package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +10 -12
- package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +5 -5
- package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +5 -5
- package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +5 -5
- package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions.test.ts +68 -40
- package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_MissingConfig.test.ts +98 -0
- package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_ProblematicConfig.test.ts +71 -0
- package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +103 -49
- package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +7 -7
- package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -7
- package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +25 -21
- package/src/tests/Section17_Functions/misra_config.json +4 -3
- package/src/tests/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.test.ts +62 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.test.ts +67 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.test.ts +84 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_MissingConfig.test.ts +33 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_ProblematicConfig.test.ts +71 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.test.ts +63 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.test.ts +91 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.test.ts +65 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.test.ts +89 -0
- package/src/tests/Section21-StandardLibraries/misra_config.json +88 -0
- package/src/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
- package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +148 -113
- package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +243 -163
- package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +32 -20
- package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +36 -30
- package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -8
- package/src/tests/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.test.ts +78 -0
- package/src/tests/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.test.ts +120 -0
- package/src/tests/Section5_Identifiers/Rule_5_7_UniqueTagNames.test.ts +51 -0
- package/src/tests/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.test.ts +73 -0
- package/src/tests/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.test.ts +97 -0
- package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.test.ts +160 -0
- package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.test.ts +46 -0
- package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.test.ts +69 -0
- package/src/tests/utils.ts +32 -7
- package/src/utils/CallUtils.ts +40 -0
- package/src/utils/CommentUtils.ts +29 -0
- package/src/utils/FileUtils.ts +141 -0
- package/src/utils/FunctionUtils.ts +75 -0
- package/src/utils/IdentifierUtils.ts +94 -0
- package/src/utils/JoinpointUtils.ts +53 -0
- package/src/utils/ProgramUtils.ts +83 -0
- package/src/utils/SwitchUtils.ts +52 -0
- package/src/utils/TypeDeclUtils.ts +89 -0
- package/src/utils/VarUtils.ts +70 -0
- package/tsconfig.json +2 -1
- package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +0 -120
- package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +0 -36
- package/src/utils/utils.ts +0 -280
package/src/MISRARule.ts
CHANGED
|
@@ -1,56 +1,64 @@
|
|
|
1
|
-
import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
|
|
1
|
+
import { Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
2
|
import MISRAContext from "./MISRAContext.js";
|
|
3
|
-
import { MISRATransformationReport } from "./MISRA.js";
|
|
3
|
+
import { AnalysisType, MISRATransformationReport, MISRATransformationResults } from "./MISRA.js";
|
|
4
|
+
import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
|
|
5
|
+
import Clava from "@specs-feup/clava/api/clava/Clava.js";
|
|
6
|
+
import Query from "@specs-feup/lara/api/weaver/Query.js";
|
|
7
|
+
import { resetCaches } from "./utils/ProgramUtils.js";
|
|
8
|
+
import StandardGuideline from "./StandardGuideline.js";
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* Represents a MISRA Rule that detects and corrects violations in the code according to MISRA standards.
|
|
7
12
|
*
|
|
8
|
-
* Need to implement:
|
|
13
|
+
* Need to implement/define:
|
|
14
|
+
* - analysisType
|
|
15
|
+
* - name()
|
|
9
16
|
* - match($jp, logErrors)
|
|
10
|
-
* -
|
|
17
|
+
* - apply($jp)
|
|
11
18
|
*/
|
|
12
|
-
export default abstract class MISRARule {
|
|
19
|
+
export default abstract class MISRARule extends StandardGuideline<MISRATransformationResults, MISRAContext> {
|
|
13
20
|
/**
|
|
14
|
-
*
|
|
21
|
+
* A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
|
|
22
|
+
* By default, a rule has the lowest priority unless overridden.
|
|
15
23
|
*/
|
|
16
|
-
readonly
|
|
24
|
+
readonly priority: number = Number.MAX_VALUE;
|
|
17
25
|
|
|
18
26
|
/**
|
|
19
|
-
*
|
|
27
|
+
* Scope of analysis: single unit or entire system.
|
|
20
28
|
*/
|
|
21
|
-
readonly
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
25
|
-
*/
|
|
26
|
-
protected
|
|
29
|
+
abstract readonly analysisType: AnalysisType;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Standards to which this rule applies to
|
|
33
|
+
*/
|
|
34
|
+
protected readonly appliesTo: Set<string> = new Set(["c90", "c99", "c11"]);
|
|
27
35
|
|
|
28
36
|
/**
|
|
29
37
|
*
|
|
30
|
-
* @param ruleID - Unique identifier for the MISRA-C rule
|
|
31
38
|
* @param context - MISRA context for error tracking and rule transformations state
|
|
32
39
|
*/
|
|
33
|
-
constructor(
|
|
34
|
-
|
|
35
|
-
this.context = context;
|
|
40
|
+
constructor(context: MISRAContext) {
|
|
41
|
+
super(context);
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
/**
|
|
39
|
-
*
|
|
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
|
|
45
|
+
* @returns Initial value stored in the shared context
|
|
44
46
|
*/
|
|
45
|
-
|
|
47
|
+
override initialValue(): MISRATransformationResults {
|
|
48
|
+
return new Map();
|
|
49
|
+
}
|
|
46
50
|
|
|
47
51
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* @param $jp - Joinpoint to transform
|
|
51
|
-
* @returns Report detailing the transformation result
|
|
52
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
52
53
|
*/
|
|
53
|
-
abstract
|
|
54
|
+
abstract override get name(): string;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* An alias for 'name'
|
|
58
|
+
*/
|
|
59
|
+
get ruleID(): string {
|
|
60
|
+
return this.name;
|
|
61
|
+
}
|
|
54
62
|
|
|
55
63
|
/**
|
|
56
64
|
* Logs a MISRA-C rule violation error
|
|
@@ -61,4 +69,28 @@ export default abstract class MISRARule {
|
|
|
61
69
|
protected logMISRAError($jp: Joinpoint, msg:string): void {
|
|
62
70
|
this.context.addMISRAError(this.ruleID, $jp, msg);
|
|
63
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Verifies if the rule applies to the standard being used
|
|
75
|
+
*/
|
|
76
|
+
protected appliesToCurrentStandard(): boolean {
|
|
77
|
+
return this.appliesTo.has(Clava.getStandard());
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Rebuilds the program based on the current AST, clears stored data in the shared context, and resets all caches
|
|
82
|
+
*/
|
|
83
|
+
protected rebuildProgram() {
|
|
84
|
+
(Query.root() as Program).rebuild();
|
|
85
|
+
this.context.resetStorage();
|
|
86
|
+
resetCaches();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Transforms the joinpoint to comply with the MISRA-C rule
|
|
91
|
+
*
|
|
92
|
+
* @param $jp - Joinpoint to transform
|
|
93
|
+
* @returns Report detailing the transformation result
|
|
94
|
+
*/
|
|
95
|
+
abstract apply($jp: LaraJoinPoint): MISRATransformationReport;
|
|
64
96
|
}
|
package/src/MISRATool.ts
CHANGED
|
@@ -1,33 +1,25 @@
|
|
|
1
1
|
import Query from "@specs-feup/lara/api/weaver/Query.js";
|
|
2
|
-
import {
|
|
2
|
+
import { FileJp, Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
|
|
3
3
|
import MISRARule from "./MISRARule.js";
|
|
4
|
-
import sortRules from "./rules/index.js";
|
|
5
4
|
import MISRAContext from "./MISRAContext.js";
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
5
|
+
import { MISRATransformationType } from "./MISRA.js";
|
|
6
|
+
import Clava from "@specs-feup/clava/api/clava/Clava.js";
|
|
7
|
+
import { resetCaches } from "./utils/ProgramUtils.js";
|
|
8
|
+
import { selectRules } from "./rules/index.js";
|
|
9
|
+
|
|
10
|
+
enum ExecutionMode {
|
|
11
|
+
CORRECTION,
|
|
12
|
+
DETECTION
|
|
13
|
+
}
|
|
8
14
|
|
|
9
15
|
export default class MISRATool {
|
|
10
16
|
static #misraRules: MISRARule[];
|
|
11
|
-
static
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
}
|
|
17
|
+
public static context: MISRAContext;
|
|
18
|
+
static readonly #standards = new Set(["c90", "c99", "c11"]);
|
|
19
|
+
static readonly #ruleTypes = new Set(["all", "single", "system"]);
|
|
28
20
|
|
|
29
21
|
public static checkCompliance(startingPoint: Program | FileJp = Query.root() as Program) {
|
|
30
|
-
this.init(
|
|
22
|
+
this.init();
|
|
31
23
|
|
|
32
24
|
const nodes = [startingPoint, ...startingPoint.descendants];
|
|
33
25
|
for (const node of nodes) {
|
|
@@ -35,39 +27,42 @@ export default class MISRATool {
|
|
|
35
27
|
rule.match(node, true);
|
|
36
28
|
}
|
|
37
29
|
}
|
|
38
|
-
|
|
39
|
-
this.#context.printAllErrors();
|
|
40
|
-
} else {
|
|
41
|
-
console.log("[Clava-MISRATool] No MISRA-C violations detected.");
|
|
42
|
-
}
|
|
30
|
+
this.outputReport(ExecutionMode.DETECTION);
|
|
43
31
|
}
|
|
44
32
|
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Transforms the source code to comply with the coding guidelines.
|
|
35
|
+
* After the transformation, any violations that could not be fixed will be displayed along with their justification.
|
|
36
|
+
*/
|
|
37
|
+
public static correctViolations() {
|
|
38
|
+
this.init();
|
|
39
|
+
|
|
40
|
+
// Store config file in context, if provided
|
|
41
|
+
const configFilePath = this.getArgValue("config");
|
|
47
42
|
if (configFilePath) {
|
|
48
|
-
this
|
|
43
|
+
this.context.config = configFilePath;
|
|
49
44
|
}
|
|
50
45
|
|
|
51
46
|
let iteration = 0;
|
|
52
|
-
let modified =
|
|
53
|
-
|
|
47
|
+
let modified = true;
|
|
48
|
+
while (modified) {
|
|
54
49
|
console.log(`[Clava-MISRATool] Iteration #${++iteration}: Applying MISRA-C transformations...`);
|
|
55
50
|
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
51
|
}
|
|
52
|
+
this.outputReport(ExecutionMode.CORRECTION);
|
|
64
53
|
}
|
|
65
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Recursively transforms the AST using a pre-order traversal
|
|
57
|
+
*
|
|
58
|
+
* @param $jp AST node from which to start the visit.
|
|
59
|
+
* @returns Return true if any modifications were made (removal, replacement, or changes in descendants). Otherwise, returns false.
|
|
60
|
+
*/
|
|
66
61
|
private static transformAST($jp: Joinpoint): boolean {
|
|
67
62
|
let modified = false;
|
|
68
63
|
|
|
69
64
|
for (const rule of this.#misraRules) {
|
|
70
|
-
const transformReport = rule.
|
|
65
|
+
const transformReport = rule.apply($jp);
|
|
71
66
|
|
|
72
67
|
if (transformReport.type !== MISRATransformationType.NoChange) {
|
|
73
68
|
modified = true;
|
|
@@ -85,11 +80,82 @@ export default class MISRATool {
|
|
|
85
80
|
return modified;
|
|
86
81
|
}
|
|
87
82
|
|
|
83
|
+
private static init() {
|
|
84
|
+
this.validateStdVersion();
|
|
85
|
+
this.context = new MISRAContext();
|
|
86
|
+
resetCaches();
|
|
87
|
+
this.initRules();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Selects applicable rules according to the analysis type. When not specified, both system and single translation unit rules are selected.
|
|
92
|
+
*/
|
|
93
|
+
private static initRules() {
|
|
94
|
+
const typeStr = this.getArgValue("type", this.#ruleTypes) ?? "all";
|
|
95
|
+
this.#misraRules = selectRules(this.context, typeStr);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Checks whether the provided standard version is valid and supported
|
|
100
|
+
*/
|
|
101
|
+
private static validateStdVersion() {
|
|
102
|
+
const stdVersion = (Query.root() as Program).standard;
|
|
103
|
+
|
|
104
|
+
if (!this.#standards.has(stdVersion)) {
|
|
105
|
+
console.error(`[Clava-MISRATool] Invalid -std value. Allowed values: ${[...this.#standards].join(", ")}`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private static getArgValue(field: string, validValues?: Set<string>): string | undefined{
|
|
111
|
+
const args = Clava.getData().get("argv") as string;
|
|
112
|
+
if (!args) return undefined;
|
|
113
|
+
|
|
114
|
+
const pair = args.split(/\s+/).find(arg => arg.startsWith(field + "="));
|
|
115
|
+
if (!pair) return undefined;
|
|
116
|
+
|
|
117
|
+
const value = pair.split("=")[1];
|
|
118
|
+
if (validValues && !validValues.has(value)) {
|
|
119
|
+
console.error(`[Clava-MISRATool] Invalid '${field}' value. Allowed values: ${[...validValues].join(", ")}`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Displays standard violations based on execution mode.
|
|
127
|
+
* - In detection mode, all violations are shown.
|
|
128
|
+
* - In correction mode, only the remaining violations are displayed
|
|
129
|
+
*
|
|
130
|
+
* @param mode execution mode
|
|
131
|
+
*/
|
|
132
|
+
private static outputReport(mode: ExecutionMode) {
|
|
133
|
+
const isDetection = mode === ExecutionMode.DETECTION;
|
|
134
|
+
const errorCount = isDetection ? this.getErrorCount() : this.getActiveErrorCount();
|
|
135
|
+
|
|
136
|
+
if (errorCount > 0) {
|
|
137
|
+
console.log(isDetection
|
|
138
|
+
? `[Clava-MISRATool] Detected ${errorCount} MISRA-C violation${errorCount === 1 ? "" : "s"}:\n`
|
|
139
|
+
: `[Clava-MISRATool] ${errorCount} MISRA-C violation${errorCount === 1 ? "" : "s"} remain${errorCount === 1 ? "s" : ""} after transformation:\n`
|
|
140
|
+
);
|
|
141
|
+
isDetection ? this.context.outputAllErrors() : this.context.outputActiveErrors();
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
console.log(isDetection ? "[Clava-MISRATool] No MISRA-C violations detected.\n" : "[Clava-MISRATool] All detected violations were corrected.\n");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @returns Returns the number of identified violations.
|
|
150
|
+
*/
|
|
88
151
|
public static getErrorCount(): number {
|
|
89
|
-
return this
|
|
152
|
+
return this.context.errors.length;
|
|
90
153
|
}
|
|
91
154
|
|
|
155
|
+
/**
|
|
156
|
+
* @returns Returns the number of active errors linked to nodes that are still present in the AST after correction.
|
|
157
|
+
*/
|
|
92
158
|
public static getActiveErrorCount(): number {
|
|
93
|
-
return this
|
|
159
|
+
return this.context.activeErrors.length;
|
|
94
160
|
}
|
|
95
161
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
|
+
import Context from "./ast-visitor/Context.js";
|
|
3
|
+
import VisitWithContext from "./ast-visitor/VisitWithContext.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents a standard guideline that detects and corrects violations in the code according to a particular coding standard.
|
|
7
|
+
*
|
|
8
|
+
* Need to implement/define:
|
|
9
|
+
* - initialValue()
|
|
10
|
+
* - match($jp, logErrors)
|
|
11
|
+
* - apply($jp)
|
|
12
|
+
*/
|
|
13
|
+
export default abstract class StandardGuideline<T,C extends Context<T> = Context<T>> extends VisitWithContext<T, C> {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Checks if the joinpoint violates the guideline
|
|
17
|
+
*
|
|
18
|
+
* @param $jp - Joinpoint to analyze
|
|
19
|
+
* @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
|
|
20
|
+
* @returns Returns true if the joinpoint violates the guideline, false otherwise
|
|
21
|
+
*/
|
|
22
|
+
abstract match($jp: Joinpoint, logErrors: boolean): boolean;
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key-value storage to share data between visits
|
|
3
|
+
*
|
|
4
|
+
* @template T Type of the stored values
|
|
5
|
+
*/
|
|
6
|
+
export default class Context<T> {
|
|
7
|
+
protected storage: Map<string, T> = new Map();
|
|
8
|
+
|
|
9
|
+
put(key: string, value: T) {
|
|
10
|
+
this.storage.set(key, value);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get(key: string): T | undefined {
|
|
14
|
+
return this.storage.get(key);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Common interface for AST transformations applied to a single node
|
|
5
|
+
*
|
|
6
|
+
* Need to implement:
|
|
7
|
+
* - apply($jp)
|
|
8
|
+
*
|
|
9
|
+
* @template T Type of data stored in the shared context
|
|
10
|
+
* @template C Type of the context (default is Context<T>)
|
|
11
|
+
*/
|
|
12
|
+
export default abstract class Visit {
|
|
13
|
+
/**
|
|
14
|
+
* Applies the transformation to the given node
|
|
15
|
+
* @param $jp The node to transform
|
|
16
|
+
* @returns Transformation result
|
|
17
|
+
*/
|
|
18
|
+
abstract apply($jp: LaraJoinPoint): unknown;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @returns List of dependent visits, which is empty by default
|
|
22
|
+
*/
|
|
23
|
+
get dependencies(): Visit[] {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
|
|
2
|
+
import Context from "./Context.js";
|
|
3
|
+
import Visit from "./Visit.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Visit with a shared context to enable communication between visits
|
|
7
|
+
*
|
|
8
|
+
* Need to implement:
|
|
9
|
+
* - apply($jp)
|
|
10
|
+
* - initialValue()
|
|
11
|
+
*/
|
|
12
|
+
export default abstract class VisitWithContext<T, C extends Context<T> = Context<T>> extends Visit {
|
|
13
|
+
protected context: C;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param context Shared context object
|
|
17
|
+
*/
|
|
18
|
+
constructor(context: C) {
|
|
19
|
+
super();
|
|
20
|
+
this.context = context;
|
|
21
|
+
this.context.put(this.name, this.initialValue());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @return Visit name, defaults to class name
|
|
26
|
+
*/
|
|
27
|
+
get name(): string {
|
|
28
|
+
return this.constructor.name;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @returns Initial value stored in the shared context
|
|
33
|
+
*/
|
|
34
|
+
abstract initialValue(): T;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Applies the transformation to the given node
|
|
38
|
+
* @param $jp The node to transform
|
|
39
|
+
* @returns Transformation result
|
|
40
|
+
*/
|
|
41
|
+
abstract apply($jp: LaraJoinPoint): unknown;
|
|
42
|
+
}
|
package/src/main.ts
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { BinaryOp, Call, FileJp, Joinpoint, ParenExpr, UnaryExprOrType, UnaryOp, VariableArrayType, Varref } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
|
+
import MISRARule from "../../MISRARule.js";
|
|
3
|
+
import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
4
|
+
import Query from "@specs-feup/lara/api/weaver/Query.js";
|
|
5
|
+
import { getVolatileVarRefs } from "../../utils/VarUtils.js";
|
|
6
|
+
import { isValidFile } from "../../utils/FileUtils.js";
|
|
7
|
+
import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* MISRA-C Rule 13.6: The operand of the sizeof operator shall not contain any expression which has potential side effects
|
|
11
|
+
*/
|
|
12
|
+
export default class Rule_13_6_SafeSizeOfOperand extends MISRARule {
|
|
13
|
+
/**
|
|
14
|
+
* Scope of analysis
|
|
15
|
+
*/
|
|
16
|
+
analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
|
|
17
|
+
|
|
18
|
+
#modifyingExpressions: (UnaryOp | BinaryOp)[] = [];
|
|
19
|
+
#functionCalls: Call[] = [];
|
|
20
|
+
#volatileRefs: Varref[] = [];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
24
|
+
*/
|
|
25
|
+
override get name(): string {
|
|
26
|
+
return "13.6";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private operandIsVariableArrayType($jp: UnaryExprOrType) {
|
|
30
|
+
return $jp.argType != undefined && $jp.argType instanceof VariableArrayType;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
* @param $jp - Joinpoint to analyze
|
|
36
|
+
* @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
|
|
37
|
+
* @returns Returns true if the joinpoint violates the rule, false otherwise
|
|
38
|
+
*/
|
|
39
|
+
match($jp: Joinpoint, logErrors: boolean = false): boolean {
|
|
40
|
+
if (!($jp instanceof UnaryExprOrType && $jp.kind === "sizeof")) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.#functionCalls = Query.searchFromInclusive($jp, Call).get();
|
|
45
|
+
this.#volatileRefs = this.operandIsVariableArrayType($jp) ? getVolatileVarRefs(($jp.argType as VariableArrayType).sizeExpr) : [];
|
|
46
|
+
this.#modifyingExpressions = [
|
|
47
|
+
...Query.searchFromInclusive($jp, UnaryOp, {kind: /(post_inc)|(post_dec)|(pre_inc)|(pre_dec)/}).get(),
|
|
48
|
+
...Query.searchFromInclusive($jp, BinaryOp, {kind: /(assign)|(add_assign)|(sub_assign)|(mul_assign)|(div_assign)|(rem_assign)|(shl_assign)|(shr_assign)|(and_assign)|(xor_assign)|(or_assign)/}).get()
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const isNonCompliant = this.#functionCalls.length > 0 || this.#modifyingExpressions.length > 0 || this.#volatileRefs.length > 0;
|
|
52
|
+
|
|
53
|
+
if (isNonCompliant && logErrors) {
|
|
54
|
+
this.#functionCalls.forEach(call => {
|
|
55
|
+
this.logMISRAError(call, `Function call '${call.name}' in sizeof is not allowed because it has no effect.`);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.#modifyingExpressions.forEach(expr => {
|
|
59
|
+
this.logMISRAError(expr, `Modifying expression '${expr.code}' in sizeof is not allowed because it has no effect.`);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
this.#volatileRefs.forEach(ref => {
|
|
63
|
+
this.logMISRAError(ref, `Access to volatile object ${ref.name} in sizeof is not allowed.`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return isNonCompliant;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
apply($jp: Joinpoint): MISRATransformationReport {
|
|
71
|
+
if (!this.match($jp)) {
|
|
72
|
+
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!this.operandIsVariableArrayType($jp as UnaryExprOrType)) {
|
|
76
|
+
for (const callJp of this.#functionCalls) {
|
|
77
|
+
const callAncestor = callJp.getAncestor("call");
|
|
78
|
+
if (callAncestor === undefined || callAncestor.depth < $jp.depth) {
|
|
79
|
+
const functionType = callJp.functionType.returnType;
|
|
80
|
+
const fileJp = callJp.getAncestor("file") as FileJp;
|
|
81
|
+
const tempJp = fileJp.lastChild.insertAfter(ClavaJoinPoints.stmtLiteral(`static int _temp_misra_var = sizeof(${functionType.code});`));
|
|
82
|
+
const jpIndex = Query.searchFrom(fileJp, UnaryExprOrType).get().length;
|
|
83
|
+
|
|
84
|
+
let newSizeOf = isValidFile(fileJp, UnaryExprOrType, jpIndex) as UnaryExprOrType;
|
|
85
|
+
newSizeOf = $jp.replaceWith(newSizeOf) as UnaryExprOrType;
|
|
86
|
+
newSizeOf.setArgType(functionType);
|
|
87
|
+
tempJp.detach();
|
|
88
|
+
return new MISRATransformationReport(MISRATransformationType.Replacement, newSizeOf);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const expr of this.#modifyingExpressions) {
|
|
93
|
+
let varRef = expr instanceof BinaryOp ?
|
|
94
|
+
expr.left : Query.searchFrom(expr, Varref).get()[0];
|
|
95
|
+
expr.replaceWith(varRef);
|
|
96
|
+
}
|
|
97
|
+
return new MISRATransformationReport(MISRATransformationType.DescendantChange);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
this.#functionCalls.forEach(call => {
|
|
101
|
+
this.logMISRAError(call, `Function call '${call.name}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
this.#modifyingExpressions.forEach(expr => {
|
|
105
|
+
this.logMISRAError(expr, `Modifying expression '${expr.code}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
this.#volatileRefs.forEach(ref => {
|
|
109
|
+
this.logMISRAError(ref,`Access to volatile object '${ref.name}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
|
|
110
|
+
});
|
|
111
|
+
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|