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