├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── README.md ├── oclint-core ├── CMakeLists.txt ├── LICENSE ├── cmake │ └── OCLintConfig.cmake ├── include │ └── oclint │ │ ├── AbstractResults.h │ │ ├── RawResults.h │ │ ├── Reporter.h │ │ ├── ResultCollector.h │ │ ├── Results.h │ │ ├── RuleBase.h │ │ ├── RuleCarrier.h │ │ ├── RuleConfiguration.h │ │ ├── RuleSet.h │ │ ├── UniqueResults.h │ │ ├── Version.h │ │ ├── Violation.h │ │ └── ViolationSet.h ├── lib │ ├── AbstractResults.cpp │ ├── CMakeLists.txt │ ├── RawResults.cpp │ ├── ResultCollector.cpp │ ├── RuleBase.cpp │ ├── RuleCarrier.cpp │ ├── RuleConfiguration.cpp │ ├── RuleSet.cpp │ ├── UniqueResults.cpp │ ├── Version.cpp │ ├── Violation.cpp │ └── ViolationSet.cpp └── test │ ├── CMakeLists.txt │ ├── CanaryTest.cpp │ ├── RawResultsTest.cpp │ ├── ResultCollectorTest.cpp │ ├── RuleBaseTest.cpp │ ├── RuleCarrierTest.cpp │ ├── RuleConfigurationTest.cpp │ ├── RuleSetTest.cpp │ ├── UniqueResultsTest.cpp │ ├── VersionTest.cpp │ ├── ViolationSetTest.cpp │ └── ViolationTest.cpp ├── oclint-driver ├── CMakeLists.txt ├── LICENSE ├── include │ └── oclint │ │ ├── Analytics.h │ │ ├── Analyzer.h │ │ ├── CompilerInstance.h │ │ ├── ConfigFile.h │ │ ├── DiagnosticDispatcher.h │ │ ├── Driver.h │ │ ├── ExitCode.h │ │ ├── GenericException.h │ │ ├── Logger.h │ │ ├── Options.h │ │ ├── RulesetBasedAnalyzer.h │ │ └── RulesetFilter.h ├── lib │ ├── Analytics.cpp │ ├── CMakeLists.txt │ ├── CompilerInstance.cpp │ ├── ConfigFile.cpp │ ├── DiagnosticDispatcher.cpp │ ├── Driver.cpp │ ├── GenericException.cpp │ ├── Logger.cpp │ ├── Options.cpp │ ├── RulesetBasedAnalyzer.cpp │ └── RulesetFilter.cpp ├── main.cpp ├── main_docgen.cpp ├── reporters.h ├── reporters_dlfcn_port.cpp ├── reporters_windows_port.cpp ├── rules.h ├── rules_dlfcn_port.cpp ├── rules_windows_port.cpp └── test │ ├── CMakeLists.txt │ └── RulesetFilterTest.cpp ├── oclint-metrics ├── CMakeLists.txt ├── LICENSE ├── include │ └── oclint │ │ └── metric │ │ ├── CyclomaticComplexityMetric.h │ │ ├── NPathComplexityMetric.h │ │ ├── NcssMetric.h │ │ └── StmtDepthMetric.h ├── lib │ ├── CMakeLists.txt │ ├── CyclomaticComplexityMetric.cpp │ ├── NPathComplexityMetric.cpp │ ├── NcssMetric.cpp │ └── StmtDepthMetric.cpp └── test │ ├── CMakeLists.txt │ ├── CanaryTest.cpp │ ├── CyclomaticComplexityMetricTest.cpp │ ├── NPathComplexityMetricTest.cpp │ ├── NcssMetricTest.cpp │ ├── StmtDepthMetricTest.cpp │ └── headers │ └── TestHeaders.h ├── oclint-reporters ├── CMakeLists.txt ├── LICENSE ├── reporters │ ├── CMakeLists.txt │ ├── HTMLReporter.cpp │ ├── JSONReporter.cpp │ ├── PMDReporter.cpp │ ├── TextReporter.cpp │ ├── XMLReporter.cpp │ └── XcodeReporter.cpp ├── template │ ├── Reporter.tmpl │ └── ReporterTest.tmpl └── test │ ├── CMakeLists.txt │ ├── CanaryTest.cpp │ ├── HTMLReporterTest.cpp │ ├── JSONReporterTest.cpp │ ├── PMDReporterTest.cpp │ ├── ReportTestResults.h │ ├── TextReporterTest.cpp │ ├── XMLReporterTest.cpp │ └── XcodeReporterTest.cpp ├── oclint-rules ├── CMakeLists.txt ├── LICENSE ├── include │ └── oclint │ │ ├── AbstractASTMatcherRule.h │ │ ├── AbstractASTRuleBase.h │ │ ├── AbstractASTVisitorRule.h │ │ ├── AbstractSourceCodeReaderRule.h │ │ ├── helper │ │ ├── AttributeHelper.h │ │ ├── EnforceHelper.h │ │ └── SuppressHelper.h │ │ └── util │ │ ├── ASTUtil.h │ │ └── StdUtil.h ├── lib │ ├── AbstractASTMatcherRule.cpp │ ├── AbstractASTRuleBase.cpp │ ├── AbstractSourceCodeReaderRule.cpp │ ├── CMakeLists.txt │ ├── helper │ │ ├── AttributeHelper.cpp │ │ ├── CMakeLists.txt │ │ ├── EnforceHelper.cpp │ │ └── SuppressHelper.cpp │ └── util │ │ ├── ASTUtil.cpp │ │ ├── CMakeLists.txt │ │ └── StdUtil.cpp ├── rules │ ├── CMakeLists.txt │ ├── abstract │ │ ├── AbstractEmptyBlockStmtRule.h │ │ └── AbstractNullCheckRule.h │ ├── basic │ │ ├── BitwiseOperatorInConditionalRule.cpp │ │ ├── BrokenNullCheckRule.cpp │ │ ├── BrokenOddnessCheckRule.cpp │ │ ├── CMakeLists.txt │ │ ├── CollapsibleIfStatementsRule.cpp │ │ ├── ConstantConditionalOperatorRule.cpp │ │ ├── ConstantIfExpressionRule.cpp │ │ ├── DeadCodeRule.cpp │ │ ├── DoubleNegativeRule.cpp │ │ ├── ForLoopShouldBeWhileLoopRule.cpp │ │ ├── GotoStatementRule.cpp │ │ ├── JumbledIncrementerRule.cpp │ │ ├── MisplacedNullCheckRule.cpp │ │ ├── MultipleUnaryOperatorRule.cpp │ │ ├── ReturnFromFinallyBlockRule.cpp │ │ └── ThrowExceptionFromFinallyBlockRule.cpp │ ├── cocoa │ │ ├── CMakeLists.txt │ │ ├── ObjCVerifyIsEqualHashRule.cpp │ │ ├── ObjCVerifyMustCallSuperRule.cpp │ │ ├── ObjCVerifyProhibitedCallRule.cpp │ │ ├── ObjCVerifyProtectedMethodRule.cpp │ │ └── ObjCVerifySubclassMustImplementRule.cpp │ ├── convention │ │ ├── AvoidBranchingStatementAsLastInLoopRule.cpp │ │ ├── BaseClassDestructorShouldBeVirtualOrProtectedRule.cpp │ │ ├── CMakeLists.txt │ │ ├── CoveredSwitchStatementsDontNeedDefaultRule.cpp │ │ ├── DefaultLabelNotLastInSwitchStatementRule.cpp │ │ ├── DestructorOfVirtualClassRule.cpp │ │ ├── InvertedLogicRule.cpp │ │ ├── MissingBreakInSwitchStatementRule.cpp │ │ ├── NonCaseLabelInSwitchStatementRule.cpp │ │ ├── ObjCAssignIvarOutsideAccessorsRule.cpp │ │ ├── ParameterReassignmentRule.cpp │ │ ├── PreferEarlyExitRule.cpp │ │ ├── SwitchStatementsShouldHaveDefaultRule.cpp │ │ └── TooFewBranchesInSwitchStatementRule.cpp │ ├── design │ │ ├── AvoidDefaultArgumentsOnVirtualMethodsRule.cpp │ │ ├── AvoidPrivateStaticMembersRule.cpp │ │ ├── CMakeLists.txt │ │ └── FeatureEnvyRule.cpp │ ├── empty │ │ ├── CMakeLists.txt │ │ ├── EmptyCatchStatementRule.cpp │ │ ├── EmptyDoWhileStatementRule.cpp │ │ ├── EmptyElseBlockRule.cpp │ │ ├── EmptyFinallyStatementRule.cpp │ │ ├── EmptyForStatementRule.cpp │ │ ├── EmptyIfStatementRule.cpp │ │ ├── EmptySwitchStatementRule.cpp │ │ ├── EmptyTryStatementRule.cpp │ │ └── EmptyWhileStatementRule.cpp │ ├── migration │ │ ├── CMakeLists.txt │ │ ├── ObjCBoxedExpressionsRule.cpp │ │ ├── ObjCContainerLiteralsRule.cpp │ │ ├── ObjCNSNumberLiteralsRule.cpp │ │ └── ObjCObjectSubscriptingRule.cpp │ ├── naming │ │ ├── CMakeLists.txt │ │ ├── LongVariableNameRule.cpp │ │ └── ShortVariableNameRule.cpp │ ├── redundant │ │ ├── CMakeLists.txt │ │ ├── RedundantConditionalOperatorRule.cpp │ │ ├── RedundantIfStatementRule.cpp │ │ ├── RedundantLocalVariableRule.cpp │ │ ├── RedundantNilCheckRule.cpp │ │ ├── UnnecessaryElseStatementRule.cpp │ │ ├── UnnecessaryNullCheckForCXXDeallocRule.cpp │ │ └── UselessParenthesesRule.cpp │ ├── size │ │ ├── CMakeLists.txt │ │ ├── CyclomaticComplexityRule.cpp │ │ ├── LongClassRule.cpp │ │ ├── LongLineRule.cpp │ │ ├── LongMethodRule.cpp │ │ ├── NPathComplexityRule.cpp │ │ ├── NcssMethodCountRule.cpp │ │ ├── NestedBlockDepthRule.cpp │ │ ├── TooManyFieldsRule.cpp │ │ ├── TooManyMethodsRule.cpp │ │ └── TooManyParametersRule.cpp │ └── unused │ │ ├── CMakeLists.txt │ │ ├── UnusedLocalVariableRule.cpp │ │ └── UnusedMethodParameterRule.cpp ├── template │ ├── ASTMatcherRule.tmpl │ ├── ASTVisitorRule.tmpl │ ├── GenericRule.tmpl │ ├── RuleTest.tmpl │ └── SourceCodeReaderRule.tmpl └── test │ ├── CMakeLists.txt │ ├── CanaryTest.cpp │ ├── abstract │ ├── CMakeLists.txt │ ├── LanguageSelectionTest.cpp │ ├── MacroLocationTest.cpp │ └── TagBasedViolationTest.cpp │ ├── basic │ ├── BitwiseOperatorInConditionalRuleTest.cpp │ ├── BrokenNullCheckRuleTest.cpp │ ├── BrokenOddnessCheckRuleTest.cpp │ ├── CMakeLists.txt │ ├── CollapsibleIfStatementsRuleTest.cpp │ ├── ConstantConditionalOperatorRuleTest.cpp │ ├── ConstantIfExpressionRuleTest.cpp │ ├── DeadCodeRuleTest.cpp │ ├── DoubleNegativeRuleTest.cpp │ ├── ForLoopShouldBeWhileLoopRuleTest.cpp │ ├── GotoStatementRuleTest.cpp │ ├── JumbledIncrementerRuleTest.cpp │ ├── MisplacedNullCheckRuleTest.cpp │ ├── MultipleUnaryOperatorRuleTest.cpp │ ├── ReturnFromFinallyBlockRuleTest.cpp │ └── ThrowExceptionFromFinallyBlockRuleTest.cpp │ ├── cocoa │ ├── CMakeLists.txt │ ├── ObjCVerifyIsEqualHashRuleTest.cpp │ ├── ObjCVerifyMustCallSuperRuleTest.cpp │ ├── ObjCVerifyProhibitedCallRuleTest.cpp │ ├── ObjCVerifyProtectedMethodRuleTest.cpp │ └── ObjCVerifySubclassMustImplementRuleTest.cpp │ ├── convention │ ├── AvoidBranchingStatementAsLastInLoopRuleTest.cpp │ ├── BaseClassDestructorShouldBeVirtualOrProtectedRuleTest.cpp │ ├── CMakeLists.txt │ ├── CoveredSwitchStatementsDontNeedDefaultRuleTest.cpp │ ├── DefaultLabelNotLastInSwitchStatementRuleTest.cpp │ ├── DestructorOfVirtualClassRuleTest.cpp │ ├── InvertedLogicRuleTest.cpp │ ├── MissingBreakInSwitchStatementRuleTest.cpp │ ├── NonCaseLabelInSwitchStatementRuleTest.cpp │ ├── ObjCAssignIvarOutsideAccessorsRuleTest.cpp │ ├── ParameterReassignmentRuleTest.cpp │ ├── PreferEarlyExitRuleTest.cpp │ ├── SwitchStatementsShouldHaveDefaultRuleTest.cpp │ └── TooFewBranchesInSwitchStatementRuleTest.cpp │ ├── design │ ├── AvoidDefaultArgumentsOnVirtualMethodsRuleTest.cpp │ ├── AvoidPrivateStaticMembersRuleTest.cpp │ ├── CMakeLists.txt │ └── FeatureEnvyRuleTest.cpp │ ├── empty │ ├── CMakeLists.txt │ ├── EmptyCatchStatementRuleTest.cpp │ ├── EmptyDoWhileStatementRuleTest.cpp │ ├── EmptyElseBlockRuleTest.cpp │ ├── EmptyFinallyStatementRuleTest.cpp │ ├── EmptyForStatementRuleTest.cpp │ ├── EmptyIfStatementRuleTest.cpp │ ├── EmptySwitchStatementRuleTest.cpp │ ├── EmptyTryStatementRuleTest.cpp │ └── EmptyWhileStatementRuleTest.cpp │ ├── headers │ ├── TestEngine.h │ ├── TestRuleOnCode.cpp │ └── TestRuleOnCode.h │ ├── helper │ ├── AttributeHelperTest.cpp │ ├── CMakeLists.txt │ └── SuppressHelperTest.cpp │ ├── migration │ ├── CMakeLists.txt │ ├── ObjCBoxedExpressionsRuleTest.cpp │ ├── ObjCContainerLiteralsRuleTest.cpp │ ├── ObjCNSNumberLiteralsRuleTest.cpp │ └── ObjCObjectSubscriptingRuleTest.cpp │ ├── naming │ ├── CMakeLists.txt │ ├── LongVariableNameRuleTest.cpp │ └── ShortVariableNameRuleTest.cpp │ ├── redundant │ ├── CMakeLists.txt │ ├── RedundantConditionalOperatorRuleTest.cpp │ ├── RedundantIfStatementRuleTest.cpp │ ├── RedundantLocalVariableRuleTest.cpp │ ├── RedundantNilCheckRuleTest.cpp │ ├── UnnecessaryElseStatementRuleTest.cpp │ ├── UnnecessaryNullCheckForCXXDeallocRuleTest.cpp │ └── UselessParenthesesRuleTest.cpp │ ├── size │ ├── CMakeLists.txt │ ├── CyclomaticComplexityRuleTest.cpp │ ├── LongClassRuleTest.cpp │ ├── LongLineRuleTest.cpp │ ├── LongMethodRuleTest.cpp │ ├── NPathComplexityRuleTest.cpp │ ├── NcssMethodCountRuleTest.cpp │ ├── NestedBlockDepthRuleTest.cpp │ ├── TooManyFieldsRuleTest.cpp │ ├── TooManyMethodsRuleTest.cpp │ └── TooManyParametersRuleTest.cpp │ └── unused │ ├── CMakeLists.txt │ ├── UnusedLocalVariableRuleTest.cpp │ └── UnusedMethodParameterRuleTest.cpp └── oclint-scripts ├── LICENSE ├── README ├── build ├── bundle ├── ci ├── clang ├── countly ├── docGen ├── dogFooding ├── googleTest ├── make ├── makeWithSystemLLVM ├── oclintscripts ├── __init__.py ├── cmake.py ├── environment.py ├── path.py ├── process.py └── version.py ├── scaffoldReporter ├── scaffoldRule ├── test ├── travis └── upload /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Issue Summary 2 | A brief but thorough description of the issue. 3 | 4 | ### Environment 5 | - Operation system name and version: 6 | - OCLint version: 7 | - How OCLint is installed: local build? prebuilt binary downloaded from github? homebrew install? others? 8 | 9 | ### Reproduction Steps 10 | Detailed steps to reproduce the issue. 11 | 12 | #### Sample code 13 | 14 | ``` 15 | C 16 | C++ 17 | Objective-C 18 | ``` 19 | 20 | Command to run OCLint with the code above. 21 | 22 | ### Expected Behavior 23 | What do you expect to happen as a result of the reproduction steps? 24 | 25 | ### Actual Behavior 26 | What currently happens as a result of the reproduction steps? 27 | 28 | ### Even Better 29 | Is your project open sourced? If yes, can you point us to your repository? 30 | If not, is it possible to make a small project that fails the Travis CI? 31 | If not, can you create a gist with your sample code for us? 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Optional modules 2 | oclint-json-compilation-database/ 3 | oclint-xcodebuild/ 4 | 5 | # Third-party dependencies and build directory 6 | countly/ 7 | googletest/ 8 | llvm/ 9 | build/ 10 | 11 | # Compile Commands 12 | compile_commands.json 13 | 14 | # Compiled Object files 15 | *.slo 16 | *.lo 17 | *.o 18 | 19 | # Compiled Dynamic libraries 20 | *.so 21 | *.dylib 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | 28 | # Compiled Python Objects 29 | *.pyc 30 | 31 | # System files 32 | .DS_Store 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OCLint - http://oclint.org 2 | 3 | [![Travis CI Status](https://api.travis-ci.org/oclint/oclint.svg?branch=master)](https://travis-ci.org/oclint/oclint) [![Coverage Status](https://coveralls.io/repos/github/oclint/oclint/badge.svg?branch=master)](https://coveralls.io/github/oclint/oclint?branch=master) 4 | 5 | OCLint is a static code analysis tool for improving quality and reducing defects 6 | by inspecting C, C++ and Objective-C code. 7 | 8 | It looks for potential problems that aren't visible to compilers, for example: 9 | 10 | * Possible bugs - empty if/else/try/catch/finally statements 11 | * Unused code - unused local variables and parameters 12 | * Complicated code - high cyclomatic complexity, NPath complexity and high NCSS 13 | * Redundant code - redundant if statement and useless parentheses 14 | * Code smells - long method and long parameter list 15 | * Bad practices - inverted logic and parameter reassignment 16 | * ... 17 | 18 | For more information, visit http://oclint.org 19 | 20 | -------------------------------------------------------------------------------- /oclint-core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | PROJECT(OCLINT_CORE) 3 | 4 | SET(CMAKE_MODULE_PATH 5 | ${CMAKE_MODULE_PATH} 6 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake" 7 | ) 8 | 9 | INCLUDE(OCLintConfig) 10 | 11 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) 12 | 13 | ADD_SUBDIRECTORY(lib) 14 | 15 | IF(TEST_BUILD) 16 | ADD_SUBDIRECTORY(test) 17 | ENDIF() 18 | -------------------------------------------------------------------------------- /oclint-core/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2014 Longyi Qi and the OCLint project contributors. 2 | Copyright (C) 2015-2018 Ryuichi Laboratories and the OCLint project contributors. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the author nor the names of its contributors may be used 14 | to endorse or promote products derived from this software without specific 15 | prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/AbstractResults.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ABSTRACTRESULTS_H 2 | #define OCLINT_ABSTRACTRESULTS_H 3 | 4 | #include "oclint/Results.h" 5 | 6 | namespace oclint 7 | { 8 | 9 | class ResultCollector; 10 | 11 | class AbstractResults : public Results 12 | { 13 | protected: 14 | const ResultCollector& _resultCollector; 15 | 16 | public: 17 | explicit AbstractResults(const ResultCollector& resultCollector); 18 | virtual ~AbstractResults() = default; 19 | 20 | virtual int numberOfViolations() const override; 21 | virtual int numberOfViolationsWithPriority(int priority) const override; 22 | 23 | virtual int numberOfFiles() const override; 24 | virtual int numberOfFilesWithViolations() const override; 25 | 26 | virtual int numberOfErrors() const override; 27 | virtual bool hasErrors() const override; 28 | 29 | virtual int numberOfWarnings() const override; 30 | virtual bool hasWarnings() const override; 31 | 32 | virtual int numberOfCheckerBugs() const override; 33 | virtual bool hasCheckerBugs() const override; 34 | }; 35 | 36 | } // end namespace oclint 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/RawResults.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RAWRESULTS_H 2 | #define OCLINT_RAWRESULTS_H 3 | 4 | #include "oclint/AbstractResults.h" 5 | 6 | namespace oclint 7 | { 8 | 9 | class ResultCollector; 10 | 11 | class RawResults : public AbstractResults 12 | { 13 | public: 14 | explicit RawResults(const ResultCollector& resultCollector); 15 | 16 | std::vector allViolations() const override; 17 | const std::vector& allErrors() const override; 18 | const std::vector& allWarnings() const override; 19 | const std::vector& allCheckerBugs() const override; 20 | }; 21 | 22 | } // end namespace oclint 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/Reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_REPORTER_H 2 | #define OCLINT_REPORTER_H 3 | 4 | #include 5 | 6 | namespace oclint 7 | { 8 | 9 | class Results; 10 | 11 | class Reporter 12 | { 13 | public: 14 | virtual ~Reporter() {} 15 | virtual void report(Results *results, std::ostream &out) = 0; 16 | virtual const std::string name() const = 0; 17 | }; 18 | 19 | } // end namespace oclint 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/ResultCollector.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RESULTCOLLECTOR_H 2 | #define OCLINT_RESULTCOLLECTOR_H 3 | 4 | #include "oclint/Violation.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace oclint 10 | { 11 | 12 | class ViolationSet; 13 | 14 | class ResultCollector 15 | { 16 | protected: 17 | ResultCollector(); 18 | ~ResultCollector(); 19 | 20 | public: 21 | static ResultCollector* getInstance(); 22 | 23 | private: 24 | std::vector _collection; 25 | std::unique_ptr _compilerErrorSet; 26 | std::unique_ptr _compilerWarningSet; 27 | std::unique_ptr _clangStaticCheckerBugSet; 28 | 29 | public: 30 | void add(ViolationSet *violationSet); 31 | 32 | const std::vector& getCollection() const; 33 | 34 | void addError(const Violation& violation); 35 | ViolationSet* getCompilerErrorSet() const; 36 | 37 | void addWarning(const Violation& violation); 38 | ViolationSet* getCompilerWarningSet() const; 39 | 40 | void addCheckerBug(const Violation& violation); 41 | ViolationSet* getClangStaticCheckerBugSet() const; 42 | }; 43 | 44 | } // end namespace oclint 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/Results.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RESULTS_H 2 | #define OCLINT_RESULTS_H 3 | 4 | #include 5 | 6 | namespace oclint 7 | { 8 | 9 | class Violation; 10 | class ViolationSet; 11 | 12 | class Results 13 | { 14 | public: 15 | 16 | virtual ~Results() = default; 17 | 18 | virtual std::vector allViolations() const = 0; 19 | 20 | virtual int numberOfViolations() const = 0; 21 | virtual int numberOfViolationsWithPriority(int priority) const = 0; 22 | 23 | virtual int numberOfFiles() const = 0; 24 | virtual int numberOfFilesWithViolations() const = 0; 25 | 26 | virtual int numberOfErrors() const = 0; 27 | virtual bool hasErrors() const = 0; 28 | virtual const std::vector& allErrors() const = 0; 29 | 30 | virtual int numberOfWarnings() const = 0; 31 | virtual bool hasWarnings() const = 0; 32 | virtual const std::vector& allWarnings() const = 0; 33 | 34 | virtual int numberOfCheckerBugs() const = 0; 35 | virtual bool hasCheckerBugs() const = 0; 36 | virtual const std::vector& allCheckerBugs() const = 0; 37 | }; 38 | 39 | } // end namespace oclint 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/RuleBase.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RULEBASE_H 2 | #define OCLINT_RULEBASE_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef DOCGEN 8 | #include 9 | #endif 10 | 11 | #include "oclint/RuleCarrier.h" 12 | 13 | namespace oclint 14 | { 15 | 16 | class RuleBase 17 | { 18 | protected: 19 | RuleCarrier *_carrier; 20 | 21 | public: 22 | void takeoff(RuleCarrier *carrier); 23 | 24 | virtual ~RuleBase() {} 25 | virtual void apply() = 0; 26 | virtual const std::string name() const = 0; 27 | virtual const std::string attributeName() const; 28 | virtual const std::string identifier() const; 29 | virtual const std::string category() const = 0; 30 | virtual int priority() const = 0; 31 | 32 | #ifdef DOCGEN 33 | virtual const std::string since() const = 0; 34 | virtual const std::string description() const = 0; 35 | virtual const std::string example() const = 0; 36 | virtual const std::string fileName() const; 37 | virtual bool enableSuppress() const; 38 | virtual const std::map thresholds() const; 39 | virtual const std::string additionalDocument() const; 40 | #endif 41 | }; 42 | 43 | } // end namespace oclint 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/RuleCarrier.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RULECARRIER_H 2 | #define OCLINT_RULECARRIER_H 3 | 4 | #include 5 | 6 | namespace clang 7 | { 8 | class ASTContext; 9 | class SourceManager; 10 | class TranslationUnitDecl; 11 | } 12 | 13 | #include "oclint/ViolationSet.h" 14 | 15 | namespace oclint 16 | { 17 | 18 | class RuleCarrier 19 | { 20 | private: 21 | ViolationSet *_violationSet; 22 | clang::ASTContext *_astContext; 23 | 24 | public: 25 | RuleCarrier(clang::ASTContext *astContext, ViolationSet *violationSet); 26 | clang::ASTContext* getASTContext(); 27 | clang::SourceManager& getSourceManager(); 28 | std::string getMainFilePath(); 29 | clang::TranslationUnitDecl* getTranslationUnitDecl(); 30 | 31 | void addViolation(std::string filePath, int startLine, int startColumn, 32 | int endLine, int endColumn, RuleBase *rule, const std::string& message = ""); 33 | }; 34 | 35 | } // end namespace oclint 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/RuleConfiguration.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RULECONFIGURATION_H 2 | #define OCLINT_RULECONFIGURATION_H 3 | 4 | #include 5 | 6 | namespace oclint 7 | { 8 | 9 | class RuleConfiguration 10 | { 11 | public: 12 | static void addConfiguration(std::string key, std::string value); 13 | static bool hasKey(std::string key); 14 | static std::string valueForKey(std::string key); 15 | static void removeAll(); 16 | 17 | static std::string stringForKey(std::string key, std::string defaultValue = ""); 18 | static int intForKey(std::string key, int defaultValue = 0); 19 | static double doubleForKey(std::string key, double defaultValue = 0.0); 20 | }; 21 | 22 | } // end namespace oclint 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/RuleSet.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RULESET_H 2 | #define OCLINT_RULESET_H 3 | 4 | namespace oclint 5 | { 6 | 7 | class RuleBase; 8 | 9 | class RuleSet 10 | { 11 | public: 12 | explicit RuleSet(RuleBase* rule); 13 | static int numberOfRules(); 14 | static RuleBase* getRuleAtIndex(int index); 15 | }; 16 | 17 | } // end namespace oclint 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/UniqueResults.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_UNIQUERESULTS_H 2 | #define OCLINT_UNIQUERESULTS_H 3 | 4 | #include "oclint/AbstractResults.h" 5 | 6 | namespace oclint 7 | { 8 | 9 | class ResultCollector; 10 | 11 | class UniqueResults : public AbstractResults 12 | { 13 | private: 14 | mutable std::vector _violations; 15 | mutable std::vector _errors; 16 | mutable std::vector _warnings; 17 | mutable std::vector _checkerBugs; 18 | 19 | public: 20 | explicit UniqueResults(const ResultCollector& resultCollector); 21 | 22 | std::vector allViolations() const override; 23 | const std::vector& allErrors() const override; 24 | const std::vector& allWarnings() const override; 25 | const std::vector& allCheckerBugs() const override; 26 | }; 27 | 28 | } // end namespace oclint 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/Version.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_VERSION_H 2 | #define OCLINT_VERSION_H 3 | 4 | #include 5 | 6 | namespace oclint 7 | { 8 | 9 | class Version 10 | { 11 | public: 12 | static std::string identifier(); 13 | }; 14 | 15 | } // end namespace oclint 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/Violation.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_VIOLATION_H 2 | #define OCLINT_VIOLATION_H 3 | 4 | #include 5 | 6 | namespace oclint 7 | { 8 | 9 | class RuleBase; 10 | 11 | class Violation 12 | { 13 | public: 14 | const RuleBase *rule; 15 | std::string path; 16 | int startLine; 17 | int startColumn; 18 | int endLine; 19 | int endColumn; 20 | std::string message; 21 | 22 | Violation(RuleBase* violatedRule, std::string violationFilePath, 23 | int violationStartLine, int violationStartColumn, 24 | int violationEndLine, int violationEndColumn, 25 | std::string violationMessage = ""); 26 | 27 | bool operator==(const oclint::Violation &rhs) const; 28 | }; 29 | 30 | } // end namespace oclint 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /oclint-core/include/oclint/ViolationSet.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_VIOLATIONSET_H 2 | #define OCLINT_VIOLATIONSET_H 3 | 4 | #include 5 | 6 | #include "oclint/Violation.h" 7 | 8 | namespace oclint 9 | { 10 | 11 | class ViolationSet 12 | { 13 | private: 14 | std::vector _violations; 15 | 16 | public: 17 | void addViolation(const Violation& violation); 18 | int numberOfViolations() const; 19 | const std::vector& getViolations() const; 20 | 21 | bool operator==(const ViolationSet& rhs) const; 22 | 23 | // TODO: getViolation(int index) 24 | }; 25 | 26 | } // end namespace oclint 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /oclint-core/lib/AbstractResults.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "oclint/AbstractResults.h" 4 | #include "oclint/ResultCollector.h" 5 | #include "oclint/RuleBase.h" 6 | 7 | namespace oclint { 8 | 9 | AbstractResults::AbstractResults(const ResultCollector& resultCollector) 10 | : _resultCollector(resultCollector) 11 | { 12 | } 13 | 14 | int AbstractResults::numberOfFiles() const 15 | { 16 | return _resultCollector.getCollection().size(); 17 | } 18 | 19 | int AbstractResults::numberOfFilesWithViolations() const 20 | { 21 | std::map violationsMapping; 22 | for (const auto& violationSet : _resultCollector.getCollection()) 23 | { 24 | if (violationSet->numberOfViolations() > 0) 25 | { 26 | std::string filePath = violationSet->getViolations()[0].path; 27 | violationsMapping[filePath] += violationSet->numberOfViolations(); 28 | } 29 | } 30 | return violationsMapping.size(); 31 | } 32 | 33 | int AbstractResults::numberOfViolations() const 34 | { 35 | return allViolations().size(); 36 | } 37 | 38 | int AbstractResults::numberOfViolationsWithPriority(int priority) const 39 | { 40 | int numViolations = 0; 41 | for (const auto& violation : allViolations()) 42 | { 43 | const RuleBase *rule = violation.rule; 44 | if (rule->priority() == priority) 45 | { 46 | numViolations++; 47 | } 48 | } 49 | return numViolations; 50 | } 51 | 52 | int AbstractResults::numberOfErrors() const 53 | { 54 | return allErrors().size(); 55 | } 56 | 57 | bool AbstractResults::hasErrors() const 58 | { 59 | return numberOfErrors() > 0; 60 | } 61 | 62 | int AbstractResults::numberOfWarnings() const 63 | { 64 | return allWarnings().size(); 65 | } 66 | 67 | bool AbstractResults::hasWarnings() const 68 | { 69 | return numberOfWarnings() > 0; 70 | } 71 | 72 | int AbstractResults::numberOfCheckerBugs() const 73 | { 74 | return allCheckerBugs().size(); 75 | } 76 | 77 | bool AbstractResults::hasCheckerBugs() const 78 | { 79 | return numberOfCheckerBugs() > 0; 80 | } 81 | 82 | } // end namespace oclint 83 | -------------------------------------------------------------------------------- /oclint-core/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_LIBRARY(OCLintCore 2 | AbstractResults.cpp 3 | ResultCollector.cpp 4 | UniqueResults.cpp 5 | RawResults.cpp 6 | RuleBase.cpp 7 | RuleCarrier.cpp 8 | Version.cpp 9 | Violation.cpp 10 | ViolationSet.cpp 11 | ) 12 | 13 | IF (${CMAKE_SYSTEM_NAME} MATCHES "Win") 14 | ADD_LIBRARY(OCLintRuleSet SHARED 15 | RuleConfiguration.cpp 16 | RuleSet.cpp 17 | ) 18 | IF(TEST_BUILD) 19 | target_link_libraries (OCLintRuleSet --coverage) 20 | ENDIF() 21 | ELSE() 22 | ADD_LIBRARY(OCLintRuleSet 23 | RuleConfiguration.cpp 24 | RuleSet.cpp 25 | ) 26 | ENDIF() 27 | -------------------------------------------------------------------------------- /oclint-core/lib/RawResults.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/RawResults.h" 2 | #include "oclint/ResultCollector.h" 3 | #include "oclint/ViolationSet.h" 4 | 5 | namespace oclint { 6 | 7 | RawResults::RawResults(const ResultCollector &resultCollector) 8 | : AbstractResults(resultCollector) 9 | { 10 | } 11 | 12 | std::vector RawResults::allViolations() const 13 | { 14 | std::vector violations; 15 | for (const auto& violationSet : _resultCollector.getCollection()) 16 | { 17 | for (const auto& violation : violationSet->getViolations()) 18 | { 19 | violations.push_back(violation); 20 | } 21 | } 22 | return violations; 23 | } 24 | 25 | const std::vector& RawResults::allErrors() const 26 | { 27 | return _resultCollector.getCompilerErrorSet()->getViolations(); 28 | } 29 | 30 | const std::vector& RawResults::allWarnings() const 31 | { 32 | return _resultCollector.getCompilerWarningSet()->getViolations(); 33 | } 34 | 35 | const std::vector& RawResults::allCheckerBugs() const 36 | { 37 | return _resultCollector.getClangStaticCheckerBugSet()->getViolations(); 38 | } 39 | 40 | } // end namespace oclint 41 | -------------------------------------------------------------------------------- /oclint-core/lib/ResultCollector.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/ResultCollector.h" 2 | #include "oclint/RuleBase.h" 3 | #include "oclint/Violation.h" 4 | #include "oclint/ViolationSet.h" 5 | 6 | static oclint::ResultCollector *_singleton = nullptr; 7 | 8 | namespace oclint { 9 | 10 | ResultCollector* ResultCollector::getInstance() 11 | { 12 | if (_singleton == nullptr) 13 | { 14 | _singleton = new ResultCollector(); 15 | } 16 | return _singleton; 17 | } 18 | 19 | ResultCollector::ResultCollector() 20 | : _compilerErrorSet(new ViolationSet) 21 | , _compilerWarningSet(new ViolationSet) 22 | , _clangStaticCheckerBugSet(new ViolationSet) 23 | { 24 | } 25 | 26 | ResultCollector::~ResultCollector() 27 | { 28 | } 29 | 30 | void ResultCollector::add(ViolationSet *violationSet) 31 | { 32 | _collection.push_back(violationSet); 33 | } 34 | 35 | const std::vector& ResultCollector::getCollection() const 36 | { 37 | return _collection; 38 | } 39 | 40 | void ResultCollector::addError(const Violation& violation) 41 | { 42 | _compilerErrorSet->addViolation(violation); 43 | } 44 | 45 | ViolationSet* ResultCollector::getCompilerErrorSet() const 46 | { 47 | return _compilerErrorSet.get(); 48 | } 49 | 50 | void ResultCollector::addWarning(const Violation& violation) 51 | { 52 | _compilerWarningSet->addViolation(violation); 53 | } 54 | 55 | ViolationSet* ResultCollector::getCompilerWarningSet() const 56 | { 57 | return _compilerWarningSet.get(); 58 | } 59 | 60 | void ResultCollector::addCheckerBug(const Violation& violation) 61 | { 62 | _clangStaticCheckerBugSet->addViolation(violation); 63 | } 64 | 65 | ViolationSet* ResultCollector::getClangStaticCheckerBugSet() const 66 | { 67 | return _clangStaticCheckerBugSet.get(); 68 | } 69 | 70 | } // end namespace oclint 71 | -------------------------------------------------------------------------------- /oclint-core/lib/RuleBase.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/RuleBase.h" 2 | 3 | using namespace oclint; 4 | 5 | void RuleBase::takeoff(RuleCarrier *carrier) 6 | { 7 | _carrier = carrier; 8 | apply(); 9 | } 10 | 11 | const std::string RuleBase::attributeName() const 12 | { 13 | return name(); 14 | } 15 | 16 | const std::string RuleBase::identifier() const 17 | { 18 | std::string copy = name(); 19 | if (copy.empty()) 20 | { 21 | return copy; 22 | } 23 | copy[0] = toupper(copy[0]); 24 | 25 | for (std::string::iterator it = copy.begin() + 1; it != copy.end(); ++it) 26 | { 27 | if (!isalpha(*(it - 1)) && islower(*it)) 28 | { 29 | *it = toupper(*it); 30 | } 31 | } 32 | copy.erase(std::remove_if(copy.begin(), copy.end(), 33 | [](char eachChar){return !isalpha(eachChar);}), copy.end()); 34 | return copy; 35 | } 36 | 37 | #ifdef DOCGEN 38 | const std::string RuleBase::fileName() const 39 | { 40 | return identifier() + "Rule.cpp"; 41 | } 42 | 43 | bool RuleBase::enableSuppress() const 44 | { 45 | return false; 46 | } 47 | 48 | const std::map RuleBase::thresholds() const 49 | { 50 | std::map emptyMap; 51 | return emptyMap; 52 | } 53 | 54 | const std::string RuleBase::additionalDocument() const 55 | { 56 | return ""; 57 | } 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /oclint-core/lib/RuleCarrier.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/RuleCarrier.h" 2 | 3 | #include 4 | 5 | using namespace oclint; 6 | 7 | RuleCarrier::RuleCarrier(clang::ASTContext *astContext, ViolationSet *violationSet) 8 | { 9 | _violationSet = violationSet; 10 | _astContext = astContext; 11 | } 12 | 13 | clang::ASTContext* RuleCarrier::getASTContext() 14 | { 15 | return _astContext; 16 | } 17 | 18 | clang::SourceManager& RuleCarrier::getSourceManager() 19 | { 20 | return getASTContext()->getSourceManager(); 21 | } 22 | 23 | std::string RuleCarrier::getMainFilePath() 24 | { 25 | clang::FileID mainFileId = getSourceManager().getMainFileID(); 26 | clang::SourceLocation mainSourceLocation = getSourceManager().getLocForStartOfFile(mainFileId); 27 | return getSourceManager().getFilename(mainSourceLocation).str(); 28 | } 29 | 30 | clang::TranslationUnitDecl* RuleCarrier::getTranslationUnitDecl() 31 | { 32 | return getASTContext()->getTranslationUnitDecl(); 33 | } 34 | 35 | void RuleCarrier::addViolation(std::string filePath, int startLine, int startColumn, 36 | int endLine, int endColumn, RuleBase *rule, const std::string& message) 37 | { 38 | if (filePath != "") 39 | { 40 | Violation violation(rule, 41 | filePath, startLine, startColumn, endLine, endColumn, message); 42 | _violationSet->addViolation(violation); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /oclint-core/lib/RuleConfiguration.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/RuleConfiguration.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace oclint; 7 | 8 | static std::map* _configurations = nullptr; 9 | 10 | void RuleConfiguration::addConfiguration(std::string key, std::string value) 11 | { 12 | if (_configurations == nullptr) 13 | { 14 | _configurations = new std::map(); 15 | } 16 | 17 | _configurations->operator[](key) = value; 18 | } 19 | 20 | bool RuleConfiguration::hasKey(std::string key) 21 | { 22 | return _configurations != nullptr && 23 | _configurations->find(key) != _configurations->end(); 24 | } 25 | 26 | std::string RuleConfiguration::valueForKey(std::string key) 27 | { 28 | return _configurations->operator[](key); 29 | } 30 | 31 | void RuleConfiguration::removeAll() 32 | { 33 | if (_configurations != nullptr) 34 | { 35 | _configurations = nullptr; 36 | } 37 | } 38 | 39 | std::string RuleConfiguration::stringForKey(std::string key, std::string defaultValue) 40 | { 41 | return hasKey(key) ? valueForKey(key) : defaultValue; 42 | } 43 | 44 | int RuleConfiguration::intForKey(std::string key, int defaultValue) 45 | { 46 | return hasKey(key) ? atoi(valueForKey(key).c_str()) : defaultValue; 47 | } 48 | 49 | double RuleConfiguration::doubleForKey(std::string key, double defaultValue) 50 | { 51 | return hasKey(key) ? atof(valueForKey(key).c_str()) : defaultValue; 52 | } 53 | -------------------------------------------------------------------------------- /oclint-core/lib/RuleSet.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/RuleSet.h" 2 | 3 | #include 4 | 5 | #include "oclint/RuleBase.h" 6 | 7 | using namespace oclint; 8 | 9 | static std::vector* _rules = nullptr; 10 | 11 | RuleSet::RuleSet(RuleBase* rule) 12 | { 13 | if (_rules == nullptr) 14 | { 15 | _rules = new std::vector(); 16 | } 17 | _rules->push_back(rule); 18 | } 19 | 20 | int RuleSet::numberOfRules() 21 | { 22 | return _rules == nullptr ? 0 : _rules->size(); 23 | } 24 | 25 | RuleBase* RuleSet::getRuleAtIndex(int index) 26 | { 27 | if (index >= numberOfRules()) 28 | { 29 | return nullptr; // Better throwing an exception 30 | } 31 | return _rules->at(index); 32 | } 33 | -------------------------------------------------------------------------------- /oclint-core/lib/Version.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/Version.h" 2 | 3 | using namespace oclint; 4 | 5 | std::string Version::identifier() 6 | { 7 | return "0.13"; 8 | } 9 | -------------------------------------------------------------------------------- /oclint-core/lib/Violation.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/Violation.h" 2 | 3 | #include 4 | 5 | #include "oclint/RuleBase.h" 6 | 7 | using namespace oclint; 8 | 9 | Violation::Violation(RuleBase* violatedRule, std::string violationFilePath, 10 | int violationStartLine, int violationStartColumn, 11 | int violationEndLine, int violationEndColumn, 12 | std::string violationMessage) 13 | : path(std::move(violationFilePath)), message(std::move(violationMessage)) 14 | { 15 | rule = violatedRule; 16 | startLine = violationStartLine; 17 | startColumn = violationStartColumn; 18 | endLine = violationEndLine; 19 | endColumn = violationEndColumn; 20 | } 21 | 22 | bool Violation::operator==(const oclint::Violation &rhs) const 23 | { 24 | return (rule == rhs.rule) 25 | && (path == rhs.path) 26 | && (startLine == rhs.startLine) 27 | && (startColumn == rhs.startColumn) 28 | && (endLine == rhs.endLine) 29 | && (endColumn == rhs.endColumn) 30 | && (message == rhs.message); 31 | } 32 | -------------------------------------------------------------------------------- /oclint-core/lib/ViolationSet.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/ViolationSet.h" 2 | 3 | using namespace oclint; 4 | 5 | void ViolationSet::addViolation(const Violation& violation) 6 | { 7 | _violations.push_back(violation); 8 | } 9 | 10 | int ViolationSet::numberOfViolations() const 11 | { 12 | return _violations.size(); 13 | } 14 | 15 | const std::vector& ViolationSet::getViolations() const 16 | { 17 | return _violations; 18 | } 19 | 20 | 21 | bool ViolationSet::operator==(const ViolationSet& rhs) const 22 | { 23 | return _violations == rhs._violations; 24 | } 25 | -------------------------------------------------------------------------------- /oclint-core/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | MACRO(build_test name) 2 | ADD_EXECUTABLE(${name} ${name}.cpp) 3 | TARGET_LINK_LIBRARIES(${name} 4 | OCLintRuleSet 5 | OCLintCore 6 | ${GTEST_LIBS} 7 | ${PROFILE_RT_LIBS} 8 | ${CLANG_LIBRARIES} 9 | ${REQ_LLVM_LIBRARIES} 10 | ${CMAKE_DL_LIBS} 11 | ) 12 | 13 | ADD_TEST(${name} ${EXECUTABLE_OUTPUT_PATH}/${name}) 14 | ENDMACRO(build_test) 15 | 16 | BUILD_TEST(CanaryTest) 17 | BUILD_TEST(RawResultsTest) 18 | BUILD_TEST(ResultCollectorTest) 19 | BUILD_TEST(RuleBaseTest) 20 | BUILD_TEST(RuleCarrierTest) 21 | BUILD_TEST(RuleConfigurationTest) 22 | BUILD_TEST(RuleSetTest) 23 | BUILD_TEST(UniqueResultsTest) 24 | TARGET_LINK_LIBRARIES(RuleSetTest OCLintRuleSet) 25 | 26 | IF(${CMAKE_SYSTEM_NAME} MATCHES "Win") 27 | add_custom_command(TARGET RuleSetTest PRE_BUILD 28 | COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $) 29 | ENDIF() 30 | BUILD_TEST(VersionTest) 31 | BUILD_TEST(ViolationSetTest) 32 | BUILD_TEST(ViolationTest) 33 | -------------------------------------------------------------------------------- /oclint-core/test/CanaryTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | TEST(CanaryTest, AlwaysTrue) 5 | { 6 | EXPECT_TRUE(true); 7 | } 8 | 9 | int main(int argc, char **argv) 10 | { 11 | ::testing::InitGoogleMock(&argc, argv); 12 | return RUN_ALL_TESTS(); 13 | } 14 | -------------------------------------------------------------------------------- /oclint-core/test/RuleCarrierTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "oclint/RuleBase.h" 7 | #include "oclint/ViolationSet.h" 8 | 9 | using namespace ::testing; 10 | using namespace oclint; 11 | 12 | class MockRuleBase : public RuleBase 13 | { 14 | public: 15 | MOCK_METHOD0(apply, void()); 16 | MOCK_CONST_METHOD0(name, const std::string()); 17 | MOCK_CONST_METHOD0(priority, int()); 18 | MOCK_CONST_METHOD0(category, const std::string()); 19 | }; 20 | 21 | TEST(RuleCarrierTest, Initializationasdf) 22 | { 23 | ViolationSet *violationSet = new ViolationSet(); 24 | RuleCarrier *carrier = new RuleCarrier(NULL, violationSet); 25 | EXPECT_THAT(carrier->getASTContext(), IsNull()); 26 | EXPECT_THAT(violationSet->numberOfViolations(), Eq(0)); 27 | } 28 | 29 | TEST(RuleCarrierTest, AddViolation) 30 | { 31 | ViolationSet *violationSet = new ViolationSet(); 32 | RuleCarrier *carrier = new RuleCarrier(NULL, violationSet); 33 | RuleBase *rule = new MockRuleBase(); 34 | carrier->addViolation("test path", 1, 2, 3, 4, rule, "test message"); 35 | EXPECT_THAT(violationSet->numberOfViolations(), Eq(1)); 36 | Violation compareViolation = violationSet->getViolations().at(0); 37 | EXPECT_THAT(compareViolation.path, StrEq("test path")); 38 | EXPECT_THAT(compareViolation.message, StrEq("test message")); 39 | EXPECT_THAT(compareViolation.rule, Eq(rule)); 40 | EXPECT_THAT(compareViolation.startLine, Eq(1)); 41 | EXPECT_THAT(compareViolation.startColumn, Eq(2)); 42 | EXPECT_THAT(compareViolation.endLine, Eq(3)); 43 | EXPECT_THAT(compareViolation.endColumn, Eq(4)); 44 | } 45 | 46 | TEST(RuleCarrierTest, AddViolationWithEmptyFilePath) 47 | { 48 | ViolationSet *violationSet = new ViolationSet(); 49 | RuleCarrier *carrier = new RuleCarrier(NULL, violationSet); 50 | RuleBase *rule = new MockRuleBase(); 51 | carrier->addViolation("", 1, 2, 3, 4, rule, "test message"); 52 | EXPECT_THAT(violationSet->numberOfViolations(), Eq(0)); 53 | } 54 | 55 | int main(int argc, char **argv) 56 | { 57 | ::testing::InitGoogleMock(&argc, argv); 58 | return RUN_ALL_TESTS(); 59 | } 60 | -------------------------------------------------------------------------------- /oclint-core/test/RuleSetTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "oclint/RuleBase.h" 5 | #include "oclint/RuleSet.h" 6 | 7 | using namespace ::testing; 8 | using namespace oclint; 9 | 10 | int RuleSetTest_applyCount; 11 | 12 | class MockRuleBase : public RuleBase 13 | { 14 | public: 15 | MOCK_METHOD0(apply, void()); 16 | MOCK_CONST_METHOD0(name, const std::string()); 17 | MOCK_CONST_METHOD0(priority, int()); 18 | MOCK_CONST_METHOD0(category, const std::string()); 19 | }; 20 | 21 | TEST(RuleSetTest, EmptyRuleSet) 22 | { 23 | EXPECT_THAT(RuleSet::numberOfRules(), Eq(0)); 24 | EXPECT_THAT(RuleSet::getRuleAtIndex(0), IsNull()); 25 | } 26 | 27 | TEST(RuleSetTest, AddRuleToRuleSet) 28 | { 29 | RuleBase *rule = new MockRuleBase(); 30 | RuleSet set(rule); 31 | EXPECT_THAT(RuleSet::numberOfRules(), Eq(1)); 32 | EXPECT_THAT(RuleSet::getRuleAtIndex(0), Eq(rule)); 33 | EXPECT_THAT(RuleSet::getRuleAtIndex(1), IsNull()); 34 | } 35 | 36 | TEST(RuleSetTest, StaticRuleVector) 37 | { 38 | RuleBase *rule = new MockRuleBase(); 39 | RuleSet set(rule); 40 | EXPECT_THAT(RuleSet::numberOfRules(), Eq(2)); 41 | EXPECT_THAT(RuleSet::getRuleAtIndex(0), NotNull()); 42 | EXPECT_THAT(RuleSet::getRuleAtIndex(1), Eq(rule)); 43 | EXPECT_THAT(RuleSet::getRuleAtIndex(2), IsNull()); 44 | } 45 | 46 | int main(int argc, char **argv) 47 | { 48 | ::testing::InitGoogleMock(&argc, argv); 49 | return RUN_ALL_TESTS(); 50 | } 51 | -------------------------------------------------------------------------------- /oclint-core/test/VersionTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "oclint/Version.h" 5 | 6 | using namespace ::testing; 7 | using namespace oclint; 8 | 9 | TEST(VersionTest, VersionString) 10 | { 11 | EXPECT_THAT(Version::identifier(), StrEq("0.13")); 12 | } 13 | 14 | int main(int argc, char **argv) 15 | { 16 | ::testing::InitGoogleMock(&argc, argv); 17 | return RUN_ALL_TESTS(); 18 | } 19 | -------------------------------------------------------------------------------- /oclint-core/test/ViolationTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "oclint/RuleBase.h" 7 | #include "oclint/Violation.h" 8 | 9 | using namespace ::testing; 10 | using namespace oclint; 11 | 12 | class MockRuleBase : public RuleBase 13 | { 14 | public: 15 | MOCK_METHOD0(apply, void()); 16 | MOCK_CONST_METHOD0(name, const std::string()); 17 | MOCK_CONST_METHOD0(priority, int()); 18 | MOCK_CONST_METHOD0(category, const std::string()); 19 | }; 20 | 21 | TEST(ViolationTest, Constructor) 22 | { 23 | RuleBase *rule = new MockRuleBase(); 24 | Violation violation(rule, "test path", 1, 2, 3, 4, "test message"); 25 | EXPECT_THAT(violation.path, StrEq("test path")); 26 | EXPECT_THAT(violation.message, StrEq("test message")); 27 | EXPECT_THAT(violation.rule, Eq(rule)); 28 | EXPECT_THAT(violation.startLine, Eq(1)); 29 | EXPECT_THAT(violation.startColumn, Eq(2)); 30 | EXPECT_THAT(violation.endLine, Eq(3)); 31 | EXPECT_THAT(violation.endColumn, Eq(4)); 32 | } 33 | 34 | int main(int argc, char **argv) 35 | { 36 | ::testing::InitGoogleMock(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /oclint-driver/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2014 Longyi Qi and the OCLint project contributors. 2 | Copyright (C) 2015-2018 Ryuichi Laboratories and the OCLint project contributors. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the author nor the names of its contributors may be used 14 | to endorse or promote products derived from this software without specific 15 | prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/Analytics.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ANALYTICS_H 2 | #define OCLINT_ANALYTICS_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace oclint 9 | { 10 | 11 | class Analytics 12 | { 13 | public: 14 | static void send(int exitCode); 15 | 16 | public: 17 | static void languageOption(clang::LangOptions langOptions); 18 | static void ruleConfiguration(std::string key, std::string value); 19 | }; 20 | 21 | } // end namespace oclint 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/Analyzer.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ANALYZER_H 2 | #define OCLINT_ANALYZER_H 3 | 4 | #include 5 | 6 | namespace clang 7 | { 8 | class ASTContext; 9 | } 10 | 11 | namespace oclint 12 | { 13 | 14 | class Analyzer 15 | { 16 | public: 17 | virtual void preprocess(std::vector &contexts) {} 18 | virtual void analyze(std::vector &contexts) = 0; 19 | virtual void postprocess(std::vector &contexts) {} 20 | }; 21 | 22 | } // end namespace oclint 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/CompilerInstance.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_COMPILERINSTANCE_H 2 | #define OCLINT_COMPILERINSTANCE_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace clang 9 | { 10 | class FrontendAction; 11 | } 12 | 13 | namespace oclint 14 | { 15 | 16 | class CompilerInstance : public clang::CompilerInstance 17 | { 18 | public: 19 | void start(); 20 | void end(); 21 | 22 | private: 23 | std::vector> _actions; 24 | }; 25 | 26 | } // end namespace oclint 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/ConfigFile.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_CONFIGFILE_H 2 | #define OCLINT_CONFIGFILE_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace oclint 11 | { 12 | namespace option 13 | { 14 | 15 | class RuleConfigurationPair 16 | { 17 | private: 18 | llvm::StringRef _key; 19 | llvm::StringRef _value; 20 | 21 | public: 22 | const llvm::StringRef &key() const; 23 | const llvm::StringRef &value() const; 24 | 25 | void mapping(llvm::yaml::IO& io); 26 | }; 27 | 28 | enum TriState {FALSE, TRUE, UNDEFINED}; 29 | 30 | class ConfigFile 31 | { 32 | private: 33 | std::string _path; 34 | std::vector _rules; 35 | std::vector _disableRules; 36 | std::vector _rulePaths; 37 | std::vector _ruleConfigurations; 38 | llvm::StringRef _output; 39 | llvm::StringRef _reportType; 40 | int _maxP1; 41 | int _maxP2; 42 | int _maxP3; 43 | TriState _clangChecker = UNDEFINED; 44 | TriState _allowDuplicatedViolations = UNDEFINED; 45 | TriState _enableGlobalAnalysis = UNDEFINED; 46 | 47 | public: 48 | explicit ConfigFile(const std::string &path); 49 | 50 | const std::string &path() const; 51 | const std::vector &rules() const; 52 | const std::vector &disableRules() const; 53 | const std::vector &rulePaths() const; 54 | const std::vector &ruleConfigurations() const; 55 | llvm::Optional output() const; 56 | llvm::Optional reportType() const; 57 | llvm::Optional maxP1() const; 58 | llvm::Optional maxP2() const; 59 | llvm::Optional maxP3() const; 60 | llvm::Optional clangChecker() const; 61 | llvm::Optional allowDuplicatedViolations() const; 62 | llvm::Optional enableGlobalAnalysis() const; 63 | 64 | void mapping(llvm::yaml::IO& io); 65 | }; 66 | 67 | } // end namespace option 68 | } // end namespace oclint 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/DiagnosticDispatcher.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_DIAGNOSTICDISPATCHER_H 2 | #define OCLINT_DIAGNOSTICDISPATCHER_H 3 | 4 | #include 5 | 6 | namespace oclint 7 | { 8 | 9 | class DiagnosticDispatcher : public clang::DiagnosticConsumer 10 | { 11 | private: 12 | bool _isCheckerCustomer; 13 | 14 | public: 15 | explicit DiagnosticDispatcher(bool runClangChecker); 16 | void HandleDiagnostic(clang::DiagnosticsEngine::Level diagnosticLevel, 17 | const clang::Diagnostic& diagnosticInfo) override; 18 | }; 19 | 20 | } // end namespace oclint 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/Driver.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_DRIVER_H 2 | #define OCLINT_DRIVER_H 3 | 4 | #include 5 | 6 | namespace llvm 7 | { 8 | template class ArrayRef; 9 | } 10 | 11 | namespace clang 12 | { 13 | namespace tooling 14 | { 15 | class CompilationDatabase; 16 | } 17 | } 18 | 19 | #include "oclint/Analyzer.h" 20 | 21 | namespace oclint 22 | { 23 | 24 | class ViolationSet; 25 | 26 | class Driver 27 | { 28 | public: 29 | void run(const clang::tooling::CompilationDatabase &compilationDatabase, 30 | llvm::ArrayRef sourcePaths, oclint::Analyzer &analyzer); 31 | }; 32 | 33 | } // end namespace oclint 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/ExitCode.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_EXITCODE_H 2 | #define OCLINT_EXITCODE_H 3 | 4 | enum ExitCode 5 | { 6 | SUCCESS, 7 | RULE_NOT_FOUND, 8 | REPORTER_NOT_FOUND, 9 | ERROR_WHILE_PROCESSING, 10 | ERROR_WHILE_REPORTING, 11 | VIOLATIONS_EXCEED_THRESHOLD, 12 | COMPILATION_ERRORS 13 | }; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/GenericException.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_GENERICEXCEPTION_H 2 | #define OCLINT_GENERICEXCEPTION_H 3 | 4 | #include 5 | #include 6 | 7 | namespace oclint 8 | { 9 | 10 | class GenericException : public std::exception 11 | { 12 | public: 13 | explicit GenericException(std::string desc); 14 | virtual ~GenericException() throw() {} 15 | virtual const char* what() const throw() override; 16 | 17 | private: 18 | std::string description; 19 | }; 20 | 21 | } // end namespace oclint 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/Logger.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_LOGGER_H 2 | #define OCLINT_LOGGER_H 3 | 4 | #include 5 | 6 | namespace oclint 7 | { 8 | namespace logger 9 | { 10 | #ifndef NDEBUG 11 | llvm::raw_ostream &debugStream(); 12 | #endif 13 | llvm::raw_ostream &verboseStream(); 14 | } // end namespace logger 15 | } // end namespace oclint 16 | 17 | #ifndef NDEBUG 18 | 19 | #define LOG_DEBUG(MSG) oclint::logger::debugStream() << MSG 20 | #define LOG_DEBUG_LINE(MSG) LOG_DEBUG(MSG << "\n") 21 | 22 | #else 23 | 24 | #define LOG_DEBUG(MSG) 25 | #define LOG_DEBUG_LINE(MSG) 26 | 27 | #endif 28 | 29 | #define LOG_VERBOSE(MSG) oclint::logger::verboseStream() << MSG 30 | #define LOG_VERBOSE_LINE(MSG) LOG_VERBOSE(MSG << "\n") 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/Options.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_OPTIONS_H 2 | #define OCLINT_OPTIONS_H 3 | 4 | #include 5 | #include 6 | 7 | #include "oclint/RulesetFilter.h" 8 | 9 | namespace oclint 10 | { 11 | namespace option 12 | { 13 | void process(const char *argv); 14 | 15 | std::string workingPath(); 16 | std::string installPrefix(); 17 | std::string binPath(); 18 | std::string libPath(); 19 | std::string etcPath(); 20 | std::string homePath(); 21 | std::vector rulesPath(); 22 | std::string reporterPath(); 23 | 24 | bool hasOutputPath(); 25 | std::string outputPath(); 26 | std::string reportType(); 27 | const oclint::RulesetFilter &rulesetFilter(); 28 | int maxP1(); 29 | int maxP2(); 30 | int maxP3(); 31 | bool showEnabledRules(); 32 | bool enableGlobalAnalysis(); 33 | bool enableClangChecker(); 34 | bool allowDuplicatedViolations(); 35 | bool disableAnalytics(); 36 | bool enableVerbose(); 37 | } // end namespace option 38 | } // end namespace oclint 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/RulesetBasedAnalyzer.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RULESETBASEDANALYZER_H 2 | #define OCLINT_RULESETBASEDANALYZER_H 3 | 4 | #include "oclint/Analyzer.h" 5 | 6 | #include "oclint/RuleBase.h" 7 | 8 | namespace oclint 9 | { 10 | 11 | class RulesetBasedAnalyzer : public Analyzer 12 | { 13 | private: 14 | std::vector _filteredRules; 15 | 16 | public: 17 | explicit RulesetBasedAnalyzer(std::vector filteredRules); 18 | 19 | virtual void analyze(std::vector& contexts) override; 20 | }; 21 | 22 | } // end namespace oclint 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /oclint-driver/include/oclint/RulesetFilter.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_RULESETFILTER_H 2 | #define OCLINT_RULESETFILTER_H 3 | 4 | #include 5 | #include 6 | 7 | #include "oclint/RuleBase.h" 8 | 9 | namespace oclint 10 | { 11 | 12 | /** 13 | * Manages a list of enabled and disabled rules and filters Ruleset on demand. 14 | * 15 | * Calling enableRule or disableRule can override previous calls, as would be 16 | * expected for a configuration hierarchy. 17 | */ 18 | class RulesetFilter 19 | { 20 | 21 | private: 22 | std::set _enabled; 23 | std::set _disabled; 24 | 25 | public: 26 | void enableRule(const std::string &ruleName); 27 | template 28 | void enableRules(const T &beg, const T &end) 29 | { 30 | for_each(beg, end, [this](const std::string &s) { enableRule(s); }); 31 | } 32 | 33 | void disableRule(const std::string &ruleName); 34 | template 35 | void disableRules(const T &beg, const T &end) 36 | { 37 | for_each(beg, end, [this](const std::string &s) { disableRule(s); }); 38 | } 39 | 40 | std::vector filteredRules() const; 41 | std::vector filteredRuleNames() const; 42 | 43 | }; 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /oclint-driver/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_LIBRARY(OCLintDriver 2 | Analytics.cpp 3 | CompilerInstance.cpp 4 | ConfigFile.cpp 5 | DiagnosticDispatcher.cpp 6 | Driver.cpp 7 | GenericException.cpp 8 | Logger.cpp 9 | Options.cpp 10 | RulesetBasedAnalyzer.cpp 11 | RulesetFilter.cpp 12 | ) 13 | -------------------------------------------------------------------------------- /oclint-driver/lib/GenericException.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/GenericException.h" 2 | 3 | #include 4 | 5 | using namespace oclint; 6 | 7 | GenericException::GenericException(std::string desc) 8 | : description(std::move(desc)) 9 | { 10 | } 11 | 12 | const char *GenericException::what() const throw() 13 | { 14 | return description.c_str(); 15 | } 16 | -------------------------------------------------------------------------------- /oclint-driver/lib/Logger.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/Logger.h" 2 | 3 | #include 4 | 5 | #include "oclint/Options.h" 6 | 7 | #ifndef NDEBUG 8 | 9 | llvm::raw_ostream &oclint::logger::debugStream() 10 | { 11 | if (llvm::DebugFlag) 12 | { 13 | return llvm::dbgs(); 14 | } 15 | return llvm::nulls(); 16 | } 17 | 18 | #endif 19 | 20 | llvm::raw_ostream &oclint::logger::verboseStream() 21 | { 22 | #ifndef NDEBUG 23 | if (llvm::DebugFlag || oclint::option::enableVerbose()) 24 | #else 25 | if (oclint::option::enableVerbose()) 26 | #endif 27 | { 28 | return llvm::outs(); 29 | } 30 | return llvm::nulls(); 31 | } 32 | -------------------------------------------------------------------------------- /oclint-driver/lib/RulesetBasedAnalyzer.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/RulesetBasedAnalyzer.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "oclint/Analytics.h" 8 | #include "oclint/Logger.h" 9 | #include "oclint/ResultCollector.h" 10 | #include "oclint/RuleBase.h" 11 | #include "oclint/RuleCarrier.h" 12 | #include "oclint/RuleSet.h" 13 | #include "oclint/ViolationSet.h" 14 | 15 | using namespace oclint; 16 | 17 | RulesetBasedAnalyzer::RulesetBasedAnalyzer(std::vector filteredRules) 18 | : _filteredRules(std::move(filteredRules)) 19 | { 20 | } 21 | 22 | void RulesetBasedAnalyzer::analyze(std::vector &contexts) 23 | { 24 | for (const auto& context : contexts) 25 | { 26 | Analytics::languageOption(context->getLangOpts()); 27 | 28 | LOG_VERBOSE("Analyzing "); 29 | auto violationSet = new ViolationSet(); 30 | auto carrier = new RuleCarrier(context, violationSet); 31 | LOG_VERBOSE(carrier->getMainFilePath().c_str()); 32 | for (RuleBase *rule : _filteredRules) 33 | { 34 | rule->takeoff(carrier); 35 | } 36 | ResultCollector *results = ResultCollector::getInstance(); 37 | results->add(violationSet); 38 | LOG_VERBOSE_LINE(" - Done"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /oclint-driver/lib/RulesetFilter.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/RulesetFilter.h" 2 | 3 | #include "oclint/RuleSet.h" 4 | 5 | using namespace oclint; 6 | 7 | static std::string getName(const oclint::RuleBase *rule) 8 | { 9 | return rule->identifier(); 10 | } 11 | 12 | void RulesetFilter::enableRule(const std::string &ruleName) 13 | { 14 | _enabled.insert(ruleName); 15 | auto iterator = _disabled.find(ruleName); 16 | if (iterator != _disabled.end()) 17 | { 18 | _disabled.erase(iterator); 19 | } 20 | } 21 | 22 | void RulesetFilter::disableRule(const std::string &ruleName) 23 | { 24 | _disabled.insert(ruleName); 25 | auto iterator = _enabled.find(ruleName); 26 | if (iterator != _enabled.end()) 27 | { 28 | _enabled.erase(iterator); 29 | } 30 | } 31 | 32 | std::vector RulesetFilter::filteredRules() const 33 | { 34 | std::vector filteredRules; 35 | 36 | for (int ruleIdx = 0, numRules = oclint::RuleSet::numberOfRules(); 37 | ruleIdx < numRules; ruleIdx++) 38 | { 39 | RuleBase *rule = oclint::RuleSet::getRuleAtIndex(ruleIdx); 40 | const std::string &name = getName(rule); 41 | if ((_enabled.empty() || find(_enabled.begin(), _enabled.end(), name) != _enabled.end()) && 42 | find(_disabled.begin(), _disabled.end(), name) == _disabled.end()) 43 | { 44 | filteredRules.push_back(rule); 45 | } 46 | } 47 | 48 | return filteredRules; 49 | } 50 | 51 | std::vector RulesetFilter::filteredRuleNames() const 52 | { 53 | const std::vector rules = filteredRules(); 54 | std::vector names(rules.size()); 55 | transform(rules.begin(), rules.end(), names.begin(), getName); 56 | return names; 57 | } 58 | -------------------------------------------------------------------------------- /oclint-driver/reporters.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "oclint/Reporter.h" 4 | 5 | void loadReporter(); 6 | oclint::Reporter* reporter(); 7 | -------------------------------------------------------------------------------- /oclint-driver/reporters_dlfcn_port.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "oclint/GenericException.h" 6 | #include "oclint/Options.h" 7 | 8 | #include "reporters.h" 9 | 10 | static oclint::Reporter* selectedReporter = nullptr; 11 | 12 | void loadReporter() 13 | { 14 | selectedReporter = nullptr; 15 | std::string reportDirPath = oclint::option::reporterPath(); 16 | DIR *pDir = opendir(reportDirPath.c_str()); 17 | if (pDir != nullptr) 18 | { 19 | struct dirent *dirp; 20 | while ((dirp = readdir(pDir))) 21 | { 22 | if (dirp->d_name[0] == '.') 23 | { 24 | continue; 25 | } 26 | std::string reporterPath = reportDirPath + "/" + std::string(dirp->d_name); 27 | void *reporterHandle = dlopen(reporterPath.c_str(), RTLD_LAZY); 28 | if (reporterHandle == nullptr) 29 | { 30 | std::cerr << dlerror() << std::endl; 31 | closedir(pDir); 32 | throw oclint::GenericException("cannot open dynamic library: " + reporterPath); 33 | } 34 | oclint::Reporter* (*createMethodPointer)(); 35 | createMethodPointer = (oclint::Reporter* (*)())dlsym(reporterHandle, "create"); 36 | oclint::Reporter* reporter = (oclint::Reporter*)createMethodPointer(); 37 | if (reporter->name() == oclint::option::reportType()) 38 | { 39 | selectedReporter = reporter; 40 | break; 41 | } 42 | } 43 | closedir(pDir); 44 | } 45 | if (selectedReporter == nullptr) 46 | { 47 | throw oclint::GenericException( 48 | "cannot find dynamic library for report type: " + oclint::option::reportType()); 49 | } 50 | } 51 | 52 | oclint::Reporter* reporter() 53 | { 54 | return selectedReporter; 55 | } 56 | -------------------------------------------------------------------------------- /oclint-driver/reporters_windows_port.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "oclint/GenericException.h" 6 | #include "oclint/Options.h" 7 | 8 | #include "reporters.h" 9 | 10 | static oclint::Reporter *selectedReporter = NULL; 11 | 12 | void loadReporter() 13 | { 14 | selectedReporter = NULL; 15 | std::string reportDirPath = oclint::option::reporterPath(); 16 | DIR *pDir = opendir(reportDirPath.c_str()); 17 | if (pDir != NULL) 18 | { 19 | struct dirent *dirp; 20 | while ((dirp = readdir(pDir))) 21 | { 22 | if (dirp->d_name[0] == '.') 23 | { 24 | continue; 25 | } 26 | std::string reporterPath = reportDirPath + "/" + std::string(dirp->d_name); 27 | HMODULE reporterHandle = LoadLibrary(reporterPath.c_str()); 28 | if (reporterHandle == NULL) 29 | { 30 | std::cerr << GetLastError() << std::endl; 31 | closedir(pDir); 32 | throw oclint::GenericException("cannot open dynamic library: " + reporterPath); 33 | } 34 | typedef oclint::Reporter* (*CreateReporterFunc)(); 35 | CreateReporterFunc createMethodPointer; 36 | createMethodPointer = (CreateReporterFunc) GetProcAddress(reporterHandle, "create"); 37 | oclint::Reporter* reporter = (oclint::Reporter*)createMethodPointer(); 38 | if (reporter->name() == oclint::option::reportType()) 39 | { 40 | selectedReporter = reporter; 41 | break; 42 | } 43 | } 44 | closedir(pDir); 45 | } 46 | if (selectedReporter == NULL) 47 | { 48 | throw oclint::GenericException( 49 | "cannot find dynamic library for report type: " + oclint::option::reportType()); 50 | } 51 | } 52 | 53 | oclint::Reporter* reporter() 54 | { 55 | return selectedReporter; 56 | } 57 | -------------------------------------------------------------------------------- /oclint-driver/rules.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void dynamicLoadRules(std::string ruleDirPath); 4 | -------------------------------------------------------------------------------- /oclint-driver/rules_dlfcn_port.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "oclint/GenericException.h" 6 | 7 | #include "rules.h" 8 | 9 | void dynamicLoadRules(std::string ruleDirPath) 10 | { 11 | DIR *pDir = opendir(ruleDirPath.c_str()); 12 | if (pDir != nullptr) 13 | { 14 | struct dirent *dirp; 15 | while ((dirp = readdir(pDir))) 16 | { 17 | if (dirp->d_name[0] == '.') 18 | { 19 | continue; 20 | } 21 | std::string rulePath = ruleDirPath + "/" + std::string(dirp->d_name); 22 | if (dlopen(rulePath.c_str(), RTLD_LAZY) == nullptr) 23 | { 24 | std::cerr << dlerror() << std::endl; 25 | closedir(pDir); 26 | throw oclint::GenericException("cannot open dynamic library: " + rulePath); 27 | } 28 | } 29 | closedir(pDir); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /oclint-driver/rules_windows_port.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "oclint/GenericException.h" 6 | 7 | #include "rules.h" 8 | 9 | void dynamicLoadRules(std::string ruleDirPath) 10 | { 11 | DIR *pDir = opendir(ruleDirPath.c_str()); 12 | if (pDir != NULL) 13 | { 14 | struct dirent *dirp; 15 | while ((dirp = readdir(pDir))) 16 | { 17 | if (dirp->d_name[0] == '.') 18 | { 19 | continue; 20 | } 21 | std::string rulePath = ruleDirPath + "/" + std::string(dirp->d_name); 22 | HMODULE rule_library = LoadLibrary(rulePath.c_str()); 23 | if (rule_library == NULL) 24 | { 25 | std::cerr << GetLastError() << std::endl; 26 | closedir(pDir); 27 | throw oclint::GenericException("cannot open dynamic library: " + rulePath); 28 | } 29 | } 30 | closedir(pDir); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /oclint-driver/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | MACRO(build_test name) 2 | ADD_EXECUTABLE(${name} ${name}.cpp) 3 | TARGET_LINK_LIBRARIES(${name} 4 | OCLintDriver 5 | OCLintRuleSet 6 | OCLintCore 7 | clangStaticAnalyzerFrontend 8 | clangStaticAnalyzerCheckers 9 | clangStaticAnalyzerCore 10 | clangRewriteFrontend 11 | clangRewrite 12 | ${GTEST_LIBS} 13 | ${PROFILE_RT_LIBS} 14 | ${CLANG_LIBRARIES} 15 | ${REQ_LLVM_LIBRARIES} 16 | ) 17 | 18 | ADD_TEST(${name} ${EXECUTABLE_OUTPUT_PATH}/${name}) 19 | ENDMACRO(build_test) 20 | 21 | BUILD_TEST(RulesetFilterTest) 22 | -------------------------------------------------------------------------------- /oclint-driver/test/RulesetFilterTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "oclint/RulesetFilter.h" 7 | #include "oclint/RuleSet.h" 8 | #include "oclint/RuleBase.h" 9 | 10 | using namespace oclint; 11 | class TestRule : public RuleBase 12 | { 13 | void apply() {} 14 | const std::string name() const 15 | { return "test rule"; } 16 | const std::string category() const 17 | { return "test"; } 18 | int priority() const 19 | { return 0; } 20 | }; 21 | 22 | TEST(RulesetFilterTest, FilteredRulesTest) 23 | { 24 | RulesetFilter filter; 25 | TestRule rule; 26 | RuleSet set(&rule); 27 | std::vector rules = {&rule}; 28 | filter.enableRule("TestRule"); 29 | EXPECT_EQ(filter.filteredRules(), rules); 30 | filter.disableRule("TestRule"); 31 | EXPECT_TRUE(filter.filteredRules().empty()); 32 | } 33 | 34 | int main(int argc, char **argv) 35 | { 36 | ::testing::InitGoogleMock(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /oclint-metrics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | PROJECT(OCLINT_METRICS) 3 | 4 | SET(CMAKE_MODULE_PATH 5 | ${CMAKE_MODULE_PATH} 6 | "${CMAKE_CURRENT_SOURCE_DIR}/../oclint-core/cmake" 7 | ) 8 | 9 | INCLUDE(OCLintConfig) 10 | 11 | INCLUDE_DIRECTORIES(${OCLINT_METRICS_SOURCE_DIR}/include) 12 | 13 | ADD_SUBDIRECTORY(lib) 14 | 15 | IF(TEST_BUILD) 16 | INCLUDE_DIRECTORIES(${OCLINT_METRICS_SOURCE_DIR}/test/headers) 17 | ADD_SUBDIRECTORY(test) 18 | ENDIF() 19 | -------------------------------------------------------------------------------- /oclint-metrics/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2014 Longyi Qi and the OCLint project contributors. 2 | Copyright (C) 2015-2018 Ryuichi Laboratories and the OCLint project contributors. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the author nor the names of its contributors may be used 14 | to endorse or promote products derived from this software without specific 15 | prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /oclint-metrics/include/oclint/metric/CyclomaticComplexityMetric.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_METRIC_CYCLOMATICCOMPLEXITYMETRIC_H 2 | #define OCLINT_METRIC_CYCLOMATICCOMPLEXITYMETRIC_H 3 | 4 | #include 5 | #include 6 | 7 | /* 8 | * References: 9 | * - McCabe (December 1976). “A Complexity Measure”. 10 | * IEEE Transactions on Software Engineering: 308–320 11 | */ 12 | 13 | namespace oclint 14 | { 15 | 16 | class CyclomaticComplexityMetric : public clang::RecursiveASTVisitor 17 | { 18 | private: 19 | int _count; 20 | 21 | public: 22 | int calculate(clang::Decl *decl); 23 | 24 | bool VisitIfStmt(clang::IfStmt *stmt); 25 | bool VisitForStmt(clang::ForStmt *stmt); 26 | bool VisitObjCForCollectionStmt(clang::ObjCForCollectionStmt *stmt); 27 | bool VisitWhileStmt(clang::WhileStmt *stmt); 28 | bool VisitDoStmt(clang::DoStmt *stmt); 29 | bool VisitCaseStmt(clang::CaseStmt *stmt); 30 | bool VisitObjCAtCatchStmt(clang::ObjCAtCatchStmt *stmt); 31 | bool VisitCXXCatchStmt(clang::CXXCatchStmt *stmt); 32 | bool VisitConditionalOperator(clang::ConditionalOperator *op); 33 | bool VisitBinaryOperator(clang::BinaryOperator *op); 34 | }; 35 | 36 | } // end namespace oclint 37 | 38 | extern "C" int getCyclomaticComplexity(clang::Decl *decl); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /oclint-metrics/include/oclint/metric/NPathComplexityMetric.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_METRIC_NPATHCOMPLEXITYMETRIC_H 2 | #define OCLINT_METRIC_NPATHCOMPLEXITYMETRIC_H 3 | 4 | #define DISPATH(STMT_TYPE) if (clang::isa(node)) \ 5 | return nPath(clang::dyn_cast(node)) 6 | 7 | #include 8 | 9 | /* 10 | * References: 11 | * - Brian A. Nejmeh (1988). “NPATH: a measure of execution path complexity and 12 | * its applications”. Communications of the ACM 31 (2) p. 188-200 13 | */ 14 | 15 | namespace oclint 16 | { 17 | 18 | class NPathComplexityMetric 19 | { 20 | public: 21 | int nPath(clang::Stmt *node) 22 | { 23 | if (node) 24 | { 25 | DISPATH(clang::CompoundStmt); 26 | DISPATH(clang::IfStmt); 27 | DISPATH(clang::WhileStmt); 28 | DISPATH(clang::DoStmt); 29 | DISPATH(clang::ForStmt); 30 | DISPATH(clang::SwitchStmt); 31 | DISPATH(clang::SwitchCase); 32 | DISPATH(clang::ObjCForCollectionStmt); 33 | } 34 | return 1; 35 | } 36 | 37 | int nPath(clang::Expr *node) 38 | { 39 | if (node) 40 | { 41 | DISPATH(clang::ConditionalOperator); 42 | DISPATH(clang::BinaryOperator); 43 | DISPATH(clang::ParenExpr); 44 | DISPATH(clang::CastExpr); 45 | } 46 | return 0; 47 | } 48 | 49 | int nPath(clang::CompoundStmt *stmt); 50 | int nPath(clang::IfStmt *stmt); 51 | int nPath(clang::WhileStmt *stmt); 52 | int nPath(clang::DoStmt *stmt); 53 | int nPath(clang::ForStmt *stmt); 54 | int nPath(clang::ObjCForCollectionStmt *stmt); 55 | int nPath(clang::SwitchStmt *stmt); 56 | int nPath(clang::SwitchCase *stmt); 57 | int nPath(clang::ConditionalOperator *expr); 58 | int nPath(clang::BinaryOperator *expr); 59 | int nPath(clang::ParenExpr *expr); 60 | int nPath(clang::CastExpr *expr); 61 | }; 62 | 63 | } // end namespace oclint 64 | 65 | extern "C" int getNPathComplexity(clang::Stmt *stmt); 66 | 67 | #undef DISPATH 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /oclint-metrics/include/oclint/metric/NcssMetric.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_METRIC_NCSSMETRIC_H 2 | #define OCLINT_METRIC_NCSSMETRIC_H 3 | 4 | #define DISPATH(STMT_TYPE) if (clang::isa(node)) \ 5 | return ncss(clang::dyn_cast(node)) 6 | 7 | #include 8 | 9 | namespace oclint 10 | { 11 | 12 | class NcssMetric 13 | { 14 | public: 15 | int ncss(clang::Stmt *node) 16 | { 17 | if (node) 18 | { 19 | DISPATH(clang::NullStmt); 20 | DISPATH(clang::CompoundStmt); 21 | DISPATH(clang::IfStmt); 22 | DISPATH(clang::WhileStmt); 23 | DISPATH(clang::DoStmt); 24 | DISPATH(clang::ForStmt); 25 | DISPATH(clang::ObjCForCollectionStmt); 26 | DISPATH(clang::SwitchStmt); 27 | DISPATH(clang::SwitchCase); 28 | DISPATH(clang::CXXTryStmt); 29 | DISPATH(clang::CXXCatchStmt); 30 | DISPATH(clang::ObjCAtTryStmt); 31 | DISPATH(clang::ObjCAtCatchStmt); 32 | DISPATH(clang::ObjCAtFinallyStmt); 33 | DISPATH(clang::ObjCAtSynchronizedStmt); 34 | DISPATH(clang::ObjCAutoreleasePoolStmt); 35 | return 1; 36 | } 37 | return 0; 38 | } 39 | 40 | int ncss(clang::NullStmt *stmt); 41 | int ncss(clang::CompoundStmt *stmt); 42 | int ncss(clang::IfStmt *stmt); 43 | int ncss(clang::WhileStmt *stmt); 44 | int ncss(clang::DoStmt *stmt); 45 | int ncss(clang::ForStmt *stmt); 46 | int ncss(clang::ObjCForCollectionStmt *stmt); 47 | int ncss(clang::SwitchStmt *stmt); 48 | int ncss(clang::SwitchCase *stmt); 49 | int ncss(clang::CXXTryStmt *stmt); 50 | int ncss(clang::CXXCatchStmt *stmt); 51 | int ncss(clang::ObjCAtTryStmt *stmt); 52 | int ncss(clang::ObjCAtCatchStmt *stmt); 53 | int ncss(clang::ObjCAtFinallyStmt *stmt); 54 | int ncss(clang::ObjCAtSynchronizedStmt *stmt); 55 | int ncss(clang::ObjCAutoreleasePoolStmt *stmt); 56 | }; 57 | 58 | } // end namespace oclint 59 | 60 | extern "C" int getNcssCount(clang::Decl *decl); 61 | 62 | #undef DISPATH 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /oclint-metrics/include/oclint/metric/StmtDepthMetric.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_METRIC_STMTDEPTHMETRIC_H 2 | #define OCLINT_METRIC_STMTDEPTHMETRIC_H 3 | 4 | #define DISPATH(STMT_TYPE) if (clang::isa(node)) \ 5 | return depth(clang::dyn_cast(node)) 6 | 7 | #include 8 | 9 | namespace oclint 10 | { 11 | 12 | class StmtDepthMetric 13 | { 14 | public: 15 | int depth(clang::Stmt *node) 16 | { 17 | if (node) 18 | { 19 | DISPATH(clang::CompoundStmt); 20 | DISPATH(clang::IfStmt); 21 | DISPATH(clang::WhileStmt); 22 | DISPATH(clang::DoStmt); 23 | DISPATH(clang::ForStmt); 24 | DISPATH(clang::ObjCForCollectionStmt); 25 | DISPATH(clang::SwitchStmt); 26 | DISPATH(clang::SwitchCase); 27 | DISPATH(clang::CXXTryStmt); 28 | DISPATH(clang::CXXCatchStmt); 29 | DISPATH(clang::ObjCAtTryStmt); 30 | DISPATH(clang::ObjCAtCatchStmt); 31 | DISPATH(clang::ObjCAtFinallyStmt); 32 | DISPATH(clang::ObjCAtSynchronizedStmt); 33 | DISPATH(clang::ObjCAutoreleasePoolStmt); 34 | } 35 | return 0; 36 | } 37 | 38 | int depth(clang::CompoundStmt *stmt); 39 | int depth(clang::IfStmt *stmt); 40 | int depth(clang::WhileStmt *stmt); 41 | int depth(clang::DoStmt *stmt); 42 | int depth(clang::ForStmt *stmt); 43 | int depth(clang::ObjCForCollectionStmt *stmt); 44 | int depth(clang::SwitchStmt *stmt); 45 | int depth(clang::SwitchCase *stmt); 46 | int depth(clang::CXXTryStmt *stmt); 47 | int depth(clang::CXXCatchStmt *stmt); 48 | int depth(clang::ObjCAtTryStmt *stmt); 49 | int depth(clang::ObjCAtCatchStmt *stmt); 50 | int depth(clang::ObjCAtFinallyStmt *stmt); 51 | int depth(clang::ObjCAtSynchronizedStmt *stmt); 52 | int depth(clang::ObjCAutoreleasePoolStmt *stmt); 53 | }; 54 | 55 | } // end namespace oclint 56 | 57 | extern "C" int getStmtDepth(clang::Stmt *stmt); 58 | 59 | #undef DISPATH 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /oclint-metrics/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET (MetricSource 3 | CyclomaticComplexityMetric.cpp 4 | NcssMetric.cpp 5 | NPathComplexityMetric.cpp 6 | StmtDepthMetric.cpp 7 | ) 8 | 9 | IF (MINGW) 10 | ADD_LIBRARY(OCLintMetric SHARED ${MetricSource}) 11 | TARGET_LINK_LIBRARIES(OCLintMetric 12 | ${CLANG_LIBRARIES} 13 | ${REQ_LLVM_LIBRARIES} 14 | ) 15 | SET_TARGET_PROPERTIES(OCLintMetric 16 | PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 17 | ) 18 | 19 | IF (TEST_BUILD) 20 | TARGET_LINK_LIBRARIES(OCLintMetric ${PROFILE_RT_LIBS}) 21 | ENDIF() 22 | TARGET_LINK_LIBRARIES(OCLintMetric LINK_INTERFACE_LIBRARIES # Nothing 23 | ) 24 | ELSE() 25 | ADD_LIBRARY(OCLintMetric ${MetricSource}) 26 | ENDIF() 27 | -------------------------------------------------------------------------------- /oclint-metrics/lib/CyclomaticComplexityMetric.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/metric/CyclomaticComplexityMetric.h" 2 | 3 | using namespace oclint; 4 | 5 | int CyclomaticComplexityMetric::calculate(clang::Decl *decl) 6 | { 7 | _count = 0; 8 | (void) /* explicitly ignore the return of this function */ TraverseDecl(decl); 9 | return _count + 1; 10 | } 11 | 12 | bool CyclomaticComplexityMetric::VisitIfStmt(clang::IfStmt *) 13 | { 14 | _count++; 15 | return true; 16 | } 17 | 18 | bool CyclomaticComplexityMetric::VisitForStmt(clang::ForStmt *) 19 | { 20 | _count++; 21 | return true; 22 | } 23 | 24 | bool CyclomaticComplexityMetric::VisitObjCForCollectionStmt(clang::ObjCForCollectionStmt *) 25 | { 26 | _count++; 27 | return true; 28 | } 29 | 30 | bool CyclomaticComplexityMetric::VisitWhileStmt(clang::WhileStmt *) 31 | { 32 | _count++; 33 | return true; 34 | } 35 | 36 | bool CyclomaticComplexityMetric::VisitDoStmt(clang::DoStmt *) 37 | { 38 | _count++; 39 | return true; 40 | } 41 | 42 | bool CyclomaticComplexityMetric::VisitCaseStmt(clang::CaseStmt *) 43 | { 44 | _count++; 45 | return true; 46 | } 47 | 48 | bool CyclomaticComplexityMetric::VisitObjCAtCatchStmt(clang::ObjCAtCatchStmt *) 49 | { 50 | _count++; 51 | return true; 52 | } 53 | 54 | bool CyclomaticComplexityMetric::VisitCXXCatchStmt(clang::CXXCatchStmt *) 55 | { 56 | _count++; 57 | return true; 58 | } 59 | 60 | bool CyclomaticComplexityMetric::VisitConditionalOperator(clang::ConditionalOperator *) 61 | { 62 | _count++; 63 | return true; 64 | } 65 | 66 | bool CyclomaticComplexityMetric::VisitBinaryOperator(clang::BinaryOperator *binaryOperator) 67 | { 68 | if (binaryOperator->getOpcode() == clang::BO_LAnd || 69 | binaryOperator->getOpcode() == clang::BO_LOr) 70 | { 71 | _count++; 72 | } 73 | return true; 74 | } 75 | 76 | extern "C" int getCyclomaticComplexity(clang::Decl *decl) 77 | { 78 | CyclomaticComplexityMetric ccnMetric; 79 | return ccnMetric.calculate(decl); 80 | } 81 | -------------------------------------------------------------------------------- /oclint-metrics/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | MACRO(build_test name) 2 | ADD_EXECUTABLE(${name} ${name}.cpp) 3 | IF (MINGW) 4 | TARGET_LINK_LIBRARIES(${name} 5 | ${GTEST_LIBS} 6 | ${PROFILE_RT_LIBS} 7 | ${CLANG_LIBRARIES} 8 | ${REQ_LLVM_LIBRARIES} 9 | ${CMAKE_DL_LIBS} 10 | OCLintMetric 11 | ) 12 | ELSE() 13 | TARGET_LINK_LIBRARIES(${name} 14 | OCLintMetric 15 | ${GTEST_LIBS} 16 | ${PROFILE_RT_LIBS} 17 | ${CLANG_LIBRARIES} 18 | ${REQ_LLVM_LIBRARIES} 19 | ${CMAKE_DL_LIBS} 20 | ) 21 | ENDIF() 22 | 23 | ADD_TEST(${name} ${EXECUTABLE_OUTPUT_PATH}/${name}) 24 | ENDMACRO(build_test) 25 | 26 | BUILD_TEST(CanaryTest) 27 | BUILD_TEST(CyclomaticComplexityMetricTest) 28 | BUILD_TEST(NPathComplexityMetricTest) 29 | BUILD_TEST(NcssMetricTest) 30 | BUILD_TEST(StmtDepthMetricTest) 31 | -------------------------------------------------------------------------------- /oclint-metrics/test/CanaryTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestHeaders.h" 2 | 3 | TEST(CanaryTest, AlwaysTrue) 4 | { 5 | EXPECT_TRUE(true); 6 | } 7 | 8 | int main(int argc, char **argv) 9 | { 10 | ::testing::InitGoogleMock(&argc, argv); 11 | return RUN_ALL_TESTS(); 12 | } 13 | -------------------------------------------------------------------------------- /oclint-metrics/test/headers/TestHeaders.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace ::testing; 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace llvm; 17 | using namespace clang; 18 | using namespace clang::ast_matchers; 19 | using namespace clang::tooling; 20 | 21 | class TestFrontendAction : public clang::ASTFrontendAction 22 | { 23 | private: 24 | MatchFinder* _finder; 25 | 26 | public: 27 | TestFrontendAction(MatchFinder &finder) 28 | { 29 | _finder = &finder; 30 | } 31 | 32 | std::unique_ptr CreateASTConsumer( 33 | clang::CompilerInstance &, llvm::StringRef) override 34 | { 35 | return _finder->newASTConsumer(); 36 | } 37 | }; 38 | 39 | void testMatcherOnCode(const Twine &fileName, MatchFinder &finder, const string &code) 40 | { 41 | FrontendAction *action = new TestFrontendAction(finder); 42 | Twine twine(code); 43 | if (!runToolOnCode(action, twine, fileName)) 44 | { 45 | FAIL(); 46 | } 47 | } 48 | 49 | void testMatcherOnCode(MatchFinder &finder, const string &code) 50 | { 51 | testMatcherOnCode("input.c", finder, code); 52 | } 53 | 54 | void testMatcherOnCXXCode(MatchFinder &finder, const string &code) 55 | { 56 | testMatcherOnCode("input.cpp", finder, code); 57 | } 58 | 59 | void testMatcherOnObjCCode(MatchFinder &finder, const string &code) 60 | { 61 | testMatcherOnCode("input.m", finder, code); 62 | } 63 | -------------------------------------------------------------------------------- /oclint-reporters/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | PROJECT(OCLINT_REPORTERS) 3 | 4 | SET(CMAKE_MODULE_PATH 5 | ${CMAKE_MODULE_PATH} 6 | "${CMAKE_CURRENT_SOURCE_DIR}/../oclint-core/cmake" 7 | ) 8 | 9 | INCLUDE(OCLintConfig) 10 | 11 | INCLUDE_DIRECTORIES(${OCLINT_SOURCE_DIR}/include) 12 | LINK_DIRECTORIES(${OCLINT_BUILD_DIR}/lib) 13 | 14 | IF(TEST_BUILD) 15 | INCLUDE_DIRECTORIES(${OCLINT_REPORTERS_SOURCE_DIR}/reporters) 16 | ADD_SUBDIRECTORY(test) 17 | ELSE(TEST_BUILD) 18 | ADD_SUBDIRECTORY(reporters) 19 | ENDIF() 20 | -------------------------------------------------------------------------------- /oclint-reporters/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2014 Longyi Qi and the OCLint project contributors. 2 | Copyright (C) 2015-2018 Ryuichi Laboratories and the OCLint project contributors. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the author nor the names of its contributors may be used 14 | to endorse or promote products derived from this software without specific 15 | prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /oclint-reporters/reporters/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | MACRO(build_dynamic_reporter name) 2 | IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 3 | SET(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup") 4 | ENDIF() 5 | 6 | ADD_LIBRARY(${name}Reporter SHARED ${name}Reporter.cpp) 7 | 8 | SET_TARGET_PROPERTIES(${name}Reporter 9 | PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/reporters.dl 10 | RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/reporters.dl 11 | ) 12 | 13 | TARGET_LINK_LIBRARIES(${name}Reporter 14 | OCLintCore 15 | ) 16 | ENDMACRO(build_dynamic_reporter) 17 | 18 | BUILD_DYNAMIC_REPORTER(Text) 19 | BUILD_DYNAMIC_REPORTER(HTML) 20 | BUILD_DYNAMIC_REPORTER(XML) 21 | BUILD_DYNAMIC_REPORTER(JSON) 22 | BUILD_DYNAMIC_REPORTER(PMD) 23 | BUILD_DYNAMIC_REPORTER(Xcode) 24 | -------------------------------------------------------------------------------- /oclint-reporters/reporters/XcodeReporter.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/Results.h" 2 | #include "oclint/Reporter.h" 3 | #include "oclint/RuleBase.h" 4 | #include "oclint/ViolationSet.h" 5 | 6 | using namespace oclint; 7 | 8 | class XcodeReporter : public Reporter 9 | { 10 | public: 11 | virtual const std::string name() const override 12 | { 13 | return "xcode"; 14 | } 15 | 16 | virtual void report(Results* results, std::ostream& out) override 17 | { 18 | // Compiler warnings, errors and clang static analyzer results 19 | // can be retrieved from Xcode directly, so we only need to 20 | // output violations that is emitted by oclint. 21 | 22 | for (const auto& violation : results->allViolations()) 23 | { 24 | writeViolation(out, violation); 25 | out << std::endl; 26 | } 27 | } 28 | 29 | void writeViolation(std::ostream &out, const Violation &violation) 30 | { 31 | out << violation.path << ":" << violation.startLine << ":" << violation.startColumn; 32 | const RuleBase *rule = violation.rule; 33 | out << ": warning: " << rule->name(); 34 | out << " [" << rule->category() << "|P" << rule->priority() << "]"; 35 | out << " " << violation.message; 36 | } 37 | }; 38 | 39 | extern "C" Reporter* create() 40 | { 41 | return new XcodeReporter(); 42 | } 43 | -------------------------------------------------------------------------------- /oclint-reporters/template/Reporter.tmpl: -------------------------------------------------------------------------------- 1 | #include "oclint/Reporter.h" 2 | 3 | using namespace oclint; 4 | 5 | class {{REPORTER_CLASS_NAME}}Reporter : public Reporter 6 | { 7 | public: 8 | virtual const std::string name() const override 9 | { 10 | return "{{REPORTER_NAME}}"; 11 | } 12 | 13 | virtual void report(Results *results, std::ostream &out) override 14 | { 15 | } 16 | }; 17 | 18 | extern "C" Reporter* create() 19 | { 20 | return new {{REPORTER_CLASS_NAME}}Reporter(); 21 | } 22 | -------------------------------------------------------------------------------- /oclint-reporters/template/ReporterTest.tmpl: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "{{REPORTER_CLASS_NAME}}Reporter.cpp" 5 | 6 | using namespace ::testing; 7 | using namespace oclint; 8 | 9 | TEST({{REPORTER_CLASS_NAME}}ReporterTest, PropertyTest) 10 | { 11 | {{REPORTER_CLASS_NAME}}Reporter reporter; 12 | EXPECT_THAT(reporter.name(), StrEq("{{REPORTER_NAME}}")); 13 | } 14 | 15 | TEST({{REPORTER_CLASS_NAME}}ReporterTest, FirstFailingTest) 16 | { 17 | EXPECT_FALSE("Start writing a new test"); 18 | } 19 | 20 | int main(int argc, char **argv) 21 | { 22 | ::testing::InitGoogleMock(&argc, argv); 23 | return RUN_ALL_TESTS(); 24 | } 25 | -------------------------------------------------------------------------------- /oclint-reporters/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | MACRO(build_test name) 2 | ADD_EXECUTABLE(${name} ${name}.cpp) 3 | TARGET_LINK_LIBRARIES(${name} 4 | ${GTEST_LIBS} 5 | ${PROFILE_RT_LIBS} 6 | ${CLANG_LIBRARIES} 7 | ${REQ_LLVM_LIBRARIES} 8 | OCLintCore 9 | ) 10 | 11 | ADD_TEST(${name} ${EXECUTABLE_OUTPUT_PATH}/${name}) 12 | ENDMACRO(build_test) 13 | 14 | BUILD_TEST(CanaryTest) 15 | BUILD_TEST(TextReporterTest) 16 | BUILD_TEST(HTMLReporterTest) 17 | BUILD_TEST(XMLReporterTest) 18 | BUILD_TEST(JSONReporterTest) 19 | BUILD_TEST(PMDReporterTest) 20 | BUILD_TEST(XcodeReporterTest) 21 | -------------------------------------------------------------------------------- /oclint-reporters/test/CanaryTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | TEST(CanaryTest, AlwaysTrue) 5 | { 6 | EXPECT_TRUE(true); 7 | } 8 | 9 | int main(int argc, char **argv) 10 | { 11 | ::testing::InitGoogleMock(&argc, argv); 12 | return RUN_ALL_TESTS(); 13 | } 14 | -------------------------------------------------------------------------------- /oclint-reporters/test/ReportTestResults.h: -------------------------------------------------------------------------------- 1 | #include "oclint/ResultCollector.h" 2 | #include "oclint/AbstractResults.h" 3 | 4 | namespace oclint 5 | { 6 | 7 | class ReportTestResults : public AbstractResults 8 | { 9 | private: 10 | std::vector _violations; 11 | 12 | public: 13 | explicit ReportTestResults(const ResultCollector &resultCollector) 14 | : AbstractResults(resultCollector) 15 | { 16 | } 17 | 18 | std::vector allViolations() const 19 | { 20 | return _violations; 21 | } 22 | 23 | const std::vector& allErrors() const 24 | { 25 | return _violations; 26 | } 27 | 28 | const std::vector& allWarnings() const 29 | { 30 | return _violations; 31 | } 32 | 33 | const std::vector& allCheckerBugs() const 34 | { 35 | return _violations; 36 | } 37 | }; 38 | 39 | } 40 | 41 | oclint::Results *getTestResults() 42 | { 43 | oclint::ResultCollector *resultCollector = oclint::ResultCollector::getInstance(); 44 | return new oclint::ReportTestResults(*resultCollector); 45 | } 46 | -------------------------------------------------------------------------------- /oclint-reporters/test/XcodeReporterTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "ReportTestResults.h" 7 | #include "XcodeReporter.cpp" 8 | 9 | using namespace ::testing; 10 | using namespace oclint; 11 | 12 | class MockRuleBase : public RuleBase 13 | { 14 | public: 15 | MOCK_METHOD0(apply, void()); 16 | MOCK_CONST_METHOD0(name, const std::string()); 17 | MOCK_CONST_METHOD0(priority, int()); 18 | MOCK_CONST_METHOD0(category, const std::string()); 19 | }; 20 | 21 | class XcodeReporterTest : public ::testing::Test 22 | { 23 | protected: 24 | XcodeReporter reporter; 25 | }; 26 | 27 | TEST_F(XcodeReporterTest, PropertyTest) 28 | { 29 | EXPECT_THAT(reporter.name(), StrEq("xcode")); 30 | } 31 | 32 | TEST_F(XcodeReporterTest, WriteViolation) 33 | { 34 | RuleBase *rule = new MockRuleBase(); 35 | Violation violation(rule, "test path", 1, 2, 3, 4, "test message"); 36 | std::ostringstream oss; 37 | reporter.writeViolation(oss, violation); 38 | EXPECT_THAT(oss.str(), HasSubstr(": warning: ")); 39 | EXPECT_THAT(oss.str(), HasSubstr("test path")); 40 | EXPECT_THAT(oss.str(), HasSubstr("1:2")); 41 | EXPECT_THAT(oss.str(), HasSubstr("test message")); 42 | } 43 | 44 | int main(int argc, char **argv) 45 | { 46 | ::testing::InitGoogleMock(&argc, argv); 47 | return RUN_ALL_TESTS(); 48 | } 49 | -------------------------------------------------------------------------------- /oclint-rules/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | PROJECT(OCLINT_RULES) 3 | 4 | SET(CMAKE_MODULE_PATH 5 | ${CMAKE_MODULE_PATH} 6 | "${CMAKE_CURRENT_SOURCE_DIR}/../oclint-core/cmake" 7 | ) 8 | 9 | INCLUDE(OCLintConfig) 10 | 11 | INCLUDE_DIRECTORIES( 12 | ${OCLINT_SOURCE_DIR}/include 13 | ${OCLINT_METRICS_SOURCE_DIR}/include 14 | ${OCLINT_RULES_SOURCE_DIR}/include 15 | ${OCLINT_RULES_SOURCE_DIR} 16 | ) 17 | LINK_DIRECTORIES( 18 | ${OCLINT_BUILD_DIR}/lib 19 | ${OCLINT_METRICS_BUILD_DIR}/lib 20 | ) 21 | 22 | ADD_SUBDIRECTORY(lib) 23 | 24 | IF(TEST_BUILD) 25 | INCLUDE_DIRECTORIES(${OCLINT_RULES_SOURCE_DIR}/test/headers) 26 | ADD_SUBDIRECTORY(test) 27 | ELSE(TEST_BUILD) 28 | ADD_SUBDIRECTORY(rules) 29 | ENDIF() 30 | -------------------------------------------------------------------------------- /oclint-rules/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2014 Longyi Qi and the OCLint project contributors. 2 | Copyright (C) 2015-2018 Ryuichi Laboratories and the OCLint project contributors. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the author nor the names of its contributors may be used 14 | to endorse or promote products derived from this software without specific 15 | prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/AbstractASTMatcherRule.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ABSTRACTASTMATCHERRULE_H 2 | #define OCLINT_ABSTRACTASTMATCHERRULE_H 3 | 4 | #include 5 | 6 | #include "oclint/AbstractASTVisitorRule.h" 7 | 8 | namespace oclint 9 | { 10 | 11 | 12 | class AbstractASTMatcherRule : 13 | public AbstractASTVisitorRule, 14 | public clang::ast_matchers::MatchFinder::MatchCallback 15 | { 16 | private: 17 | clang::ast_matchers::MatchFinder *_finder; 18 | 19 | protected: 20 | virtual void 21 | run(const clang::ast_matchers::MatchFinder::MatchResult& result) override; 22 | 23 | template 24 | void addMatcher(const T &nodeMatch) 25 | { 26 | _finder->addMatcher(nodeMatch, this); 27 | } 28 | 29 | public: 30 | virtual void setUp() override; 31 | 32 | bool VisitDecl(clang::Decl *decl); 33 | 34 | bool VisitStmt(clang::Stmt *stmt); 35 | 36 | virtual void tearDown() override; 37 | 38 | public: 39 | virtual ~AbstractASTMatcherRule(); 40 | 41 | virtual void setUpMatcher() = 0; 42 | virtual void callback(const clang::ast_matchers::MatchFinder::MatchResult &result) = 0; 43 | }; 44 | 45 | } // end namespace oclint 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/AbstractASTRuleBase.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ABSTRACTASTRULEBASE_H 2 | #define OCLINT_ABSTRACTASTRULEBASE_H 3 | 4 | #include 5 | 6 | #include "oclint/RuleBase.h" 7 | 8 | namespace oclint 9 | { 10 | 11 | enum LanguageSupportFlags 12 | { 13 | LANG_C = 1 << 0, 14 | LANG_CXX = 1 << 1, 15 | LANG_OBJC = 1 << 2 16 | }; 17 | 18 | class AbstractASTRuleBase : public RuleBase 19 | { 20 | protected: 21 | void addViolation(clang::SourceLocation startLocation, 22 | clang::SourceLocation endLocation, RuleBase *rule, const std::string& message = ""); 23 | 24 | void addViolation(const clang::Decl *decl, RuleBase *rule, const std::string& message = ""); 25 | void addViolation(const clang::Stmt *stmt, RuleBase *rule, const std::string& message = ""); 26 | 27 | private: 28 | bool supportsC() const; 29 | bool supportsCXX() const; 30 | bool supportsObjC() const; 31 | 32 | protected: 33 | virtual unsigned int supportedLanguages() const; 34 | bool isLanguageSupported() const; 35 | 36 | public: 37 | virtual ~AbstractASTRuleBase(); 38 | }; 39 | 40 | } // end namespace oclint 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/AbstractASTVisitorRule.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ABSTRACTASTVISITORRULE_H 2 | #define OCLINT_ABSTRACTASTVISITORRULE_H 3 | 4 | #include 5 | 6 | #include "oclint/AbstractASTRuleBase.h" 7 | 8 | namespace oclint 9 | { 10 | 11 | template 12 | class AbstractASTVisitorRule : public AbstractASTRuleBase, protected clang::RecursiveASTVisitor 13 | { 14 | friend class clang::RecursiveASTVisitor; 15 | protected: 16 | virtual void apply() 17 | { 18 | if (!isLanguageSupported()) 19 | { 20 | return; 21 | } 22 | 23 | setUp(); 24 | clang::SourceManager *sourceManager = &_carrier->getSourceManager(); 25 | clang::DeclContext *decl = _carrier->getTranslationUnitDecl(); 26 | for (clang::DeclContext::decl_iterator it = decl->decls_begin(), declEnd = decl->decls_end(); 27 | it != declEnd; ++it) 28 | { 29 | clang::SourceLocation startLocation = (*it)->getLocStart(); 30 | if (startLocation.isValid() && 31 | sourceManager->getMainFileID() == sourceManager->getFileID(startLocation)) 32 | { 33 | (void) /* explicitly ignore the return of this function */ 34 | clang::RecursiveASTVisitor::TraverseDecl(*it); 35 | } 36 | } 37 | tearDown(); 38 | } 39 | 40 | public: 41 | virtual ~AbstractASTVisitorRule() {} 42 | 43 | virtual void setUp() {} 44 | virtual void tearDown() {} 45 | }; 46 | 47 | } // end namespace oclint 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/AbstractSourceCodeReaderRule.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ABSTRACTSOURCECODEREADERRULE_H 2 | #define OCLINT_ABSTRACTSOURCECODEREADERRULE_H 3 | 4 | #include "oclint/RuleBase.h" 5 | 6 | namespace oclint 7 | { 8 | 9 | class AbstractSourceCodeReaderRule : public RuleBase 10 | { 11 | protected: 12 | virtual void apply() override; 13 | 14 | void addViolation(int startLine, int startColumn, 15 | int endLine, int endColumn, RuleBase *rule, const std::string& message = ""); 16 | 17 | public: 18 | virtual ~AbstractSourceCodeReaderRule(); 19 | 20 | virtual void eachLine(int lineNumber, std::string line) = 0; 21 | }; 22 | 23 | } // end namespace oclint 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/helper/AttributeHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_HELPER_ATTRIBUTEHELPER_H 2 | #define OCLINT_HELPER_ATTRIBUTEHELPER_H 3 | 4 | #include 5 | 6 | namespace clang { class Decl; } 7 | namespace oclint { class RuleBase; } 8 | 9 | bool declHasOCLintAttribute( 10 | const clang::Decl *decl, 11 | const std::string& attributeName, 12 | std::string* comment = nullptr); 13 | 14 | bool declHasActionAttribute( 15 | const clang::Decl *decl, 16 | const std::string& action, 17 | const oclint::RuleBase& rule, 18 | std::string* comment = nullptr); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/helper/EnforceHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_HELPER_ENFORCEHELPER_H 2 | #define OCLINT_HELPER_ENFORCEHELPER_H 3 | 4 | #include 5 | 6 | namespace clang { class Decl; } 7 | namespace oclint { class RuleBase; } 8 | 9 | bool declHasEnforceAttribute( 10 | const clang::Decl *decl, 11 | const oclint::RuleBase& rule, 12 | std::string* comment = nullptr); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/helper/SuppressHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_HELPER_SUPPRESSHELPER_H 2 | #define OCLINT_HELPER_SUPPRESSHELPER_H 3 | 4 | #include 5 | 6 | #include "oclint/RuleBase.h" 7 | 8 | bool shouldSuppress(const clang::Decl *decl, clang::ASTContext &context, oclint::RuleBase *rule); 9 | bool shouldSuppress(const clang::Stmt *stmt, clang::ASTContext &context, oclint::RuleBase *rule); 10 | bool shouldSuppress(int beginLine, clang::ASTContext& context, 11 | oclint::RuleBase* rule = nullptr); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/util/ASTUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_UTIL_ASTUTIL_H 2 | #define OCLINT_UTIL_ASTUTIL_H 3 | 4 | #include 5 | 6 | bool isObjCMethodDeclaredInSuperClass(clang::ObjCMethodDecl *decl); 7 | bool isObjCMethodDeclaredInProtocol(clang::ObjCMethodDecl *decl); 8 | bool isObjCMethodDeclLocatedInInterfaceContainer(clang::ObjCMethodDecl *decl); 9 | bool isObjCMethodDeclInChildOfClass(const clang::ObjCMethodDecl* decl, const std::string& className); 10 | bool isObjCInterfaceClassOrSubclass(const clang::ObjCInterfaceDecl* decl, const std::string& className); 11 | bool isCppMethodDeclLocatedInCppRecordDecl(clang::CXXMethodDecl *decl); 12 | bool isANullPointerExpr(const clang::Expr& expr); 13 | bool areSameExpr(clang::ASTContext& context, const clang::Expr& lhs, const clang::Expr& rhs); 14 | const clang::Expr* ignoreCastExpr(const clang::Expr& expr); 15 | int getLineCount(clang::SourceRange sourceRange, const clang::SourceManager& sourceManager); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /oclint-rules/include/oclint/util/StdUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_UTIL_STDUTIL_H 2 | #define OCLINT_UTIL_STDUTIL_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | std::string toString(T item) 10 | { 11 | std::stringstream buffer; 12 | buffer << item; 13 | return buffer.str(); 14 | } 15 | 16 | template 17 | bool vectorContains(T item, std::vector &collection) 18 | { 19 | return std::find(collection.begin(), collection.end(), item) != collection.end(); 20 | } 21 | 22 | bool isUnderscore(char aChar); 23 | std::string removeUnderscores(std::string str); 24 | std::string capitalizeFirstLetter(std::string str); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /oclint-rules/lib/AbstractASTMatcherRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTMatcherRule.h" 2 | 3 | namespace oclint 4 | { 5 | 6 | /*virtual*/ 7 | AbstractASTMatcherRule::~AbstractASTMatcherRule() {} 8 | 9 | /*virtual*/ 10 | void AbstractASTMatcherRule::run(const clang::ast_matchers::MatchFinder::MatchResult &result) 11 | { 12 | callback(result); 13 | } 14 | 15 | /*virtual*/ 16 | void AbstractASTMatcherRule::setUp() 17 | { 18 | _finder = new clang::ast_matchers::MatchFinder(); 19 | setUpMatcher(); 20 | } 21 | 22 | bool AbstractASTMatcherRule::VisitDecl(clang::Decl *decl) 23 | { 24 | _finder->match(*decl, *_carrier->getASTContext()); 25 | return true; 26 | } 27 | 28 | bool AbstractASTMatcherRule::VisitStmt(clang::Stmt *stmt) 29 | { 30 | _finder->match(*stmt, *_carrier->getASTContext()); 31 | return true; 32 | } 33 | 34 | /*virtual*/ 35 | void AbstractASTMatcherRule::tearDown() 36 | { 37 | delete _finder; 38 | _finder = nullptr; 39 | } 40 | 41 | } // end namespace oclint 42 | -------------------------------------------------------------------------------- /oclint-rules/lib/AbstractSourceCodeReaderRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractSourceCodeReaderRule.h" 2 | #include 3 | #include "oclint/helper/SuppressHelper.h" 4 | 5 | namespace oclint 6 | { 7 | 8 | /*virtual*/ 9 | AbstractSourceCodeReaderRule::~AbstractSourceCodeReaderRule() {} 10 | 11 | /*virtual*/ 12 | void AbstractSourceCodeReaderRule::apply() 13 | { 14 | clang::SourceManager *sourceManager = &_carrier->getSourceManager(); 15 | 16 | clang::FileID mainFileID = sourceManager->getMainFileID(); 17 | llvm::StringRef mainFileStringRef = sourceManager->getBufferData(mainFileID); 18 | 19 | llvm::StringRef remaining = mainFileStringRef; 20 | int currentLineNumber = 1; 21 | while (remaining.size() > 0) 22 | { 23 | std::pair splitPair = remaining.split('\n'); 24 | llvm::StringRef currentLine = splitPair.first; 25 | eachLine(currentLineNumber++, currentLine.str()); 26 | remaining = splitPair.second; 27 | } 28 | } 29 | 30 | void AbstractSourceCodeReaderRule::addViolation(int startLine, int startColumn, 31 | int endLine, int endColumn, RuleBase *rule, const std::string& message) 32 | { 33 | if (!shouldSuppress(startLine, *_carrier->getASTContext(), rule)) 34 | { 35 | clang::SourceManager *sourceManager = &_carrier->getSourceManager(); 36 | 37 | clang::FileID mainFileID = sourceManager->getMainFileID(); 38 | clang::SourceLocation startOfMainFile = sourceManager->getLocForStartOfFile(mainFileID); 39 | llvm::StringRef filePath = sourceManager->getFilename(startOfMainFile); 40 | 41 | _carrier->addViolation(filePath.str(), 42 | startLine, startColumn, endLine, endColumn, rule, message); 43 | } 44 | } 45 | 46 | } // end namespace oclint 47 | 48 | -------------------------------------------------------------------------------- /oclint-rules/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_SUBDIRECTORY(helper) 2 | ADD_SUBDIRECTORY(util) 3 | 4 | SET (AbstractSource 5 | AbstractASTMatcherRule.cpp 6 | AbstractASTRuleBase.cpp 7 | AbstractSourceCodeReaderRule.cpp 8 | ) 9 | 10 | IF (MINGW) 11 | ADD_LIBRARY(OCLintAbstractRule SHARED 12 | ${AbstractSource} 13 | helper/AttributeHelper.cpp 14 | helper/EnforceHelper.cpp 15 | helper/SuppressHelper.cpp 16 | util/ASTUtil.cpp 17 | util/StdUtil.cpp) 18 | TARGET_LINK_LIBRARIES(OCLintAbstractRule 19 | OCLintCore 20 | OCLintRuleSet 21 | ${CLANG_LIBRARIES} 22 | ${REQ_LLVM_LIBRARIES} 23 | ) 24 | SET_TARGET_PROPERTIES(OCLintAbstractRule 25 | PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin 26 | ) 27 | 28 | TARGET_LINK_LIBRARIES(OCLintAbstractRule LINK_INTERFACE_LIBRARIES OCLintRuleSet) 29 | ELSE() 30 | ADD_LIBRARY(OCLintAbstractRule ${AbstractSource}) 31 | ENDIF() 32 | -------------------------------------------------------------------------------- /oclint-rules/lib/helper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF (NOT MINGW) 2 | ADD_LIBRARY(OCLintHelper 3 | AttributeHelper.cpp 4 | EnforceHelper.cpp 5 | SuppressHelper.cpp 6 | ) 7 | ENDIF() 8 | -------------------------------------------------------------------------------- /oclint-rules/lib/helper/EnforceHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/helper/EnforceHelper.h" 2 | 3 | #include "oclint/helper/AttributeHelper.h" 4 | 5 | bool declHasEnforceAttribute( 6 | const clang::Decl *decl, 7 | const oclint::RuleBase& rule, 8 | std::string* comment) { 9 | return declHasActionAttribute(decl, "enforce", rule, comment); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /oclint-rules/lib/util/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF (NOT MINGW) 2 | ADD_LIBRARY(OCLintUtil 3 | ASTUtil.cpp 4 | StdUtil.cpp 5 | ) 6 | ENDIF() 7 | -------------------------------------------------------------------------------- /oclint-rules/lib/util/StdUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/util/StdUtil.h" 2 | 3 | #include 4 | 5 | bool isUnderscore(char aChar) { 6 | return aChar == '_'; 7 | } 8 | 9 | std::string removeUnderscores(std::string str) { 10 | str.erase(remove_if(str.begin(), str.end(), &::isUnderscore), str.end()); 11 | return str; 12 | } 13 | 14 | std::string capitalizeFirstLetter(std::string str) { 15 | if(str.length() > 0) { 16 | std::transform(str.begin(), str.begin() + 1, str.begin(), ::toupper); 17 | } 18 | return str; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /oclint-rules/rules/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | MACRO(build_dynamic_rule name) 2 | IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 3 | SET(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup") 4 | ENDIF() 5 | 6 | ADD_LIBRARY(${name}Rule SHARED ${name}Rule.cpp) 7 | 8 | SET_TARGET_PROPERTIES(${name}Rule 9 | PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/rules.dl 10 | RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/rules.dl 11 | ) 12 | 13 | IF (MINGW) 14 | TARGET_LINK_LIBRARIES(${name}Rule 15 | OCLintAbstractRule 16 | OCLintMetric 17 | ) 18 | ELSE() 19 | TARGET_LINK_LIBRARIES(${name}Rule OCLintAbstractRule) 20 | 21 | TARGET_LINK_LIBRARIES(${name}Rule 22 | clangASTMatchers 23 | ) # TODO: might be redundant 24 | 25 | TARGET_LINK_LIBRARIES(${name}Rule 26 | OCLintMetric 27 | OCLintHelper 28 | OCLintUtil 29 | OCLintCore 30 | ) 31 | 32 | IF (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") 33 | TARGET_LINK_LIBRARIES(${name}Rule 34 | ${CLANG_LIBRARIES} 35 | ${REQ_LLVM_LIBRARIES} 36 | OCLintRuleSet 37 | ) 38 | ENDIF() 39 | ENDIF() 40 | 41 | ENDMACRO(build_dynamic_rule) 42 | 43 | MACRO(build_dynamic_rules rules) 44 | FOREACH(it ${rules}) 45 | BUILD_DYNAMIC_RULE(${it}) 46 | ENDFOREACH(it) 47 | ENDMACRO(build_dynamic_rules) 48 | 49 | MACRO(add_rule_category_directory category) 50 | IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${category}/CMakeLists.txt) 51 | ADD_SUBDIRECTORY(${category}) 52 | ENDIF() 53 | ENDMACRO(add_rule_category_directory) 54 | 55 | ADD_RULE_CATEGORY_DIRECTORY(basic) 56 | ADD_RULE_CATEGORY_DIRECTORY(cocoa) 57 | ADD_RULE_CATEGORY_DIRECTORY(convention) 58 | ADD_RULE_CATEGORY_DIRECTORY(design) 59 | ADD_RULE_CATEGORY_DIRECTORY(empty) 60 | ADD_RULE_CATEGORY_DIRECTORY(migration) 61 | ADD_RULE_CATEGORY_DIRECTORY(naming) 62 | ADD_RULE_CATEGORY_DIRECTORY(redundant) 63 | ADD_RULE_CATEGORY_DIRECTORY(size) 64 | ADD_RULE_CATEGORY_DIRECTORY(unused) 65 | 66 | -------------------------------------------------------------------------------- /oclint-rules/rules/abstract/AbstractEmptyBlockStmtRule.h: -------------------------------------------------------------------------------- 1 | #ifndef OCLINT_ABSTRACTEMPTYBLOCKSTMTRULE_H 2 | #define OCLINT_ABSTRACTEMPTYBLOCKSTMTRULE_H 3 | 4 | template 5 | class AbstractEmptyBlockStmtRule : public oclint::AbstractASTVisitorRule 6 | { 7 | protected: 8 | bool isLexicalEmpty(clang::Stmt *stmt) 9 | { 10 | clang::CompoundStmt *compoundStmt = clang::dyn_cast_or_null(stmt); 11 | return clang::isa(stmt) || (compoundStmt && compoundStmt->body_empty()); 12 | } 13 | 14 | bool checkLexicalEmptyStmt(clang::Stmt *stmt, oclint::RuleBase *rule) 15 | { 16 | if (stmt && isLexicalEmpty(stmt)) 17 | { 18 | oclint::AbstractASTVisitorRule::addViolation(stmt, rule); 19 | } 20 | 21 | return true; 22 | } 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /oclint-rules/rules/basic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | BitwiseOperatorInConditional 3 | BrokenNullCheck 4 | BrokenOddnessCheck 5 | CollapsibleIfStatements 6 | ConstantConditionalOperator 7 | ConstantIfExpression 8 | DeadCode 9 | DoubleNegative 10 | ForLoopShouldBeWhileLoop 11 | GotoStatement 12 | JumbledIncrementer 13 | MisplacedNullCheck 14 | MultipleUnaryOperator 15 | ReturnFromFinallyBlock 16 | ThrowExceptionFromFinallyBlock 17 | ) 18 | 19 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 20 | -------------------------------------------------------------------------------- /oclint-rules/rules/basic/ConstantConditionalOperatorRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace oclint; 7 | 8 | class ConstantConditionalOperatorRule : 9 | public AbstractASTVisitorRule 10 | { 11 | public: 12 | virtual const string name() const override 13 | { 14 | return "constant conditional operator"; 15 | } 16 | 17 | virtual int priority() const override 18 | { 19 | return 2; 20 | } 21 | 22 | virtual const string category() const override 23 | { 24 | return "basic"; 25 | } 26 | 27 | #ifdef DOCGEN 28 | virtual const std::string since() const override 29 | { 30 | return "0.6"; 31 | } 32 | 33 | virtual const std::string description() const override 34 | { 35 | return "``conditional operator`` whose conditionals are always true " 36 | "or always false are confusing."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: cpp 43 | 44 | void example() 45 | { 46 | int a = 1 == 1 ? 1 : 0; // 1 == 1 is actually always true 47 | } 48 | )rst"; 49 | } 50 | #endif 51 | 52 | bool VisitConditionalOperator(ConditionalOperator *conditionalOperator) 53 | { 54 | Expr *conditionExpr = conditionalOperator->getCond(); 55 | 56 | bool evaluatedResult; 57 | if (conditionExpr->EvaluateAsBooleanCondition(evaluatedResult, *_carrier->getASTContext())) 58 | { 59 | addViolation(conditionExpr, this); 60 | } 61 | 62 | return true; 63 | } 64 | }; 65 | 66 | static RuleSet rules(new ConstantConditionalOperatorRule()); 67 | -------------------------------------------------------------------------------- /oclint-rules/rules/basic/ConstantIfExpressionRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace oclint; 7 | 8 | class ConstantIfExpressionRule : public AbstractASTVisitorRule 9 | { 10 | public: 11 | virtual const string name() const override 12 | { 13 | return "constant if expression"; 14 | } 15 | 16 | virtual int priority() const override 17 | { 18 | return 2; 19 | } 20 | 21 | virtual const string category() const override 22 | { 23 | return "basic"; 24 | } 25 | 26 | #ifdef DOCGEN 27 | virtual const std::string since() const override 28 | { 29 | return "0.2"; 30 | } 31 | 32 | virtual const std::string description() const override 33 | { 34 | return "``if`` statements whose conditionals are always true " 35 | "or always false are confusing."; 36 | } 37 | 38 | virtual const std::string example() const override 39 | { 40 | return R"rst( 41 | .. code-block:: cpp 42 | 43 | void example() 44 | { 45 | if (true) // always true 46 | { 47 | foo(); 48 | } 49 | if (1 == 0) // always false 50 | { 51 | bar(); 52 | } 53 | } 54 | )rst"; 55 | } 56 | #endif 57 | 58 | bool VisitIfStmt(IfStmt *ifStmt) 59 | { 60 | Expr *conditionExpr = ifStmt->getCond(); 61 | 62 | bool evaluatedResult; 63 | if (conditionExpr->EvaluateAsBooleanCondition(evaluatedResult, *_carrier->getASTContext())) 64 | { 65 | addViolation(conditionExpr, this); 66 | } 67 | 68 | return true; 69 | } 70 | }; 71 | 72 | static RuleSet rules(new ConstantIfExpressionRule()); 73 | -------------------------------------------------------------------------------- /oclint-rules/rules/basic/ForLoopShouldBeWhileLoopRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace oclint; 7 | 8 | class ForLoopShouldBeWhileLoopRule : public AbstractASTVisitorRule 9 | { 10 | public: 11 | virtual const string name() const override 12 | { 13 | return "for loop should be while loop"; 14 | } 15 | 16 | virtual int priority() const override 17 | { 18 | return 3; 19 | } 20 | 21 | virtual const string category() const override 22 | { 23 | return "basic"; 24 | } 25 | 26 | #ifdef DOCGEN 27 | virtual const std::string since() const override 28 | { 29 | return "0.6"; 30 | } 31 | 32 | virtual const std::string description() const override 33 | { 34 | return "Under certain circumstances, some ``for`` loops can be simplified to while " 35 | "loops to make code more concise."; 36 | } 37 | 38 | virtual const std::string example() const override 39 | { 40 | return R"rst( 41 | .. code-block:: cpp 42 | 43 | void example(int a) 44 | { 45 | for (; a < 100;) 46 | { 47 | foo(a); 48 | } 49 | } 50 | )rst"; 51 | } 52 | #endif 53 | 54 | bool VisitForStmt(ForStmt *forStmt) 55 | { 56 | Stmt *initStmt = forStmt->getInit(); 57 | Expr *condExpr = forStmt->getCond(); 58 | Expr *incExpr = forStmt->getInc(); 59 | if (!initStmt && !incExpr && condExpr && !isa(condExpr)) 60 | { 61 | addViolation(forStmt, this); 62 | } 63 | 64 | return true; 65 | } 66 | }; 67 | 68 | static RuleSet rules(new ForLoopShouldBeWhileLoopRule()); 69 | -------------------------------------------------------------------------------- /oclint-rules/rules/basic/GotoStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTMatcherRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace clang::ast_matchers; 7 | using namespace oclint; 8 | 9 | /* 10 | * References: 11 | * - Edsger Dijkstra (March 1968). “Go To Statement Considered Harmful”. 12 | * Communications of the ACM (PDF) 11 (3): 147–148. doi:10.1145/362929.362947. 13 | */ 14 | 15 | class GotoStatementRule : public AbstractASTMatcherRule 16 | { 17 | public: 18 | virtual const string name() const override 19 | { 20 | return "goto statement"; 21 | } 22 | 23 | virtual int priority() const override 24 | { 25 | return 3; 26 | } 27 | 28 | virtual const string category() const override 29 | { 30 | return "basic"; 31 | } 32 | 33 | #ifdef DOCGEN 34 | virtual const std::string since() const override 35 | { 36 | return "0.6"; 37 | } 38 | 39 | virtual const std::string description() const override 40 | { 41 | return "`\"Go To Statement Considered Harmful\" " 42 | "`_"; 43 | } 44 | 45 | virtual const std::string example() const override 46 | { 47 | return R"rst( 48 | .. code-block:: cpp 49 | 50 | void example() 51 | { 52 | A: 53 | a(); 54 | goto A; // Considered Harmful 55 | } 56 | )rst"; 57 | } 58 | 59 | virtual const std::string additionalDocument() const override 60 | { 61 | return R"rst( 62 | **References:** 63 | 64 | Edsger Dijkstra (March 1968). `"Go To Statement Considered Harmful" 65 | `_. 66 | *Communications of the ACM* (PDF) 11 (3): 147–148. doi:10.1145/362929.362947. 67 | )rst"; 68 | } 69 | #endif 70 | 71 | virtual void callback(const MatchFinder::MatchResult& result) override 72 | { 73 | addViolation(result.Nodes.getNodeAs("gotoStmt"), this); 74 | } 75 | 76 | virtual void setUpMatcher() override 77 | { 78 | addMatcher(gotoStmt().bind("gotoStmt")); 79 | } 80 | }; 81 | 82 | static RuleSet rules(new GotoStatementRule()); 83 | -------------------------------------------------------------------------------- /oclint-rules/rules/basic/MultipleUnaryOperatorRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace oclint; 7 | 8 | class MultipleUnaryOperatorRule : public AbstractASTVisitorRule 9 | { 10 | private: 11 | bool isTargetUnaryOperator(UnaryOperator *unaryOperator) 12 | { 13 | return unaryOperator->getOpcode() == UO_LNot || 14 | unaryOperator->getOpcode() == UO_Not || 15 | unaryOperator->getOpcode() == UO_Plus || 16 | unaryOperator->getOpcode() == UO_Minus; 17 | } 18 | 19 | public: 20 | virtual const string name() const override 21 | { 22 | return "multiple unary operator"; 23 | } 24 | 25 | virtual int priority() const override 26 | { 27 | return 2; 28 | } 29 | 30 | virtual const string category() const override 31 | { 32 | return "basic"; 33 | } 34 | 35 | #ifdef DOCGEN 36 | virtual const std::string since() const override 37 | { 38 | return "0.6"; 39 | } 40 | 41 | virtual const std::string description() const override 42 | { 43 | return "Multiple unary operator can always be confusing and should be simplified."; 44 | } 45 | 46 | virtual const std::string example() const override 47 | { 48 | return R"rst( 49 | .. code-block:: cpp 50 | 51 | void example() 52 | { 53 | int b = -(+(!(~1))); 54 | } 55 | )rst"; 56 | } 57 | #endif 58 | 59 | bool VisitUnaryOperator(UnaryOperator *unaryOperator) 60 | { 61 | Expr *subExpr = unaryOperator->getSubExpr(); 62 | while (subExpr && isa(subExpr)) 63 | { 64 | ParenExpr *parenExpr = dyn_cast(subExpr); 65 | subExpr = parenExpr->getSubExpr(); 66 | } 67 | if (subExpr && isa(subExpr)) 68 | { 69 | UnaryOperator *subUnaryOperator = dyn_cast(subExpr); 70 | if (isTargetUnaryOperator(unaryOperator) && isTargetUnaryOperator(subUnaryOperator)) 71 | { 72 | addViolation(unaryOperator, this); 73 | } 74 | } 75 | 76 | return true; 77 | } 78 | }; 79 | 80 | static RuleSet rules(new MultipleUnaryOperatorRule()); 81 | -------------------------------------------------------------------------------- /oclint-rules/rules/cocoa/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | ObjCVerifyIsEqualHash 3 | ObjCVerifyMustCallSuper 4 | ObjCVerifySubclassMustImplement 5 | ObjCVerifyProhibitedCall 6 | ObjCVerifyProtectedMethod 7 | ) 8 | 9 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 10 | -------------------------------------------------------------------------------- /oclint-rules/rules/convention/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | AvoidBranchingStatementAsLastInLoop 3 | BaseClassDestructorShouldBeVirtualOrProtected 4 | DefaultLabelNotLastInSwitchStatement 5 | DestructorOfVirtualClass 6 | InvertedLogic 7 | MissingBreakInSwitchStatement 8 | NonCaseLabelInSwitchStatement 9 | ObjCAssignIvarOutsideAccessors 10 | ParameterReassignment 11 | PreferEarlyExit 12 | SwitchStatementsShouldHaveDefault 13 | CoveredSwitchStatementsDontNeedDefault 14 | TooFewBranchesInSwitchStatement 15 | ) 16 | 17 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 18 | -------------------------------------------------------------------------------- /oclint-rules/rules/design/AvoidPrivateStaticMembersRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTMatcherRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace clang::ast_matchers; 7 | using namespace oclint; 8 | 9 | namespace clang { 10 | namespace ast_matchers { 11 | AST_MATCHER(VarDecl, isStaticDataMember) 12 | { 13 | return Node.isStaticDataMember(); 14 | } 15 | 16 | AST_MATCHER(CXXMethodDecl, isStatic) 17 | { 18 | return Node.isStatic(); 19 | } 20 | } // namespace ast_matchers 21 | } // namespace clang 22 | 23 | class AvoidPrivateStaticMembersRule : public AbstractASTMatcherRule 24 | { 25 | public: 26 | virtual const string name() const override 27 | { 28 | return "avoid private static members"; 29 | } 30 | 31 | virtual int priority() const override 32 | { 33 | return 3; 34 | } 35 | 36 | virtual const string category() const override 37 | { 38 | return "design"; 39 | } 40 | 41 | #ifdef DOCGEN 42 | virtual const std::string since() const override 43 | { 44 | return "0.10.1"; 45 | } 46 | 47 | virtual const std::string description() const override 48 | { 49 | return "Having static members is easier to harm encapsulation."; 50 | } 51 | 52 | virtual const std::string example() const override 53 | { 54 | return R"rst( 55 | .. code-block:: cpp 56 | 57 | class Foo 58 | { 59 | static int a; // static field 60 | }; 61 | class Bar 62 | { 63 | static int b(); // static method 64 | } 65 | )rst"; 66 | } 67 | #endif 68 | 69 | virtual void callback(const MatchFinder::MatchResult &result) override 70 | { 71 | if (auto field = result.Nodes.getNodeAs("field")) 72 | { 73 | addViolation(field, this); 74 | } 75 | if (auto method = result.Nodes.getNodeAs("cxxMethod")) 76 | { 77 | addViolation(method, this); 78 | } 79 | } 80 | 81 | virtual void setUpMatcher() override 82 | { 83 | addMatcher(varDecl(isPrivate(), isStaticDataMember()).bind("field")); 84 | addMatcher(cxxMethodDecl(isPrivate(), isStatic()).bind("cxxMethod")); 85 | } 86 | }; 87 | 88 | static RuleSet rules(new AvoidPrivateStaticMembersRule()); 89 | -------------------------------------------------------------------------------- /oclint-rules/rules/design/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | AvoidDefaultArgumentsOnVirtualMethods 3 | AvoidPrivateStaticMembers 4 | #FeatureEnvy 5 | ) 6 | 7 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 8 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | EmptyCatchStatement 3 | EmptyDoWhileStatement 4 | EmptyElseBlock 5 | EmptyFinallyStatement 6 | EmptyForStatement 7 | EmptyIfStatement 8 | EmptySwitchStatement 9 | EmptyTryStatement 10 | EmptyWhileStatement 11 | ) 12 | 13 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 14 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyCatchStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyCatchStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty catch statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where an exception is caught, " 37 | "but nothing is done about it."; 38 | } 39 | 40 | virtual const std::string example() const override 41 | { 42 | return R"rst( 43 | .. code-block:: cpp 44 | 45 | void example() 46 | { 47 | try 48 | { 49 | int* m= new int[1000]; 50 | } 51 | catch(...) // empty catch statement, this swallows an exception 52 | { 53 | } 54 | } 55 | )rst"; 56 | } 57 | #endif 58 | 59 | bool VisitCXXCatchStmt(CXXCatchStmt *catchStmt) 60 | { 61 | return checkLexicalEmptyStmt(catchStmt->getHandlerBlock(), this); 62 | } 63 | 64 | bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *catchStmt) 65 | { 66 | return checkLexicalEmptyStmt(catchStmt->getCatchBody(), this); 67 | } 68 | }; 69 | 70 | static RuleSet rules(new EmptyCatchStatementRule()); 71 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyDoWhileStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyDoWhileStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty do/while statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where do-while statement does nothing."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: cpp 43 | 44 | void example() 45 | { 46 | do 47 | { // empty do-while statement 48 | } while(1); 49 | } 50 | )rst"; 51 | } 52 | #endif 53 | 54 | bool VisitDoStmt(DoStmt *doStmt) 55 | { 56 | return checkLexicalEmptyStmt(doStmt->getBody(), this); 57 | } 58 | }; 59 | 60 | static RuleSet rules(new EmptyDoWhileStatementRule()); 61 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyElseBlockRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyElseBlockRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty else block"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where a else statement does nothing."; 37 | } 38 | 39 | virtual const std::string fileName() const override 40 | { 41 | return "EmptyElseBlockRule.cpp"; 42 | } 43 | 44 | virtual const std::string example() const override 45 | { 46 | return R"rst( 47 | .. code-block:: cpp 48 | 49 | int example(int a) 50 | { 51 | if (1) 52 | { 53 | return a + 1; 54 | } 55 | else // empty else statement, can be safely removed 56 | { 57 | } 58 | } 59 | )rst"; 60 | } 61 | #endif 62 | 63 | bool VisitIfStmt(IfStmt *ifStmt) 64 | { 65 | return checkLexicalEmptyStmt(ifStmt->getElse(), this); 66 | } 67 | }; 68 | 69 | static RuleSet rules(new EmptyElseBlockRule()); 70 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyFinallyStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyFinallyStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty finally statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where a finally statement does nothing."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: objective-c 43 | 44 | void example() 45 | { 46 | Foo *foo; 47 | @try 48 | { 49 | [foo bar]; 50 | } 51 | @catch(NSException *e) 52 | { 53 | NSLog(@"Exception occurred: %@", [e description]); 54 | } 55 | @finally // empty finally statement, probably forget to clean up? 56 | { 57 | } 58 | } 59 | )rst"; 60 | } 61 | #endif 62 | 63 | bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *finallyStmt) 64 | { 65 | return checkLexicalEmptyStmt(finallyStmt->getFinallyBody(), this); 66 | } 67 | }; 68 | 69 | static RuleSet rules(new EmptyFinallyStatementRule()); 70 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyForStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyForStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty for statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where a for statement does nothing."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: objective-c 43 | 44 | void example(NSArray *array) 45 | { 46 | for (;;) // empty for statement 47 | { 48 | } 49 | 50 | for (id it in array) // empty for-each statement 51 | { 52 | } 53 | } 54 | )rst"; 55 | } 56 | #endif 57 | 58 | bool VisitForStmt(ForStmt *forStmt) 59 | { 60 | return checkLexicalEmptyStmt(forStmt->getBody(), this); 61 | } 62 | 63 | bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *forStmt) 64 | { 65 | return checkLexicalEmptyStmt(forStmt->getBody(), this); 66 | } 67 | }; 68 | 69 | static RuleSet rules(new EmptyForStatementRule()); 70 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyIfStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyIfStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty if statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.2"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where a condition is checked, " 37 | "but nothing is done about it."; 38 | } 39 | 40 | virtual const std::string example() const override 41 | { 42 | return R"rst( 43 | .. code-block:: cpp 44 | 45 | void example(int a) 46 | { 47 | if (a == 1) // empty if statement 48 | { 49 | } 50 | } 51 | )rst"; 52 | } 53 | #endif 54 | 55 | bool VisitIfStmt(IfStmt *ifStmt) 56 | { 57 | return checkLexicalEmptyStmt(ifStmt->getThen(), this); 58 | } 59 | }; 60 | 61 | static RuleSet rules(new EmptyIfStatementRule()); 62 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptySwitchStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptySwitchStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty switch statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where a switch statement does nothing."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: cpp 43 | 44 | void example(int i) 45 | { 46 | switch (i) // empty switch statement 47 | { 48 | } 49 | } 50 | )rst"; 51 | } 52 | #endif 53 | 54 | bool VisitSwitchStmt(SwitchStmt *switchStmt) 55 | { 56 | return checkLexicalEmptyStmt(switchStmt->getBody(), this); 57 | } 58 | }; 59 | 60 | static RuleSet rules(new EmptySwitchStatementRule()); 61 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyTryStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyTryStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty try statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where a try statement is empty."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: cpp 43 | 44 | void example() 45 | { 46 | try // but this try statement is empty 47 | { 48 | } 49 | catch(...) 50 | { 51 | cout << "Exception is caught!"; 52 | } 53 | } 54 | )rst"; 55 | } 56 | #endif 57 | 58 | bool VisitCXXTryStmt(CXXTryStmt *tryStmt) 59 | { 60 | return checkLexicalEmptyStmt(tryStmt->getTryBlock(), this); 61 | } 62 | 63 | bool VisitObjCAtTryStmt(ObjCAtTryStmt *tryStmt) 64 | { 65 | return checkLexicalEmptyStmt(tryStmt->getTryBody(), this); 66 | } 67 | }; 68 | 69 | static RuleSet rules(new EmptyTryStatementRule()); 70 | -------------------------------------------------------------------------------- /oclint-rules/rules/empty/EmptyWhileStatementRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | #include "../abstract/AbstractEmptyBlockStmtRule.h" 5 | 6 | using namespace std; 7 | using namespace clang; 8 | using namespace oclint; 9 | 10 | class EmptyWhileStatementRule : public AbstractEmptyBlockStmtRule 11 | { 12 | public: 13 | virtual const string name() const override 14 | { 15 | return "empty while statement"; 16 | } 17 | 18 | virtual int priority() const override 19 | { 20 | return 2; 21 | } 22 | 23 | virtual const string category() const override 24 | { 25 | return "empty"; 26 | } 27 | 28 | #ifdef DOCGEN 29 | virtual const std::string since() const override 30 | { 31 | return "0.6"; 32 | } 33 | 34 | virtual const std::string description() const override 35 | { 36 | return "This rule detects instances where a while statement does nothing."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: cpp 43 | 44 | void example(int a) 45 | { 46 | while(a--) // empty while statement 47 | { 48 | } 49 | } 50 | )rst"; 51 | } 52 | #endif 53 | 54 | bool VisitWhileStmt(WhileStmt *whileStmt) 55 | { 56 | return checkLexicalEmptyStmt(whileStmt->getBody(), this); 57 | } 58 | }; 59 | 60 | static RuleSet rules(new EmptyWhileStatementRule()); 61 | -------------------------------------------------------------------------------- /oclint-rules/rules/migration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | ObjCBoxedExpressions 3 | ObjCContainerLiterals 4 | ObjCNSNumberLiterals 5 | ObjCObjectSubscripting 6 | ) 7 | 8 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 9 | -------------------------------------------------------------------------------- /oclint-rules/rules/naming/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | LongVariableName 3 | ShortVariableName 4 | ) 5 | 6 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 7 | -------------------------------------------------------------------------------- /oclint-rules/rules/redundant/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | RedundantConditionalOperator 3 | RedundantIfStatement 4 | RedundantLocalVariable 5 | RedundantNilCheck 6 | UnnecessaryElseStatement 7 | UnnecessaryNullCheckForCXXDealloc 8 | UselessParentheses 9 | ) 10 | 11 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 12 | -------------------------------------------------------------------------------- /oclint-rules/rules/redundant/UselessParenthesesRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace oclint; 7 | 8 | class UselessParenthesesRule : public AbstractASTVisitorRule 9 | { 10 | private: 11 | void addParenExprToViolation(Expr *expr) 12 | { 13 | if (expr && isa(expr)) 14 | { 15 | addViolation(expr, this); 16 | } 17 | } 18 | 19 | public: 20 | virtual const string name() const override 21 | { 22 | return "useless parentheses"; 23 | } 24 | 25 | virtual int priority() const override 26 | { 27 | return 3; 28 | } 29 | 30 | virtual const string category() const override 31 | { 32 | return "redundant"; 33 | } 34 | 35 | #ifdef DOCGEN 36 | virtual const std::string since() const override 37 | { 38 | return "0.6"; 39 | } 40 | 41 | virtual const std::string description() const override 42 | { 43 | return "This rule detects useless parentheses."; 44 | } 45 | 46 | virtual const std::string example() const override 47 | { 48 | return R"rst( 49 | .. code-block:: cpp 50 | 51 | int example(int a) 52 | { 53 | int y = (a + 1); // int y = a + 1; 54 | if ((y > 0)) // if (y > 0) 55 | { 56 | return a; 57 | } 58 | return (0); // return 0; 59 | } 60 | )rst"; 61 | } 62 | #endif 63 | 64 | bool VisitIfStmt(IfStmt *ifStmt) 65 | { 66 | addParenExprToViolation(ifStmt->getCond()); 67 | 68 | return true; 69 | } 70 | 71 | bool VisitReturnStmt(ReturnStmt *returnStmt) 72 | { 73 | addParenExprToViolation(returnStmt->getRetValue()); 74 | 75 | return true; 76 | } 77 | 78 | bool VisitVarDecl(VarDecl *varDecl) 79 | { 80 | addParenExprToViolation(varDecl->getInit()); 81 | 82 | return true; 83 | } 84 | }; 85 | 86 | static RuleSet rules(new UselessParenthesesRule()); 87 | -------------------------------------------------------------------------------- /oclint-rules/rules/size/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | CyclomaticComplexity 3 | LongClass 4 | LongLine 5 | LongMethod 6 | NcssMethodCount 7 | NestedBlockDepth 8 | NPathComplexity 9 | TooManyFields 10 | TooManyMethods 11 | TooManyParameters 12 | ) 13 | 14 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 15 | -------------------------------------------------------------------------------- /oclint-rules/rules/size/LongLineRule.cpp: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractSourceCodeReaderRule.h" 2 | #include "oclint/RuleConfiguration.h" 3 | #include "oclint/RuleSet.h" 4 | #include "oclint/util/StdUtil.h" 5 | 6 | using namespace std; 7 | using namespace oclint; 8 | 9 | class LongLineRule : public AbstractSourceCodeReaderRule 10 | { 11 | public: 12 | virtual const string name() const override 13 | { 14 | return "long line"; 15 | } 16 | 17 | virtual int priority() const override 18 | { 19 | return 3; 20 | } 21 | 22 | virtual const string category() const override 23 | { 24 | return "size"; 25 | } 26 | 27 | #ifdef DOCGEN 28 | virtual const std::string since() const override 29 | { 30 | return "0.6"; 31 | } 32 | 33 | virtual const std::string description() const override 34 | { 35 | return "When the number of characters for one line of code is very high, " 36 | "it largely harms the readability. Break long lines of code into multiple lines."; 37 | } 38 | 39 | virtual const std::string example() const override 40 | { 41 | return R"rst( 42 | .. code-block:: cpp 43 | 44 | void example() 45 | { 46 | int a012345678901234567890123456789...1234567890123456789012345678901234567890123456789; 47 | } 48 | )rst"; 49 | } 50 | 51 | virtual const std::map thresholds() const override 52 | { 53 | std::map thresholdMapping; 54 | thresholdMapping["LONG_LINE"] = "The long line reporting threshold, default value is 100."; 55 | return thresholdMapping; 56 | } 57 | #endif 58 | 59 | virtual void eachLine(int lineNumber, string line) override 60 | { 61 | int threshold = RuleConfiguration::intForKey("LONG_LINE", 100); 62 | int currentLineSize = line.size(); 63 | if (currentLineSize > threshold) 64 | { 65 | string description = "Line with " + toString(currentLineSize) + 66 | " characters exceeds limit of " + toString(threshold); 67 | addViolation(lineNumber, 1, lineNumber, currentLineSize, this, description); 68 | } 69 | } 70 | }; 71 | 72 | static RuleSet rules(new LongLineRule()); 73 | -------------------------------------------------------------------------------- /oclint-rules/rules/unused/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LIST_OF_RULES 2 | UnusedLocalVariable 3 | UnusedMethodParameter 4 | ) 5 | 6 | BUILD_DYNAMIC_RULES("${LIST_OF_RULES}") 7 | -------------------------------------------------------------------------------- /oclint-rules/template/ASTVisitorRule.tmpl: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractASTVisitorRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace clang; 6 | using namespace oclint; 7 | 8 | class {{RULE_CLASS_NAME}}Rule : public AbstractASTVisitorRule<{{RULE_CLASS_NAME}}Rule> 9 | { 10 | public: 11 | virtual const string name() const override 12 | { 13 | return "{{RULE_NAME}}"; 14 | } 15 | 16 | virtual int priority() const override 17 | { 18 | return {{RULE_PRIORITY}}; 19 | } 20 | 21 | virtual const string category() const override 22 | { 23 | return "{{RULE_CATEGORY}}"; 24 | } 25 | 26 | #ifdef DOCGEN 27 | virtual const std::string since() const override 28 | { 29 | return "{{OCLINT_VERSION}}"; 30 | } 31 | 32 | virtual const std::string description() const override 33 | { 34 | return ""; // TODO: fill in the description of the rule. 35 | } 36 | 37 | virtual const std::string example() const override 38 | { 39 | return R"rst( 40 | .. code-block:: cpp 41 | 42 | void example() 43 | { 44 | // TODO: modify the example for this rule. 45 | } 46 | )rst"; 47 | } 48 | 49 | /* fill in the file name only when it does not match the rule identifier 50 | virtual const std::string fileName() const override 51 | { 52 | return ""; 53 | } 54 | */ 55 | 56 | /* add each threshold's key, description, and its default value to the map. 57 | virtual const std::map thresholds() const override 58 | { 59 | std::map thresholdMapping; 60 | return thresholdMapping; 61 | } 62 | */ 63 | 64 | /* add additional document for the rule, like references, notes, etc. 65 | virtual const std::string additionalDocument() const override 66 | { 67 | return ""; 68 | } 69 | */ 70 | 71 | /* uncomment this method when the rule is enabled to be suppressed. 72 | virtual bool enableSuppress() const override 73 | { 74 | return true; 75 | } 76 | */ 77 | #endif 78 | 79 | virtual void setUp() override {} 80 | virtual void tearDown() override {} 81 | 82 | {{VISIT_AST_NODE_BLOCK}} 83 | }; 84 | 85 | static RuleSet rules(new {{RULE_CLASS_NAME}}Rule()); 86 | -------------------------------------------------------------------------------- /oclint-rules/template/GenericRule.tmpl: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "oclint/RuleBase.h" 4 | #include "oclint/RuleSet.h" 5 | 6 | using namespace std; 7 | using namespace oclint; 8 | 9 | class {{RULE_CLASS_NAME}}Rule : public RuleBase 10 | { 11 | public: 12 | virtual const string name() const override 13 | { 14 | return "{{RULE_NAME}}"; 15 | } 16 | 17 | virtual int priority() const override 18 | { 19 | return {{RULE_PRIORITY}}; 20 | } 21 | 22 | virtual const string category() const override 23 | { 24 | return "{{RULE_CATEGORY}}"; 25 | } 26 | 27 | #ifdef DOCGEN 28 | virtual const std::string since() const override 29 | { 30 | return "{{OCLINT_VERSION}}"; 31 | } 32 | 33 | virtual const std::string description() const override 34 | { 35 | return ""; // TODO: fill in the description of the rule. 36 | } 37 | 38 | virtual const std::string example() const override 39 | { 40 | return R"rst( 41 | .. code-block:: cpp 42 | 43 | void example() 44 | { 45 | // TODO: modify the example for this rule. 46 | } 47 | )rst"; 48 | } 49 | 50 | /* fill in the file name only when it does not match the rule identifier 51 | virtual const std::string fileName() const override 52 | { 53 | return ""; 54 | } 55 | */ 56 | 57 | /* add each threshold's key, description, and its default value to the map. 58 | virtual const std::map thresholds() const override 59 | { 60 | std::map thresholdMapping; 61 | return thresholdMapping; 62 | } 63 | */ 64 | 65 | /* add additional document for the rule, like references, notes, etc. 66 | virtual const std::string additionalDocument() const override 67 | { 68 | return ""; 69 | } 70 | */ 71 | 72 | /* uncomment this method when the rule is enabled to be suppressed. 73 | virtual bool enableSuppress() const override 74 | { 75 | return true; 76 | } 77 | */ 78 | #endif 79 | 80 | virtual void apply() override 81 | { 82 | } 83 | 84 | }; 85 | 86 | static RuleSet rules(new {{RULE_CLASS_NAME}}Rule()); 87 | -------------------------------------------------------------------------------- /oclint-rules/template/RuleTest.tmpl: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | #include "rules/{{RULE_CATEGORY}}/{{RULE_CLASS_NAME}}Rule.cpp" 3 | 4 | TEST({{RULE_CLASS_NAME}}RuleTest, PropertyTest) 5 | { 6 | {{RULE_CLASS_NAME}}Rule rule; 7 | EXPECT_EQ({{RULE_PRIORITY}}, rule.priority()); 8 | EXPECT_EQ("{{RULE_NAME}}", rule.name()); 9 | EXPECT_EQ("{{RULE_CATEGORY}}", rule.category()); 10 | } 11 | 12 | TEST({{RULE_CLASS_NAME}}RuleTest, FirstFailingTest) 13 | { 14 | EXPECT_FALSE("Start writing a new test"); 15 | } 16 | -------------------------------------------------------------------------------- /oclint-rules/template/SourceCodeReaderRule.tmpl: -------------------------------------------------------------------------------- 1 | #include "oclint/AbstractSourceCodeReaderRule.h" 2 | #include "oclint/RuleSet.h" 3 | 4 | using namespace std; 5 | using namespace oclint; 6 | 7 | class {{RULE_CLASS_NAME}}Rule : public AbstractSourceCodeReaderRule 8 | { 9 | public: 10 | virtual const string name() const override 11 | { 12 | return "{{RULE_NAME}}"; 13 | } 14 | 15 | virtual int priority() const override 16 | { 17 | return {{RULE_PRIORITY}}; 18 | } 19 | 20 | virtual const string category() const override 21 | { 22 | return "{{RULE_CATEGORY}}"; 23 | } 24 | 25 | #ifdef DOCGEN 26 | virtual const std::string since() const override 27 | { 28 | return "{{OCLINT_VERSION}}"; 29 | } 30 | 31 | virtual const std::string description() const override 32 | { 33 | return ""; // TODO: fill in the description of the rule. 34 | } 35 | 36 | virtual const std::string example() const override 37 | { 38 | return R"rst( 39 | .. code-block:: cpp 40 | 41 | void example() 42 | { 43 | // TODO: modify the example for this rule. 44 | } 45 | )rst"; 46 | } 47 | 48 | /* fill in the file name only when it does not match the rule identifier 49 | virtual const std::string fileName() const override 50 | { 51 | return ""; 52 | } 53 | */ 54 | 55 | /* add each threshold's key, description, and its default value to the map. 56 | virtual const std::map thresholds() const override 57 | { 58 | std::map thresholdMapping; 59 | return thresholdMapping; 60 | } 61 | */ 62 | 63 | /* add additional document for the rule, like references, notes, etc. 64 | virtual const std::string additionalDocument() const override 65 | { 66 | return ""; 67 | } 68 | */ 69 | 70 | /* uncomment this method when the rule is enabled to be suppressed. 71 | virtual bool enableSuppress() const override 72 | { 73 | return true; 74 | } 75 | */ 76 | #endif 77 | 78 | virtual void eachLine(int lineNumber, string line) override 79 | { 80 | } 81 | }; 82 | 83 | static RuleSet rules(new {{RULE_CLASS_NAME}}Rule()); 84 | -------------------------------------------------------------------------------- /oclint-rules/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_LIBRARY(test_helper headers/TestRuleOnCode.cpp) 2 | IF (MINGW) 3 | SET(TEST_LIBS 4 | test_helper 5 | ${GTEST_LIBS} 6 | gtest_main 7 | gmock_main 8 | ${PROFILE_RT_LIBS} 9 | ${CLANG_LIBRARIES} 10 | ${REQ_LLVM_LIBRARIES} 11 | OCLintMetric 12 | OCLintAbstractRule 13 | OCLintCore 14 | OCLintRuleSet 15 | ) 16 | ELSE() 17 | SET(TEST_LIBS 18 | test_helper 19 | OCLintAbstractRule 20 | OCLintMetric 21 | OCLintHelper 22 | OCLintUtil 23 | OCLintCore 24 | OCLintRuleSet 25 | ${GTEST_LIBS} 26 | gtest_main 27 | gmock_main 28 | ${PROFILE_RT_LIBS} 29 | ${CLANG_LIBRARIES} 30 | ${REQ_LLVM_LIBRARIES} 31 | ) 32 | ENDIF() 33 | MACRO(build_test name) 34 | ADD_EXECUTABLE(${name} ${ARGN}) 35 | TARGET_LINK_LIBRARIES(${name} ${TEST_LIBS}) 36 | ADD_TEST(${name} ${EXECUTABLE_OUTPUT_PATH}/${name}) 37 | ENDMACRO(build_test) 38 | 39 | BUILD_TEST(CanaryTest CanaryTest.cpp) 40 | IF (MINGW) 41 | # Do it once, instead of copying for each test 42 | file(TO_CMAKE_PATH "${OCLINT_BUILD_DIR}" OCLINT_BUILD_CMAKE_PATH) 43 | file(TO_CMAKE_PATH "${OCLINT_METRICS_BUILD_DIR}" OCLINT_METRICS_CMAKE_PATH) 44 | add_custom_command(TARGET CanaryTest PRE_BUILD 45 | COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OCLINT_BUILD_CMAKE_PATH}/bin/libOCLintRuleSet.dll" $) 46 | add_custom_command(TARGET CanaryTest PRE_BUILD 47 | COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OCLINT_METRICS_CMAKE_PATH}/bin/libOCLintMetric.dll" $) 48 | ENDIF() 49 | 50 | ADD_SUBDIRECTORY(abstract) 51 | ADD_SUBDIRECTORY(helper) 52 | 53 | ADD_SUBDIRECTORY(basic) 54 | ADD_SUBDIRECTORY(cocoa) 55 | ADD_SUBDIRECTORY(convention) 56 | ADD_SUBDIRECTORY(design) 57 | ADD_SUBDIRECTORY(empty) 58 | ADD_SUBDIRECTORY(migration) 59 | ADD_SUBDIRECTORY(naming) 60 | ADD_SUBDIRECTORY(redundant) 61 | ADD_SUBDIRECTORY(size) 62 | ADD_SUBDIRECTORY(unused) 63 | -------------------------------------------------------------------------------- /oclint-rules/test/CanaryTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | TEST(CanaryTest, AlwaysTrue) 5 | { 6 | EXPECT_TRUE(true); 7 | } 8 | 9 | int main(int argc, char **argv) 10 | { 11 | ::testing::InitGoogleMock(&argc, argv); 12 | return RUN_ALL_TESTS(); 13 | } 14 | -------------------------------------------------------------------------------- /oclint-rules/test/abstract/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(AbstractTests 2 | LanguageSelectionTest.cpp 3 | MacroLocationTest.cpp 4 | TagBasedViolationTest.cpp 5 | ) 6 | -------------------------------------------------------------------------------- /oclint-rules/test/abstract/MacroLocationTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "oclint/AbstractASTVisitorRule.h" 4 | 5 | using namespace std; 6 | using namespace clang; 7 | using namespace oclint; 8 | 9 | class DefaultASTRule2 : public AbstractASTVisitorRule 10 | { 11 | public: 12 | virtual const string name() const override 13 | { 14 | return "default ast rule"; 15 | } 16 | 17 | virtual int priority() const override 18 | { 19 | return 0; 20 | } 21 | 22 | virtual const string category() const override 23 | { 24 | return "test"; 25 | } 26 | 27 | bool VisitBinaryOperator(BinaryOperator *binaryOperator) 28 | { 29 | addViolation(binaryOperator, this); 30 | return true; 31 | } 32 | }; 33 | 34 | TEST(DefaultASTRuleTest, WithoutMacro) 35 | { 36 | testRuleOnCode(new DefaultASTRule2(), "int a = 1+1;", 0, 1, 9, 1, 11); 37 | } 38 | 39 | TEST(DefaultASTRuleTest, WithMacro) 40 | { 41 | testRuleOnCode(new DefaultASTRule2(), "#define ADD(a,b) ((a)+(b))\nint a = ADD(1,1);", 0, 2, 9, 2, 9); 42 | } 43 | -------------------------------------------------------------------------------- /oclint-rules/test/abstract/TagBasedViolationTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "oclint/AbstractASTVisitorRule.h" 4 | 5 | using namespace std; 6 | using namespace oclint; 7 | 8 | class FindAllCompoundStmtRule : public AbstractASTVisitorRule 9 | { 10 | private: 11 | int _counter; 12 | 13 | public: 14 | virtual void setUp() override 15 | { 16 | _counter = 0; 17 | } 18 | 19 | virtual const string name() const override 20 | { 21 | return "find all compound stmt rule"; 22 | } 23 | 24 | virtual int priority() const override 25 | { 26 | return 0; 27 | } 28 | 29 | virtual const string category() const override 30 | { 31 | return "test"; 32 | } 33 | 34 | bool VisitCompoundStmt(clang::CompoundStmt *stmt) 35 | { 36 | addViolation(stmt, this, std::to_string(++_counter)); 37 | return true; 38 | } 39 | }; 40 | 41 | TEST(FindAllCompoundStmtRuleTest, PropertyTest) 42 | { 43 | FindAllCompoundStmtRule rule; 44 | EXPECT_EQ(0, rule.priority()); 45 | EXPECT_EQ("find all compound stmt rule", rule.name()); 46 | } 47 | 48 | TEST(FindAllCompoundStmtRuleTest, NumberBasedViolation) 49 | { 50 | testRuleOnCode(new FindAllCompoundStmtRule(), "void a() {}", 0, 1, 10, 1, 11, "1"); 51 | } 52 | 53 | TEST(FindAllCompoundStmtRuleTest, OneSingleTagBasedViolation) 54 | { 55 | testRuleOnCode(new FindAllCompoundStmtRule(), "void a() " VIOLATION_START "{" VIOLATION_END "}", {"1"}); 56 | } 57 | 58 | TEST(FindAllCompoundStmtRuleTest, NestedViolations) 59 | { 60 | testRuleOnCode(new FindAllCompoundStmtRule(), 61 | "void a() " VIOLATION_START "{" VIOLATION_START "{" VIOLATION_END "}" VIOLATION_END "}", 62 | {"1", "2"}); 63 | } 64 | 65 | TEST(FindAllCompoundStmtRuleTest, ParallelViolations) 66 | { 67 | testRuleOnCode(new FindAllCompoundStmtRule(), 68 | "void a() " VIOLATION_START "{" VIOLATION_START "{" VIOLATION_END "}" VIOLATION_START "{" VIOLATION_END "}" VIOLATION_END "}", 69 | {"1", "2", "3"}); 70 | } 71 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/BrokenOddnessCheckRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/BrokenOddnessCheckRule.cpp" 4 | 5 | TEST(BrokenOddnessCheckRuleTest, PropertyTest) 6 | { 7 | BrokenOddnessCheckRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("broken oddness check", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(BrokenOddnessCheckRuleTest, CorrectApproaches) 14 | { 15 | testRuleOnCode(new BrokenOddnessCheckRule(), "void m(int i) { if ((i & 1) == 1) {;} }"); 16 | testRuleOnCode(new BrokenOddnessCheckRule(), "void m(int i) { if (i % 1 == 1) {;} }"); 17 | } 18 | 19 | TEST(BrokenOddnessCheckRuleTest, NegativeNumberDoesNotWork) 20 | { 21 | testRuleOnCode(new BrokenOddnessCheckRule(), "void m(int i) { if (i % 2 == 1) {;} }", 22 | 0, 1, 21, 1, 30); 23 | } 24 | 25 | TEST(BrokenOddnessCheckRuleTest, NegativeNumberDoesNotWorkReverse) 26 | { 27 | testRuleOnCode(new BrokenOddnessCheckRule(), "void m(int i) { if (1 == i % 2) {;} }", 28 | 0, 1, 21, 1, 30); 29 | } 30 | 31 | TEST(BrokenOddnessCheckRuleTest, Method) 32 | { 33 | testRuleOnCode(new BrokenOddnessCheckRule(), "int a(); void m() { if (1 == a() % 2) {;} }", 34 | 0, 1, 25, 1, 36); 35 | } 36 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(BasicTests 2 | BitwiseOperatorInConditionalRuleTest.cpp 3 | BrokenNullCheckRuleTest.cpp 4 | BrokenOddnessCheckRuleTest.cpp 5 | CollapsibleIfStatementsRuleTest.cpp 6 | ConstantConditionalOperatorRuleTest.cpp 7 | ConstantIfExpressionRuleTest.cpp 8 | DeadCodeRuleTest.cpp 9 | DoubleNegativeRuleTest.cpp 10 | ForLoopShouldBeWhileLoopRuleTest.cpp 11 | GotoStatementRuleTest.cpp 12 | JumbledIncrementerRuleTest.cpp 13 | MisplacedNullCheckRuleTest.cpp 14 | MultipleUnaryOperatorRuleTest.cpp 15 | ReturnFromFinallyBlockRuleTest.cpp 16 | ThrowExceptionFromFinallyBlockRuleTest.cpp 17 | ) 18 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/ConstantConditionalOperatorRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/ConstantConditionalOperatorRule.cpp" 4 | 5 | TEST(ConstantConditionalOperatorRuleTest, PropertyTest) 6 | { 7 | ConstantConditionalOperatorRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("constant conditional operator", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(ConstantConditionalOperatorRuleTest, GoodConditionExpression) 14 | { 15 | testRuleOnCode(new ConstantConditionalOperatorRule(), "void aMethod(int b, int c) { int a = b == c ? 1 : 0; }"); 16 | } 17 | 18 | TEST(ConstantConditionalOperatorRuleTest, testCompareTwoKnownBoolValuesAlwaysBeTrue) 19 | { 20 | testRuleOnCode(new ConstantConditionalOperatorRule(), "void aMethod() { int a = 1 == 1 ? 1 : 0; }", 21 | 0, 1, 26, 1, 31); 22 | } 23 | 24 | // ConstantConditionalOperatorRule internally uses the same EvaluateAsBooleanCondition 25 | // method as ConstantIfExpressionRule does. There are more comprehensive tests in 26 | // ConstantIfExpressionRuleTest that verifies how "smartness" the EvaluateAsBooleanCondition 27 | // method is. We only verify if ConditionalOperator is visited here in above test cases. 28 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/ConstantIfExpressionRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/ConstantIfExpressionRule.cpp" 4 | 5 | TEST(ConstantIfExpressionRuleTest, PropertyTest) 6 | { 7 | ConstantIfExpressionRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("constant if expression", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(ConstantIfExpressionRuleTest, GoodConditionExpression) 14 | { 15 | testRuleOnCode(new ConstantIfExpressionRule(), "void aMethod(int b, int c) { if (b == c) {;} }"); 16 | } 17 | 18 | TEST(ConstantIfExpressionRuleTest, testCompareTwoKnownBoolValuesAlwaysBeTrue) 19 | { 20 | testRuleOnCode(new ConstantIfExpressionRule(), "void aMethod() { if (1 == 1) {;} }", 21 | 0, 1, 22, 1, 27); 22 | } 23 | 24 | TEST(ConstantIfExpressionRuleTest, testCompareTwoKnownBoolValuesAlwaysBeFalse) 25 | { 26 | testRuleOnCode(new ConstantIfExpressionRule(), "void aMethod() { if (1 == 0) {;} }", 27 | 0, 1, 22, 1, 27); 28 | } 29 | 30 | TEST(ConstantIfExpressionRuleTest, testIntegerAlwaysConstant) 31 | { 32 | testRuleOnCode(new ConstantIfExpressionRule(), "void aMethod() { if (1) {;} }", 33 | 0, 1, 22, 1, 22); 34 | } 35 | 36 | TEST(ConstantIfExpressionRuleTest, testFloatAlwaysConstant) 37 | { 38 | testRuleOnCode(new ConstantIfExpressionRule(), "void aMethod() { if (1.23) {;} }", 39 | 0, 1, 22, 1, 22); 40 | } 41 | 42 | TEST(ConstantIfExpressionRuleTest, testCompareWithTwoConstantVariables) 43 | { 44 | // testRuleOnCode(new ConstantIfExpressionRule(), "void aMethod() { int a = 1, b = 2; if (a == b) {;} }", 45 | // 0, 1, 40, 1, 46); 46 | // I am not smart enough to do this 47 | } 48 | 49 | TEST(ConstantIfExpressionRuleTest, testComplexConstantComparison) 50 | { 51 | testRuleOnCode(new ConstantIfExpressionRule(), "void aMethod() { if (1 ? 0 : 1) {;} }", 52 | 0, 1, 22, 1, 30); 53 | } 54 | 55 | TEST(ConstantIfExpressionRuleTest, testOnlyEvaluateTheNecessaryCondition) 56 | { 57 | testRuleOnCode(new ConstantIfExpressionRule(), "int foo() { return 1; } void aMethod() { if (1 ? 0 : foo()) {;} }", 58 | 0, 1, 46, 1, 58); 59 | } 60 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/DoubleNegativeRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/DoubleNegativeRule.cpp" 4 | 5 | TEST(DoubleNegativeRuleTest, PropertyTest) 6 | { 7 | DoubleNegativeRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("double negative", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(DoubleNegativeRuleTest, GoodNegative) 14 | { 15 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b1 = !0; int b2 = ~1; }"); 16 | } 17 | 18 | TEST(DoubleNegativeRuleTest, DoubleLogicalNot) 19 | { 20 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b = !!1; }", 21 | 0, 1, 26, 1, 28); 22 | } 23 | 24 | TEST(DoubleNegativeRuleTest, DoubleLogicalNotWithParentheses) 25 | { 26 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b = !(!1); }", 27 | 0, 1, 26, 1, 30); 28 | } 29 | 30 | TEST(DoubleNegativeRuleTest, DoubleNot) 31 | { 32 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b = ~~1; }", 33 | 0, 1, 26, 1, 28); 34 | } 35 | 36 | TEST(DoubleNegativeRuleTest, DoubleNotWithParentheses) 37 | { 38 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b = ~(~1); }", 39 | 0, 1, 26, 1, 30); 40 | } 41 | 42 | TEST(DoubleNegativeRuleTest, DoubleNegativeWithNestedParentheses) 43 | { 44 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b = !(((!1))); }", 45 | 0, 1, 26, 1, 34); 46 | } 47 | 48 | TEST(DoubleNegativeRuleTest, NotFollowByLogicalNot) 49 | { 50 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b = ~!1; }"); 51 | } 52 | 53 | TEST(DoubleNegativeRuleTest, LogicalNotFollowByNot) 54 | { 55 | testRuleOnCode(new DoubleNegativeRule(), "void aMethod() { int b = !~1; }"); 56 | } 57 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/ForLoopShouldBeWhileLoopRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/ForLoopShouldBeWhileLoopRule.cpp" 4 | 5 | TEST(ForLoopShouldBeWhileLoopRuleTest, PropertyTest) 6 | { 7 | ForLoopShouldBeWhileLoopRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("for loop should be while loop", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(ForLoopShouldBeWhileLoopRuleTest, GoodForLoop) 14 | { 15 | testRuleOnCode(new ForLoopShouldBeWhileLoopRule(), "void aMethod(int a) { for (int i = 0; i < a; i++) {;} }"); 16 | } 17 | 18 | TEST(ForLoopShouldBeWhileLoopRuleTest, NoIncExpr) 19 | { 20 | testRuleOnCode(new ForLoopShouldBeWhileLoopRule(), "void aMethod(int a) { for (int i = 0; i < a;) {;} }"); 21 | } 22 | 23 | TEST(ForLoopShouldBeWhileLoopRuleTest, NoInitExpr) 24 | { 25 | testRuleOnCode(new ForLoopShouldBeWhileLoopRule(), "void aMethod(int a) { for (; a < 100; a++) {;} }"); 26 | } 27 | 28 | TEST(ForLoopShouldBeWhileLoopRuleTest, NoInitExprNorIncExpr) 29 | { 30 | testRuleOnCode(new ForLoopShouldBeWhileLoopRule(), "void aMethod(int a) { for (; a < 100;) {;} }", 31 | 0, 1, 23, 1, 42); 32 | } 33 | 34 | TEST(ForLoopShouldBeWhileLoopRuleTest, IgnoreNullCondExpr) 35 | { 36 | testRuleOnCode(new ForLoopShouldBeWhileLoopRule(), "void aMethod(int a) { for (int i = 0; ; i++) {;} }"); 37 | } 38 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/GotoStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/GotoStatementRule.cpp" 4 | 5 | TEST(GotoStatementRuleTest, PropertyTest) 6 | { 7 | GotoStatementRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("goto statement", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(GotoStatementRuleTest, NoGoto) 14 | { 15 | testRuleOnCode(new GotoStatementRule(), "void m() { if (1) { ; } }"); 16 | } 17 | 18 | TEST(GotoStatementRuleTest, OneGoto) 19 | { 20 | testRuleOnCode(new GotoStatementRule(), "void a(); void m() { goto A; A:\na(); }", 21 | 0, 1, 22, 1, 27); 22 | } 23 | 24 | TEST(GotoStatementRuleTest, TwoGotos) 25 | { 26 | testRuleOnCode(new GotoStatementRule(), "void a(); void m() { goto A; goto B; A:\na();\nB:\na(); }", 27 | 0, 1, 22, 1, 27); 28 | testRuleOnCode(new GotoStatementRule(), "void a(); void m() { goto A; goto B; A:\na();\nB:\na(); }", 29 | 1, 1, 30, 1, 35); 30 | } 31 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/JumbledIncrementerRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/JumbledIncrementerRule.cpp" 4 | 5 | TEST(JumbledIncrementerRuleTest, PropertyTest) 6 | { 7 | JumbledIncrementerRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("jumbled incrementer", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(JumbledIncrementerRuleTest, GoodNestedForLoops) 14 | { 15 | testRuleOnCode(new JumbledIncrementerRule(), "void aMethod(int a) { for (int i = 0; i < a; i++) { for (int j = 0; j < a; j++) {;} } }"); 16 | } 17 | 18 | TEST(JumbledIncrementerRuleTest, InnerForLoopInsideCompoundStmt) 19 | { 20 | testRuleOnCode(new JumbledIncrementerRule(), "void aMethod(int a) { for (int i = 0; i < a; i++) { for (int j = 0; j < a; i++) {;} } }", 21 | 0, 1, 76, 1, 77); 22 | } 23 | 24 | TEST(JumbledIncrementerRuleTest, InnerForLoopIsTheBodyOfOuterForLoop) 25 | { 26 | testRuleOnCode(new JumbledIncrementerRule(), "void aMethod(int a) { for (int i = 0; i < a; i++) for (int j = 0; j < a; i++) {;} }", 27 | 0, 1, 74, 1, 75); 28 | } 29 | 30 | TEST(JumbledIncrementerRuleTest, MultiIncsAreFine) 31 | { 32 | testRuleOnCode(new JumbledIncrementerRule(), "void aMethod(int a) { for (int i = 0; i < a; i++) for (int j = 0; j < a; i++, j++) {;} }"); 33 | } 34 | -------------------------------------------------------------------------------- /oclint-rules/test/basic/ReturnFromFinallyBlockRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/basic/ReturnFromFinallyBlockRule.cpp" 4 | 5 | TEST(ReturnFromFinallyBlockRuleTest, PropertyTest) 6 | { 7 | ReturnFromFinallyBlockRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("return from finally block", rule.name()); 10 | EXPECT_EQ("basic", rule.category()); 11 | } 12 | 13 | TEST(ReturnFromFinallyBlockRuleTest, NoReturnFromFinallyBlock) 14 | { 15 | testRuleOnObjCCode(new ReturnFromFinallyBlockRule(), "void m() { @try {;} @catch(id ex) {;} @finally {;} }"); 16 | } 17 | 18 | TEST(ReturnFromFinallyBlockRuleTest, ReturnFromFinallyBlock) 19 | { 20 | testRuleOnObjCCode(new ReturnFromFinallyBlockRule(), "void m() { @try {;} @catch(id ex) {;} @finally { int i; return; int j; } }", 21 | 0, 1, 57, 1, 57); 22 | } 23 | 24 | TEST(ReturnFromFinallyBlockRuleTest, ReturnFromNestedBlockInsideFinallyBlock) 25 | { 26 | testRuleOnObjCCode(new ReturnFromFinallyBlockRule(), "void m() { @try {;} @catch(id ex) {;} @finally { int i; if(1) {return;} int j; } }", 27 | 0, 1, 64, 1, 64); 28 | } 29 | -------------------------------------------------------------------------------- /oclint-rules/test/cocoa/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(CocoaTests 2 | ObjCVerifyIsEqualHashRuleTest.cpp 3 | ObjCVerifyMustCallSuperRuleTest.cpp 4 | ObjCVerifyProhibitedCallRuleTest.cpp 5 | ObjCVerifyProtectedMethodRuleTest.cpp 6 | ObjCVerifySubclassMustImplementRuleTest.cpp 7 | ) 8 | -------------------------------------------------------------------------------- /oclint-rules/test/convention/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(ConventionTests 2 | AvoidBranchingStatementAsLastInLoopRuleTest.cpp 3 | BaseClassDestructorShouldBeVirtualOrProtectedRuleTest.cpp 4 | CoveredSwitchStatementsDontNeedDefaultRuleTest.cpp 5 | DefaultLabelNotLastInSwitchStatementRuleTest.cpp 6 | DestructorOfVirtualClassRuleTest.cpp 7 | InvertedLogicRuleTest.cpp 8 | MissingBreakInSwitchStatementRuleTest.cpp 9 | NonCaseLabelInSwitchStatementRuleTest.cpp 10 | ObjCAssignIvarOutsideAccessorsRuleTest.cpp 11 | ParameterReassignmentRuleTest.cpp 12 | PreferEarlyExitRuleTest.cpp 13 | SwitchStatementsShouldHaveDefaultRuleTest.cpp 14 | TooFewBranchesInSwitchStatementRuleTest.cpp 15 | ) 16 | -------------------------------------------------------------------------------- /oclint-rules/test/convention/DefaultLabelNotLastInSwitchStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/convention/DefaultLabelNotLastInSwitchStatementRule.cpp" 4 | 5 | TEST(DefaultLabelNotLastInSwitchStatementRuleTest, PropertyTest) 6 | { 7 | DefaultLabelNotLastInSwitchStatementRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("ill-placed default label in switch statement", rule.name()); 10 | EXPECT_EQ("MisplacedDefaultLabel", rule.identifier()); 11 | EXPECT_EQ("convention", rule.category()); 12 | } 13 | 14 | TEST(DefaultLabelNotLastInSwitchStatementRuleTest, DefaultIsLast) 15 | { 16 | testRuleOnCode(new DefaultLabelNotLastInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 17 | case 1: \n\ 18 | \tbreak; \n\ 19 | default: \n\ 20 | \tbreak; \n\ 21 | } }"); 22 | } 23 | 24 | TEST(DefaultLabelNotLastInSwitchStatementRuleTest, DefaultInTheMiddle) 25 | { 26 | testRuleOnCode(new DefaultLabelNotLastInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 27 | case 1: \n\ 28 | \tbreak; \n\ 29 | default: \n\ 30 | \tbreak; \n\ 31 | case 2: \n\ 32 | \tbreak; \n\ 33 | } }", 34 | 0, 4, 1, 5, 2); 35 | } 36 | 37 | TEST(DefaultLabelNotLastInSwitchStatementRuleTest, SwitchNoDefault) 38 | { 39 | testRuleOnCode(new DefaultLabelNotLastInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 40 | case 1: \n\ 41 | \tbreak; \n\ 42 | case 2: \n\ 43 | \tbreak; \n\ 44 | } }"); 45 | } 46 | -------------------------------------------------------------------------------- /oclint-rules/test/convention/InvertedLogicRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/convention/InvertedLogicRule.cpp" 4 | 5 | TEST(InvertedLogicRuleTest, PropertyTest) 6 | { 7 | InvertedLogicRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("inverted logic", rule.name()); 10 | EXPECT_EQ("convention", rule.category()); 11 | } 12 | 13 | TEST(InvertedLogicRuleTest, IfElseInCorrectOrder) 14 | { 15 | testRuleOnCode(new InvertedLogicRule(), "void aMethod() { int i; if (1) { i = 1; } else { i = 0; } }"); 16 | } 17 | 18 | TEST(InvertedLogicRuleTest, IfLogicalNotUnaryOperator) 19 | { 20 | testRuleOnCode(new InvertedLogicRule(), "void aMethod() { int i; if (!1) { i = 1; } else { i = 0; } }", 21 | 0, 1, 29, 1, 30); 22 | } 23 | 24 | TEST(InvertedLogicRuleTest, IfNotEqualBinaryOperator) 25 | { 26 | testRuleOnCode(new InvertedLogicRule(), "void aMethod() { int i; if (1 != 0) { i = 1; } else { i = 0; } }", 27 | 0, 1, 29, 1, 34); 28 | } 29 | 30 | TEST(InvertedLogicRuleTest, IfNegativeConditionWithNoElseBlockIsFine) 31 | { 32 | testRuleOnCode(new InvertedLogicRule(), "void aMethod() { int i; if (!1) { i = 1; } }"); 33 | } 34 | 35 | TEST(InvertedLogicRuleTest, ConditionalOperatorCorrectOrder) 36 | { 37 | testRuleOnCode(new InvertedLogicRule(), "int m(int i) { return i == 1 ? 2 : 3; }"); 38 | testRuleOnCode(new InvertedLogicRule(), "int m(int i) { return i ? 2 : 3; }"); 39 | } 40 | 41 | TEST(InvertedLogicRuleTest, ConditionalOperatorLogicalNotUnaryOperator) 42 | { 43 | testRuleOnCode(new InvertedLogicRule(), "int m(int i) { return !i ? 2 : 3; }", 44 | 0, 1, 23, 1, 24); 45 | } 46 | 47 | TEST(InvertedLogicRuleTest, ConditionalOperatorNotEqualBinaryOperator) 48 | { 49 | testRuleOnCode(new InvertedLogicRule(), "int m(int i) { return i != 0 ? 3 : 2; }", 50 | 0, 1, 23, 1, 28); 51 | } 52 | -------------------------------------------------------------------------------- /oclint-rules/test/convention/NonCaseLabelInSwitchStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/convention/NonCaseLabelInSwitchStatementRule.cpp" 4 | 5 | TEST(NonCaseLabelInSwitchStatementRuleTest, PropertyTest) 6 | { 7 | NonCaseLabelInSwitchStatementRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("non case label in switch statement", rule.name()); 10 | EXPECT_EQ("convention", rule.category()); 11 | } 12 | 13 | TEST(NonCaseLabelInSwitchStatementRuleTest, CaseAndDefault) 14 | { 15 | testRuleOnCode(new NonCaseLabelInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 16 | case 1: \n\ 17 | \tbreak; \n\ 18 | default: \n\ 19 | \tbreak; \n\ 20 | } }"); 21 | } 22 | 23 | TEST(NonCaseLabelInSwitchStatementRuleTest, OneLabel) 24 | { 25 | testRuleOnCode(new NonCaseLabelInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 26 | case 1: \n\ 27 | \tbreak; \n\ 28 | label1: \n\ 29 | \tbreak; \n\ 30 | case 2: \n\ 31 | \tbreak; \n\ 32 | } }", 33 | 0, 4, 1, 5, 2); 34 | } 35 | 36 | TEST(NonCaseLabelInSwitchStatementRuleTest, TwoLabels) 37 | { 38 | testRuleOnCode(new NonCaseLabelInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 39 | label1: \n\ 40 | \tbreak; \n\ 41 | label2: \n\ 42 | \tbreak; \n\ 43 | } }", 44 | 0, 2, 1, 3, 2); 45 | testRuleOnCode(new NonCaseLabelInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 46 | label1: \n\ 47 | \tbreak; \n\ 48 | label2: \n\ 49 | \tbreak; \n\ 50 | } }", 51 | 1, 4, 1, 5, 2); 52 | } 53 | -------------------------------------------------------------------------------- /oclint-rules/test/convention/SwitchStatementsShouldHaveDefaultRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/convention/SwitchStatementsShouldHaveDefaultRule.cpp" 4 | 5 | TEST(SwitchStatementsShouldHaveDefaultRuleTest, PropertyTest) 6 | { 7 | SwitchStatementsShouldHaveDefaultRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("missing default in switch statements", rule.name()); 10 | EXPECT_EQ("convention", rule.category()); 11 | } 12 | 13 | TEST(SwitchStatementsShouldHaveDefaultRuleTest, SwitchHasDefault) 14 | { 15 | testRuleOnCode(new SwitchStatementsShouldHaveDefaultRule(), "void aMethod(int a) { switch(a){\n\ 16 | case 1: \n\ 17 | \tbreak; \n\ 18 | default: \n\ 19 | \tbreak; \n\ 20 | } }"); 21 | } 22 | 23 | TEST(SwitchStatementsShouldHaveDefaultRuleTest, SwitchNoDefault) 24 | { 25 | testRuleOnCode(new SwitchStatementsShouldHaveDefaultRule(), "void aMethod(int a) { switch(a){\n\ 26 | case 1: \n\ 27 | \tbreak; \n\ 28 | case 2: \n\ 29 | \tbreak; \n\ 30 | } }", 31 | 0, 1, 23, 6, 1); 32 | } 33 | 34 | TEST(SwitchStatementsShouldHaveDefaultRuleTest, SwitchNoDefaultButCovered) 35 | { 36 | testRuleOnCode(new SwitchStatementsShouldHaveDefaultRule(), "typedef enum { \n\ 37 | value1 = 0, \n\ 38 | value2 = 1 \n\ 39 | } eValues; \n\ 40 | void aMethod(eValues a) { switch(a){ \n\ 41 | case value1: \n\ 42 | \tbreak; \n\ 43 | case value2: \n\ 44 | \tbreak; \n\ 45 | } }"); 46 | } 47 | 48 | TEST(SwitchStatementsShouldHaveDefaultRuleTest, SwitchNoDefaultAndNotCovered) 49 | { 50 | testRuleOnCode(new SwitchStatementsShouldHaveDefaultRule(), "typedef enum { \n\ 51 | value1 = 0, \n\ 52 | value2 = 1, \n\ 53 | value3 = 2 \n\ 54 | } eValues; \n\ 55 | void aMethod(eValues a) { switch(a){ \n\ 56 | case value1: \n\ 57 | \tbreak; \n\ 58 | case value2: \n\ 59 | \tbreak; \n\ 60 | } }", 61 | 0, 6, 27, 11, 1); 62 | } 63 | -------------------------------------------------------------------------------- /oclint-rules/test/convention/TooFewBranchesInSwitchStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/convention/TooFewBranchesInSwitchStatementRule.cpp" 4 | 5 | class TooFewBranchesInSwitchStatementRuleTest : public ::testing::Test { 6 | protected: 7 | virtual void SetUp() override 8 | { 9 | RuleConfiguration::addConfiguration("MINIMUM_CASES_IN_SWITCH", "3"); 10 | } 11 | 12 | virtual void TearDown() override 13 | { 14 | RuleConfiguration::removeAll(); 15 | } 16 | }; 17 | 18 | TEST_F(TooFewBranchesInSwitchStatementRuleTest, PropertyTest) 19 | { 20 | TooFewBranchesInSwitchStatementRule rule; 21 | EXPECT_EQ(3, rule.priority()); 22 | EXPECT_EQ("too few branches in switch statement", rule.name()); 23 | EXPECT_EQ("convention", rule.category()); 24 | } 25 | 26 | TEST_F(TooFewBranchesInSwitchStatementRuleTest, FourBranches) 27 | { 28 | testRuleOnCode(new TooFewBranchesInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 29 | case 1: \n\ 30 | \tbreak; \n\ 31 | case 2: \n\ 32 | \tbreak; \n\ 33 | case 3: \n\ 34 | \tbreak; \n\ 35 | case 4: \n\ 36 | \tbreak; \n\ 37 | } }"); 38 | } 39 | 40 | TEST_F(TooFewBranchesInSwitchStatementRuleTest, ThreeBranches) 41 | { 42 | testRuleOnCode(new TooFewBranchesInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 43 | case 1: \n\ 44 | \tbreak; \n\ 45 | case 2: \n\ 46 | \tbreak; \n\ 47 | case 3: \n\ 48 | \tbreak; \n\ 49 | } }"); 50 | } 51 | 52 | TEST_F(TooFewBranchesInSwitchStatementRuleTest, TwoBranches) 53 | { 54 | testRuleOnCode(new TooFewBranchesInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 55 | case 1: \n\ 56 | \tbreak; \n\ 57 | case 2: \n\ 58 | \tbreak; \n\ 59 | } }", 60 | 0, 1, 23, 6, 1); 61 | } 62 | 63 | TEST_F(TooFewBranchesInSwitchStatementRuleTest, OneBranche) 64 | { 65 | testRuleOnCode(new TooFewBranchesInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 66 | case 1: \n\ 67 | \tbreak; \n\ 68 | } }", 69 | 0, 1, 23, 4, 1); 70 | } 71 | 72 | TEST_F(TooFewBranchesInSwitchStatementRuleTest, ZeroBranch) 73 | { 74 | testRuleOnCode(new TooFewBranchesInSwitchStatementRule(), "void aMethod(int a) { switch(a){\n\ 75 | default: \n\ 76 | \tbreak; \n\ 77 | } }", 78 | 0, 1, 23, 4, 1); 79 | } 80 | -------------------------------------------------------------------------------- /oclint-rules/test/design/AvoidDefaultArgumentsOnVirtualMethodsRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/design/AvoidDefaultArgumentsOnVirtualMethodsRule.cpp" 4 | 5 | TEST(AvoidDefaultArgumentsOnVirtualMethodsRuleTest, PropertyTest) 6 | { 7 | AvoidDefaultArgumentsOnVirtualMethodsRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("avoid default arguments on virtual methods", rule.name()); 10 | EXPECT_EQ("design", rule.category()); 11 | } 12 | 13 | TEST(AvoidDefaultArgumentsOnVirtualMethodsRuleTest, VirtualWithDefaultArg) 14 | { 15 | // 1 2 3 4 16 | // 1234567890123456789012345678901234567890123 17 | std::string code = "class Test { virtual void test(int a=0); };"; 18 | testRuleOnCXXCode(new AvoidDefaultArgumentsOnVirtualMethodsRule(), 19 | code, 0, 1, 14, 1, 39); 20 | } 21 | 22 | TEST(AvoidDefaultArgumentsOnVirtualMethodsRuleTest, VirtualWithSomeArgs) 23 | { 24 | std::string code = "class Test { virtual void test(int a, int b); };"; 25 | testRuleOnCXXCode(new AvoidDefaultArgumentsOnVirtualMethodsRule(), 26 | code); 27 | } 28 | 29 | TEST(AvoidDefaultArgumentsOnVirtualMethodsRuleTest, NonVirtualWithDefaultArg) 30 | { 31 | std::string code = "class Test { void test(int a=0); };"; 32 | testRuleOnCXXCode(new AvoidDefaultArgumentsOnVirtualMethodsRule(), 33 | code); 34 | } 35 | -------------------------------------------------------------------------------- /oclint-rules/test/design/AvoidPrivateStaticMembersRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/design/AvoidPrivateStaticMembersRule.cpp" 4 | 5 | TEST(AvoidPrivateStaticMembersRuleTest, PropertyTest) 6 | { 7 | AvoidPrivateStaticMembersRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("avoid private static members", rule.name()); 10 | EXPECT_EQ("design", rule.category()); 11 | } 12 | 13 | TEST(AvoidPrivateStaticMembersRuleTest, PrivateStaticField) 14 | { 15 | // 1 2 16 | // 12345678901234567890123456789 17 | std::string code = "class Test { static int a; };"; 18 | testRuleOnCXXCode(new AvoidPrivateStaticMembersRule(), 19 | code, 0, 1, 14, 1, 25); 20 | } 21 | 22 | TEST(AvoidPrivateStaticMembersRuleTest, PrivateStaticMethod) 23 | { 24 | // 1 2 25 | // 12345678901234567890123456789 26 | std::string code = "class Test { static int a(); };"; 27 | testRuleOnCXXCode(new AvoidPrivateStaticMembersRule(), 28 | code, 0, 1, 14, 1, 27); 29 | } 30 | 31 | TEST(AvoidPrivateStaticMembersRuleTest, PublicStaticField) 32 | { 33 | std::string code = "class Test { public: static int a; };"; 34 | testRuleOnCXXCode(new AvoidPrivateStaticMembersRule(), code); 35 | } 36 | 37 | TEST(AvoidPrivateStaticMembersRuleTest, PublicStaticMethod) 38 | { 39 | std::string code = "class Test { public: static int a(); };"; 40 | testRuleOnCXXCode(new AvoidPrivateStaticMembersRule(), code); 41 | } 42 | -------------------------------------------------------------------------------- /oclint-rules/test/design/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(DesignTests 2 | AvoidDefaultArgumentsOnVirtualMethodsRuleTest.cpp 3 | AvoidPrivateStaticMembersRuleTest.cpp 4 | FeatureEnvyRuleTest.cpp 5 | ) 6 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(EmptyTests 2 | EmptyCatchStatementRuleTest.cpp 3 | EmptyDoWhileStatementRuleTest.cpp 4 | EmptyElseBlockRuleTest.cpp 5 | EmptyFinallyStatementRuleTest.cpp 6 | EmptyForStatementRuleTest.cpp 7 | EmptyIfStatementRuleTest.cpp 8 | EmptySwitchStatementRuleTest.cpp 9 | EmptyTryStatementRuleTest.cpp 10 | EmptyWhileStatementRuleTest.cpp 11 | ) 12 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyCatchStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyCatchStatementRule.cpp" 4 | 5 | TEST(EmptyCatchStatementRuleTest, PropertyTest) 6 | { 7 | EmptyCatchStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty catch statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyCatchStatementRuleTest, NonEmptyCXXCatchStmt) 14 | { 15 | testRuleOnCXXCode(new EmptyCatchStatementRule(), "void m() { try { ; } catch(...) { ; } }"); 16 | } 17 | 18 | TEST(EmptyCatchStatementRuleTest, EmptyCXXCatchWithEmptyCompoundStmt) 19 | { 20 | testRuleOnCXXCode(new EmptyCatchStatementRule(), "void m() { try { ; } catch(...) {} }", 21 | 0, 1, 33, 1, 34); 22 | } 23 | 24 | TEST(EmptyCatchStatementRuleTest, MultipleEmptyCXXCatchStmts) 25 | { 26 | testRuleOnCXXCode(new EmptyCatchStatementRule(), "void m() { try { ; } catch (int i) {} catch(...) {} }", 27 | 0, 1, 36, 1, 37); 28 | testRuleOnCXXCode(new EmptyCatchStatementRule(), "void m() { try { ; } catch (int i) {} catch(...) {} }", 29 | 1, 1, 50, 1, 51); 30 | } 31 | 32 | TEST(EmptyCatchStatementRuleTest, NonEmptyObjCCatchStmt) 33 | { 34 | testRuleOnObjCCode(new EmptyCatchStatementRule(), "void m() { @try { ; } @catch(id ex) { ; } }"); 35 | } 36 | 37 | TEST(EmptyCatchStatementRuleTest, EmptyObjCCatchWithEmptyCompoundStmt) 38 | { 39 | testRuleOnObjCCode(new EmptyCatchStatementRule(), "void m() { @try { ; } @catch(id ex) {} }", 40 | 0, 1, 37, 1, 38); 41 | } 42 | 43 | TEST(EmptyCatchStatementRuleTest, MultipleEmptyObjCCatchStmts) 44 | { 45 | testRuleOnObjCCode(new EmptyCatchStatementRule(), "void m() { @try { ; } @catch(id i) {} @catch(id ex) {} }", 46 | 0, 1, 36, 1, 37); 47 | testRuleOnObjCCode(new EmptyCatchStatementRule(), "void m() { @try { ; } @catch(id i) {} @catch(id ex) {} }", 48 | 1, 1, 53, 1, 54); 49 | } 50 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyDoWhileStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyDoWhileStatementRule.cpp" 4 | 5 | TEST(EmptyDoWhileStatementRuleTest, PropertyTest) 6 | { 7 | EmptyDoWhileStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty do/while statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyDoWhileStatementRuleTest, GoodWhileStatement) 14 | { 15 | testRuleOnCode(new EmptyDoWhileStatementRule(), "void m() { do {;} while(1); }"); 16 | } 17 | 18 | TEST(EmptyDoWhileStatementRuleTest, WhileStatementWithEmptyComponent) 19 | { 20 | testRuleOnCode(new EmptyDoWhileStatementRule(), "void m() { do {} while(1); }", 21 | 0, 1, 15, 1, 16); 22 | } 23 | 24 | TEST(EmptyDoWhileStatementRuleTest, WhileStatementWithNullStmt) 25 | { 26 | testRuleOnCode(new EmptyDoWhileStatementRule(), "void m() { do \n;\nwhile(1); }", 27 | 0, 2, 1, 2, 1); 28 | } 29 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyElseBlockRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyElseBlockRule.cpp" 4 | 5 | TEST(EmptyElseBlockRuleTest, PropertyTest) 6 | { 7 | EmptyElseBlockRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty else block", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyElseBlockRuleTest, GoodElseBlock) 14 | { 15 | testRuleOnCode(new EmptyElseBlockRule(), "void aMethod() { if (1) {;} else {;} }"); 16 | } 17 | 18 | TEST(EmptyElseBlockRuleTest, EmptyElseComponent) 19 | { 20 | testRuleOnCode(new EmptyElseBlockRule(), "void aMethod() { if (1) {;} else {} }", 21 | 0, 1, 34, 1, 35); 22 | } 23 | 24 | TEST(EmptyElseBlockRuleTest, NullElseComponent) 25 | { 26 | testRuleOnCode(new EmptyElseBlockRule(), "void aMethod() { if (1) {;} else; }", 27 | 0, 1, 33, 1, 33); 28 | } 29 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyFinallyStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyFinallyStatementRule.cpp" 4 | 5 | TEST(EmptyFinallyStatementRuleTest, PropertyTest) 6 | { 7 | EmptyFinallyStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty finally statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyFinallyStatementRuleTest, NonEmptyObjCFinallyStmt) 14 | { 15 | testRuleOnObjCCode(new EmptyFinallyStatementRule(), "void m() { @try { ; } @catch(id ex) { ; } @finally { ; } }"); 16 | } 17 | 18 | TEST(EmptyFinallyStatementRuleTest, EmptyObjCFinallyWithEmptyCompoundStmt) 19 | { 20 | testRuleOnObjCCode(new EmptyFinallyStatementRule(), "void m() { @try { ; } @catch(id ex) { ; } @finally {} }", 21 | 0, 1, 52, 1, 53); 22 | } 23 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyForStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyForStatementRule.cpp" 4 | 5 | TEST(EmptyForStatementRuleTest, PropertyTest) 6 | { 7 | EmptyForStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty for statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyForStatementRuleTest, GoodForStatement) 14 | { 15 | testRuleOnCode(new EmptyForStatementRule(), "void aMethod() { for (;;) {;} }"); 16 | } 17 | 18 | TEST(EmptyForStatementRuleTest, ForStatementWithEmptyComponent) 19 | { 20 | testRuleOnCode(new EmptyForStatementRule(), "void aMethod() { for (;;) {} }", 21 | 0, 1, 27, 1, 28); 22 | } 23 | 24 | TEST(EmptyForStatementRuleTest, ForStatementWithNullStmt) 25 | { 26 | testRuleOnCode(new EmptyForStatementRule(), "void aMethod() { for (;;) \n; }", 27 | 0, 2, 1, 2, 1); 28 | } 29 | 30 | TEST(EmptyForStatementRuleTest, GoodObjcForEachStatement) 31 | { 32 | testRuleOnObjCCode(new EmptyForStatementRule(), "void aMethod() { id a; for (id it in a) {;} }"); 33 | } 34 | 35 | TEST(EmptyForStatementRuleTest, ObjcForEachStatementWithEmptyComponent) 36 | { 37 | testRuleOnObjCCode(new EmptyForStatementRule(), "void aMethod() { id a; for (id it in a) {} }", 38 | 0, 1, 41, 1, 42); 39 | } 40 | 41 | TEST(EmptyForStatementRuleTest, ObjcForEachStatementWithNullStmt) 42 | { 43 | testRuleOnObjCCode(new EmptyForStatementRule(), "void aMethod() { id a; for (id it in a) \n; }", 44 | 0, 2, 1, 2, 1); 45 | } 46 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyIfStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyIfStatementRule.cpp" 4 | 5 | TEST(EmptyIfStatementRuleTest, PropertyTest) 6 | { 7 | EmptyIfStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty if statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyIfStatementRuleTest, GoodIfStatement) 14 | { 15 | testRuleOnCode(new EmptyIfStatementRule(), "void aMethod() { if (1) {;} }"); 16 | } 17 | 18 | TEST(EmptyIfStatementRuleTest, IfStatementWithEmptyComponent) 19 | { 20 | testRuleOnCode(new EmptyIfStatementRule(), "void aMethod() { if (1) {} }", 21 | 0, 1, 25, 1, 26); 22 | } 23 | 24 | TEST(EmptyIfStatementRuleTest, IfStatementWithNull) 25 | { 26 | testRuleOnCode(new EmptyIfStatementRule(), "void aMethod() { if (1)\n; }", 27 | 0, 2, 1, 2, 1); 28 | } 29 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptySwitchStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptySwitchStatementRule.cpp" 4 | 5 | TEST(EmptySwitchStatementRuleTest, PropertyTest) 6 | { 7 | EmptySwitchStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty switch statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptySwitchStatementRuleTest, GoodSwitchStatement) 14 | { 15 | testRuleOnCode(new EmptySwitchStatementRule(), "void m() { int i; switch (i) {;} }"); 16 | } 17 | 18 | TEST(EmptySwitchStatementRuleTest, SwitchStatementWithEmptyComponent) 19 | { 20 | testRuleOnCode(new EmptySwitchStatementRule(), "void m() { int i; switch (i) {} }", 21 | 0, 1, 30, 1, 31); 22 | } 23 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyTryStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyTryStatementRule.cpp" 4 | 5 | TEST(EmptyTryStatementRuleTest, PropertyTest) 6 | { 7 | EmptyTryStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty try statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyTryStatementRuleTest, NonEmptyCXXTryStmt) 14 | { 15 | testRuleOnCXXCode(new EmptyTryStatementRule(), "void m() { try { ; } catch(...) { ; } }"); 16 | } 17 | 18 | TEST(EmptyTryStatementRuleTest, EmptyCXXTryWithEmptyCompoundStmt) 19 | { 20 | testRuleOnCXXCode(new EmptyTryStatementRule(), "void m() { try {} catch(...) { ; } }", 21 | 0, 1, 16, 1, 17); 22 | } 23 | 24 | TEST(EmptyTryStatementRuleTest, NonEmptyObjCTryStmt) 25 | { 26 | testRuleOnObjCCode(new EmptyTryStatementRule(), "void m() { @try { ; } @catch(id ex) { ; } }"); 27 | } 28 | 29 | TEST(EmptyTryStatementRuleTest, EmptyObjCTryWithEmptyCompoundStmt) 30 | { 31 | testRuleOnObjCCode(new EmptyTryStatementRule(), "void m() { @try {} @catch(id ex) { ; } }", 32 | 0, 1, 17, 1, 18); 33 | } 34 | -------------------------------------------------------------------------------- /oclint-rules/test/empty/EmptyWhileStatementRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/empty/EmptyWhileStatementRule.cpp" 4 | 5 | TEST(EmptyWhileStatementRuleTest, PropertyTest) 6 | { 7 | EmptyWhileStatementRule rule; 8 | EXPECT_EQ(2, rule.priority()); 9 | EXPECT_EQ("empty while statement", rule.name()); 10 | EXPECT_EQ("empty", rule.category()); 11 | } 12 | 13 | TEST(EmptyWhileStatementRuleTest, GoodWhileStatement) 14 | { 15 | testRuleOnCode(new EmptyWhileStatementRule(), "void m() { while(1) {;} }"); 16 | } 17 | 18 | TEST(EmptyWhileStatementRuleTest, WhileStatementWithEmptyComponent) 19 | { 20 | testRuleOnCode(new EmptyWhileStatementRule(), "void m() { while(1) {} }", 21 | 0, 1, 21, 1, 22); 22 | } 23 | 24 | TEST(EmptyWhileStatementRuleTest, WhileStatementWithNullStmt) 25 | { 26 | testRuleOnCode(new EmptyWhileStatementRule(), "void m() { while(1) \n; }", 27 | 0, 2, 1, 2, 1); 28 | } 29 | -------------------------------------------------------------------------------- /oclint-rules/test/headers/TestEngine.h: -------------------------------------------------------------------------------- 1 | #include "oclint/RuleBase.h" 2 | 3 | using namespace oclint; 4 | 5 | class TestProcessor : public ASTConsumer 6 | { 7 | private: 8 | RuleBase* _rule; 9 | ViolationSet *_violationSet; 10 | 11 | public: 12 | TestProcessor(RuleBase *rule, ViolationSet *violationSet) 13 | { 14 | _rule = rule; 15 | _violationSet = violationSet; 16 | } 17 | 18 | virtual void HandleTranslationUnit(ASTContext &astContext) override 19 | { 20 | RuleCarrier *carrier = new RuleCarrier(&astContext, _violationSet); 21 | _rule->takeoff(carrier); 22 | } 23 | }; 24 | 25 | class TestFrontendAction : public clang::ASTFrontendAction 26 | { 27 | private: 28 | RuleBase* _rule; 29 | ViolationSet *_violationSet; 30 | 31 | public: 32 | TestFrontendAction(RuleBase *rule, ViolationSet *violationSet) 33 | { 34 | _rule = rule; 35 | _violationSet = violationSet; 36 | } 37 | 38 | std::unique_ptr 39 | CreateASTConsumer(clang::CompilerInstance &, llvm::StringRef) override 40 | { 41 | return llvm::make_unique(_rule, _violationSet); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /oclint-rules/test/helper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(HelperTests 2 | AttributeHelperTest.cpp 3 | SuppressHelperTest.cpp 4 | ) 5 | -------------------------------------------------------------------------------- /oclint-rules/test/migration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(MigrationTests 2 | ObjCBoxedExpressionsRuleTest.cpp 3 | ObjCContainerLiteralsRuleTest.cpp 4 | ObjCNSNumberLiteralsRuleTest.cpp 5 | ObjCObjectSubscriptingRuleTest.cpp 6 | ) 7 | -------------------------------------------------------------------------------- /oclint-rules/test/naming/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(NamingTests 2 | LongVariableNameRuleTest.cpp 3 | ShortVariableNameRuleTest.cpp 4 | ) 5 | -------------------------------------------------------------------------------- /oclint-rules/test/naming/LongVariableNameRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/naming/LongVariableNameRule.cpp" 4 | 5 | class LongVariableNameRuleTest : public ::testing::Test { 6 | protected: 7 | virtual void SetUp() override 8 | { 9 | RuleConfiguration::addConfiguration("LONG_VARIABLE_NAME", "3"); 10 | } 11 | 12 | virtual void TearDown() override 13 | { 14 | RuleConfiguration::removeAll(); 15 | } 16 | }; 17 | 18 | TEST_F(LongVariableNameRuleTest, PropertyTest) 19 | { 20 | LongVariableNameRule rule; 21 | EXPECT_EQ(3, rule.priority()); 22 | EXPECT_EQ("long variable name", rule.name()); 23 | EXPECT_EQ("naming", rule.category()); 24 | } 25 | 26 | TEST_F(LongVariableNameRuleTest, NoVar) 27 | { 28 | testRuleOnCode(new LongVariableNameRule(), "void aMethod() { }"); 29 | } 30 | 31 | TEST_F(LongVariableNameRuleTest, OneCharName) 32 | { 33 | testRuleOnCode(new LongVariableNameRule(), "void aMethod(int i) {}"); 34 | } 35 | 36 | TEST_F(LongVariableNameRuleTest, TwoCharsName) 37 | { 38 | testRuleOnCode(new LongVariableNameRule(), "void aMethod() { int ii; }"); 39 | } 40 | 41 | TEST_F(LongVariableNameRuleTest, ThreeCharsName) 42 | { 43 | testRuleOnCode(new LongVariableNameRule(), "void aMethod() { int iii; }"); 44 | } 45 | 46 | TEST_F(LongVariableNameRuleTest, FourCharsName) 47 | { 48 | testRuleOnCode(new LongVariableNameRule(), "void aMethod(int iiii) {}", 49 | 0, 1, 14, 1, 18, "Length of variable name `iiii` is 4, which is longer than the threshold of 3"); 50 | } 51 | 52 | TEST_F(LongVariableNameRuleTest, FiveCharsName) 53 | { 54 | testRuleOnCode(new LongVariableNameRule(), "void aMethod() { int iiiii; }", 55 | 0, 1, 18, 1, 22, "Length of variable name `iiiii` is 5, which is longer than the threshold of 3"); 56 | } 57 | TEST_F(LongVariableNameRuleTest, FifteenCharsName) 58 | { 59 | testRuleOnCode(new LongVariableNameRule(), "void aMethod() { int iiiiiiiiiiiiiii; }", 60 | 0, 1, 18, 1, 22, "Length of variable name `iiiiii...iii` is 15, which is longer than the threshold of 3"); 61 | } 62 | -------------------------------------------------------------------------------- /oclint-rules/test/redundant/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(RedundantTests 2 | RedundantConditionalOperatorRuleTest.cpp 3 | RedundantIfStatementRuleTest.cpp 4 | RedundantLocalVariableRuleTest.cpp 5 | RedundantNilCheckRuleTest.cpp 6 | UnnecessaryElseStatementRuleTest.cpp 7 | UnnecessaryNullCheckForCXXDeallocRuleTest.cpp 8 | UselessParenthesesRuleTest.cpp 9 | ) 10 | -------------------------------------------------------------------------------- /oclint-rules/test/redundant/RedundantLocalVariableRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/redundant/RedundantLocalVariableRule.cpp" 4 | 5 | TEST(RedundantLocalVariableRuleTest, PropertyTest) 6 | { 7 | RedundantLocalVariableRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("redundant local variable", rule.name()); 10 | EXPECT_EQ("redundant", rule.category()); 11 | } 12 | 13 | TEST(RedundantLocalVariableRuleTest, NoRedundantLocalVariable) 14 | { 15 | testRuleOnCode(new RedundantLocalVariableRule(), "int aMethod() { int i = 1; i++; return 0; }"); 16 | } 17 | 18 | TEST(RedundantLocalVariableRuleTest, DeclVarFollowedByReturnStmt) 19 | { 20 | testRuleOnCode(new RedundantLocalVariableRule(), 21 | "int aMethod() { " VIOLATION_START "int i = " VIOLATION_END "1; return i; }"); 22 | } 23 | 24 | TEST(RedundantLocalVariableRuleTest, DeclVarFollowedByReturnStmtInANestedCompoundStmt) 25 | { 26 | testRuleOnCode(new RedundantLocalVariableRule(), 27 | "int aMethod() { if (1) { " VIOLATION_START "int i = " VIOLATION_END "1; return i; } return 0; }"); 28 | } 29 | -------------------------------------------------------------------------------- /oclint-rules/test/redundant/UselessParenthesesRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/redundant/UselessParenthesesRule.cpp" 4 | 5 | TEST(UselessParenthesesRuleTest, PropertyTest) 6 | { 7 | UselessParenthesesRule rule; 8 | EXPECT_EQ(3, rule.priority()); 9 | EXPECT_EQ("useless parentheses", rule.name()); 10 | EXPECT_EQ("redundant", rule.category()); 11 | } 12 | 13 | TEST(UselessParenthesesRuleTest, NoParentheses) 14 | { 15 | testRuleOnCode(new UselessParenthesesRule(), "void m() { if(1) {} }"); 16 | } 17 | 18 | TEST(UselessParenthesesRuleTest, RedundantParenthesesInReturnStmt) 19 | { 20 | testRuleOnCode(new UselessParenthesesRule(), 21 | "int m() { return " VIOLATION_START "(0" VIOLATION_END "); }"); 22 | } 23 | 24 | TEST(UselessParenthesesRuleTest, RedundantParenthesesInAssignment) 25 | { 26 | testRuleOnCode(new UselessParenthesesRule(), 27 | "int m(int x) { int y = " VIOLATION_START "(x + 1" VIOLATION_END "); return y; }"); 28 | } 29 | 30 | TEST(UselessParenthesesRuleTest, RedundantParenthesesInMultipleAssignments) 31 | { 32 | testRuleOnCode(new UselessParenthesesRule(), 33 | "int m(int x) { int a, y = " VIOLATION_START "(x + 1" VIOLATION_END "), " 34 | "z = " VIOLATION_START "(x + 2" VIOLATION_END "); return y + z; }"); 35 | } 36 | 37 | TEST(UselessParenthesesRuleTest, RedundantParenthesesInIfCondition) 38 | { 39 | testRuleOnCode(new UselessParenthesesRule(), 40 | "void m(int x) { if (" VIOLATION_START "(x > 0" VIOLATION_END ")) { return; } }"); 41 | } 42 | 43 | TEST(UselessParenthesesRuleTest, ParenthesesInArithmetic) 44 | { 45 | testRuleOnCode(new UselessParenthesesRule(), "int m(int x) { return (x + 1) / 2; }"); 46 | } 47 | -------------------------------------------------------------------------------- /oclint-rules/test/size/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(SizeTests 2 | CyclomaticComplexityRuleTest.cpp 3 | LongClassRuleTest.cpp 4 | LongLineRuleTest.cpp 5 | LongMethodRuleTest.cpp 6 | NPathComplexityRuleTest.cpp 7 | NcssMethodCountRuleTest.cpp 8 | NestedBlockDepthRuleTest.cpp 9 | TooManyFieldsRuleTest.cpp 10 | TooManyMethodsRuleTest.cpp 11 | TooManyParametersRuleTest.cpp 12 | ) 13 | -------------------------------------------------------------------------------- /oclint-rules/test/size/LongLineRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/size/LongLineRule.cpp" 4 | 5 | class LongLineRuleTest : public ::testing::Test { 6 | protected: 7 | virtual void SetUp() override 8 | { 9 | RuleConfiguration::addConfiguration("LONG_LINE", "0"); 10 | } 11 | 12 | virtual void TearDown() override 13 | { 14 | RuleConfiguration::removeAll(); 15 | } 16 | }; 17 | 18 | TEST_F(LongLineRuleTest, PropertyTest) 19 | { 20 | LongLineRule rule; 21 | EXPECT_EQ(3, rule.priority()); 22 | EXPECT_EQ("long line", rule.name()); 23 | EXPECT_EQ("size", rule.category()); 24 | } 25 | 26 | TEST_F(LongLineRuleTest, GetNumberOfCharactersForALine) 27 | { 28 | testRuleOnCode(new LongLineRule(), "void m() {}", 29 | 0, 1, 1, 1, 11, "Line with 11 characters exceeds limit of 0"); 30 | } 31 | 32 | TEST_F(LongLineRuleTest, GetNumberOfCharactersForThreeLines) 33 | { 34 | testRuleOnCode(new LongLineRule(), "void m() {\n \n}", 35 | 0, 1, 1, 1, 10, "Line with 10 characters exceeds limit of 0"); 36 | testRuleOnCode(new LongLineRule(), "void m() {\n \n}", 37 | 1, 2, 1, 2, 2, "Line with 2 characters exceeds limit of 0"); 38 | testRuleOnCode(new LongLineRule(), "void m() {\n \n}", 39 | 2, 3, 1, 3, 1, "Line with 1 characters exceeds limit of 0"); 40 | } 41 | -------------------------------------------------------------------------------- /oclint-rules/test/size/LongMethodRuleTest.cpp: -------------------------------------------------------------------------------- 1 | #include "TestRuleOnCode.h" 2 | 3 | #include "rules/size/LongMethodRule.cpp" 4 | 5 | class LongMethodRuleTest : public ::testing::Test { 6 | protected: 7 | virtual void SetUp() override 8 | { 9 | RuleConfiguration::addConfiguration("LONG_METHOD", "0"); 10 | } 11 | 12 | virtual void TearDown() override 13 | { 14 | RuleConfiguration::removeAll(); 15 | } 16 | }; 17 | 18 | TEST_F(LongMethodRuleTest, PropertyTest) 19 | { 20 | LongMethodRule rule; 21 | EXPECT_EQ(3, rule.priority()); 22 | EXPECT_EQ("long method", rule.name()); 23 | EXPECT_EQ("size", rule.category()); 24 | } 25 | 26 | TEST_F(LongMethodRuleTest, OneLine) 27 | { 28 | testRuleOnCode(new LongMethodRule(), "void aMethod() { }", 29 | 0, 1, 1, 1, 18, "Method with 1 lines exceeds limit of 0"); 30 | } 31 | 32 | TEST_F(LongMethodRuleTest, OneLineWithoutBraces) 33 | { 34 | testRuleOnCXXCode(new LongMethodRule(), "void aMethod() try{} catch(...) {}", 35 | 0, 1, 1, 1, 34, "Method with 1 lines exceeds limit of 0"); 36 | } 37 | 38 | TEST_F(LongMethodRuleTest, TweLines) 39 | { 40 | testRuleOnCode(new LongMethodRule(), "void aMethod() {\n}", 41 | 0, 1, 1, 2, 1, "Method with 2 lines exceeds limit of 0"); 42 | } 43 | -------------------------------------------------------------------------------- /oclint-rules/test/unused/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BUILD_TEST(UnusedTests 2 | UnusedLocalVariableRuleTest.cpp 3 | UnusedMethodParameterRuleTest.cpp 4 | ) 5 | -------------------------------------------------------------------------------- /oclint-scripts/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010-2014 Longyi Qi and the OCLint project contributors. 2 | Copyright (C) 2015-2018 Ryuichi Laboratories and the OCLint project contributors. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the author nor the names of its contributors may be used 14 | to endorse or promote products derived from this software without specific 15 | prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /oclint-scripts/README: -------------------------------------------------------------------------------- 1 | Quick Start 2 | ------------------------------------------------------------------------------- 3 | 4 | ./make - Delete existing build, check out dependencies, build LLVM/Clang, 5 | build OCLint in optimized mode, bundle binaries and libraries 6 | together, and finally archive everything at ../build folder 7 | 8 | Detail description can be found at 9 | http://oclint.org/docs/intro/build.html 10 | 11 | Compiling in debug mode and enabling testing, please look at 12 | http://oclint.org/docs/devel/compiletest.html 13 | -------------------------------------------------------------------------------- /oclint-scripts/countly: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import argparse 4 | import shutil 5 | import subprocess 6 | import sys 7 | import os 8 | 9 | from oclintscripts import cmake 10 | from oclintscripts import environment 11 | from oclintscripts import path 12 | from oclintscripts import process 13 | from oclintscripts import version 14 | 15 | arg_parser = argparse.ArgumentParser() 16 | arg_parser.add_argument('task_name', choices=['checkout', 'co', 'build']) 17 | arg_parser.add_argument('-clean', '--clean', action="store_true") 18 | arg_parser.add_argument('-j', type=int, default=0) 19 | arg_parser.add_argument('-use-system-compiler', '--use-system-compiler', action="store_true", default=environment.is_linux()) 20 | args = arg_parser.parse_args() 21 | 22 | def clean_module(): 23 | build_path = path.build.countly_build_dir 24 | path.rm_f(build_path) 25 | 26 | def build_command(): 27 | cmd_build = cmake.builder(path.source.countly_dir) 28 | cmd_build.append('CMAKE_BUILD_TYPE', 'Release') 29 | if environment.is_unix() and not args.use_system_compiler: 30 | cmd_build.use_local_clang_compiler() 31 | return cmd_build.str() 32 | 33 | def build_module(j): 34 | build_path = path.build.countly_build_dir 35 | command = build_command() 36 | current_dir = os.getcwd() 37 | path.mkdir_p(build_path) 38 | path.cd(build_path) 39 | process.call(command) 40 | process.make(j) 41 | path.cd(current_dir) 42 | 43 | def checkout_countly(): 44 | if path.is_dir(path.source.countly_dir): 45 | sys.exit('Countly folder exists!') 46 | current_dir = os.getcwd() 47 | path.cd(path.root_dir) 48 | process.call('git clone --branch ' + version.countly_cpp_tag() + ' --depth 1 ' + path.url.countly_cpp + ' countly') 49 | path.cd(current_dir) 50 | 51 | if args.task_name == 'checkout' or args.task_name == 'co': 52 | checkout_countly() 53 | 54 | if args.task_name == 'build': 55 | if args.clean: 56 | clean_module() 57 | build_module(args.j) 58 | -------------------------------------------------------------------------------- /oclint-scripts/docGen: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | ./build core -docgen 4 | ./build metrics -docgen 5 | ./build rules -docgen 6 | ./build driver -docgen 7 | ./bundle -docgen 8 | mkdir -p ../build/oclint-docs/rules 9 | ../build/oclint-release/bin/oclint-docgen docgen 10 | cd ../build/ 11 | tar zcf oclint-docs-dev-snapshot.tar.gz oclint-docs/ 12 | -------------------------------------------------------------------------------- /oclint-scripts/make: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | ./ci -reset "$@" 4 | ./ci -setup -release "$@" 5 | -------------------------------------------------------------------------------- /oclint-scripts/makeWithSystemLLVM: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | if test $# -ne 1; then 4 | echo "Build with external LLVM/clang." 5 | echo "Expected:" 6 | echo "$0 " 7 | exit 1 8 | fi 9 | 10 | LLVM_PATH=$1 11 | 12 | if test ! -s $LLVM_PATH; then 13 | echo "Could not find directory $LLVM_PATH" 14 | exit 2 15 | fi 16 | 17 | # Build OCLint against an existing LLVM installation outside this repository. 18 | # The path of the LLVM build needs to be absolute. 19 | 20 | ./build -llvm-root=$LLVM_PATH -release -clean -use-system-compiler 21 | ./bundle -llvm-root=$LLVM_PATH -release 22 | -------------------------------------------------------------------------------- /oclint-scripts/oclintscripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulingtianxia/oclint/e55814f3087d19511f3fb65f205f9a8b7c8d47fa/oclint-scripts/oclintscripts/__init__.py -------------------------------------------------------------------------------- /oclint-scripts/oclintscripts/cmake.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import os 4 | 5 | from oclintscripts import environment 6 | from oclintscripts import path 7 | 8 | class builder: 9 | def __init__(self, source_path): 10 | self.__source_path = source_path 11 | self.__cmd = 'cmake' 12 | if environment.is_mingw32(): 13 | self.__cmd += ' -G "MSYS Makefiles"' 14 | 15 | def __wrap_double_quote(self, value): 16 | return '"' + value + '"' 17 | 18 | def str(self): 19 | cmd = self.__cmd + ' ' 20 | if environment.is_mingw32(): 21 | return cmd + self.__wrap_double_quote(self.__source_path) 22 | else: 23 | return cmd + self.__source_path 24 | 25 | def append(self, key, value, double_quote = False): 26 | self.__cmd += ' -D ' + key + '=' 27 | if double_quote: 28 | self.__cmd += self.__wrap_double_quote(value) 29 | else: 30 | self.__cmd += value 31 | return self 32 | 33 | def release_build(self): 34 | return self.append('OCLINT_BUILD_TYPE', 'Release') 35 | 36 | def test_build(self): 37 | return self.append('TEST_BUILD', '1') 38 | 39 | def doc_gen_build(self): 40 | return self.append('DOC_GEN_BUILD', '1') 41 | 42 | def no_analytics_build(self): 43 | return self.append('NO_ANALYTICS', '1') 44 | 45 | def use_local_clang_compiler(self, llvm_root = path.build.clang_install_dir): 46 | clang_bin_path = os.path.join(llvm_root, 'bin', 'clang') 47 | return self.append('CMAKE_CXX_COMPILER', clang_bin_path + '++').append('CMAKE_C_COMPILER', clang_bin_path) 48 | 49 | def use_ninja(self): 50 | if not environment.is_mingw32(): 51 | self.__cmd += ' -G Ninja' 52 | return self 53 | 54 | def append_dict(self, dict): 55 | for key, value in dict.items(): 56 | self.append(key, value, environment.is_mingw32()) 57 | return self 58 | -------------------------------------------------------------------------------- /oclint-scripts/oclintscripts/environment.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import platform 4 | import multiprocessing 5 | import subprocess 6 | 7 | def cpu_count(): 8 | return multiprocessing.cpu_count() 9 | 10 | def kernel(): 11 | return platform.uname()[0].lower() 12 | 13 | def kernel_version(): 14 | return platform.uname()[2] 15 | 16 | def arch(): 17 | return platform.uname()[4].lower() 18 | 19 | def linux_distribution(): 20 | return platform.linux_distribution() 21 | 22 | def dist_env(): 23 | return arch() + '-' + kernel() + '-' + kernel_version() 24 | 25 | def is_mingw32(): 26 | return kernel().startswith("windows") 27 | # Cygwin should say CYGWIN_NT-6.1-WOW64 28 | 29 | def is_darwin(): 30 | return kernel().startswith("darwin") 31 | 32 | def is_linux(): 33 | return kernel().startswith("linux") 34 | 35 | def is_unix(): 36 | return is_darwin() or is_linux() 37 | -------------------------------------------------------------------------------- /oclint-scripts/oclintscripts/process.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import subprocess 4 | import sys 5 | 6 | from oclintscripts import environment 7 | 8 | def call(command): 9 | command_exit_code = subprocess.call(command, shell=True) 10 | if command_exit_code: 11 | sys.exit(command_exit_code) 12 | 13 | def j_flag(j=None): 14 | multiple_thread = environment.cpu_count() 15 | if environment.is_mingw32(): 16 | multiple_thread = 1 17 | if j is not None and j is not 0: 18 | multiple_thread = j 19 | return ' -j ' + str(multiple_thread) 20 | 21 | def make(j=None): 22 | call('make' + j_flag(j)) 23 | 24 | def ninja(): 25 | call('ninja') 26 | -------------------------------------------------------------------------------- /oclint-scripts/oclintscripts/version.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import subprocess 4 | import os 5 | 6 | from oclintscripts import path 7 | from oclintscripts import environment 8 | 9 | def dev_version(): 10 | current_working_folder = os.getcwd() 11 | try: 12 | os.chdir(path.root_dir) 13 | git_hash = subprocess.check_output(['git', 'log', '-n', '1', '--pretty=%h']).split()[0] 14 | path.cd(current_working_folder) 15 | return git_hash 16 | except: 17 | print("Ignore the git error above if you are building from a source code download instead of a git clone.") 18 | path.cd(current_working_folder) 19 | return "src" 20 | 21 | def oclint_version(): 22 | return "0.13" 23 | 24 | def oclint_dev_version(): 25 | return oclint_version() + '.dev.' + dev_version() 26 | 27 | def llvm_branches(): 28 | return [llvm_master_branch(), llvm_latest_release_branch()] 29 | 30 | def llvm_default_branch(): 31 | return llvm_latest_release_branch() 32 | 33 | def llvm_master_branch(): 34 | return 'trunk' 35 | 36 | def llvm_latest_release_branch(): 37 | return 'tags/RELEASE_500/final' 38 | 39 | def countly_cpp_tag(): 40 | return '17.10' 41 | -------------------------------------------------------------------------------- /oclint-scripts/travis: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | ./clang prebuilt 4 | if [ "$1" = "build" ] 5 | then 6 | ./countly co 7 | ./countly build 8 | ./build -no-ninja 9 | ./bundle -archive 10 | elif [ "$1" = "docgen" ] 11 | then 12 | ./docGen 13 | else 14 | ./googleTest co 15 | ./googleTest build 16 | shift 17 | MODULE="$1" 18 | shift 19 | for dep in $* 20 | do 21 | ./test "$dep" -as-dep -no-ninja 22 | done 23 | ./test "$MODULE" 24 | fi 25 | -------------------------------------------------------------------------------- /oclint-scripts/upload: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import json 4 | import sys 5 | import time 6 | import os 7 | 8 | from oclintscripts import environment 9 | from oclintscripts import path 10 | from oclintscripts import process 11 | from oclintscripts import version 12 | 13 | # This is a placeholder script for uploading generated oclint archive to remote server. 14 | # Implement this script and comment the line below 15 | sys.exit("Error: no upload script implemented.") 16 | 17 | def build_root_dir(): 18 | return path.build_root 19 | 20 | def archive_file_name(): 21 | distribution_name = version.oclint_dev_version() + '-' + environment.dist_env() 22 | if environment.is_mingw32(): 23 | return 'oclint-' + distribution_name + '.zip' 24 | elif environment.is_darwin() or environment.is_linux(): 25 | return 'oclint-' + distribution_name + '.tar.gz' 26 | else: 27 | sys.exit("Error: this environment is not supported yet.") 28 | 29 | def archive_file_path(): 30 | return os.path.join(build_root_dir(), archive_file_name()) 31 | 32 | def archive_file_size(): 33 | return os.path.getsize(archive_file_path()) 34 | 35 | def archive_file_human_readable_size(): 36 | size = archive_file_size() 37 | format = "%.0f%s" 38 | for unit in ['bytes','KB','MB','GB']: 39 | if size < 1024.0: 40 | return format % (size, unit) 41 | size /= 1024.0 42 | return format % (size, 'TB') 43 | 44 | def archive_json(var_name): 45 | archive_info_dict = {} 46 | archive_info_dict['date'] = int(time.time()) 47 | archive_info_dict['version'] = version.oclint_dev_version(); 48 | archive_info_dict['size'] = archive_file_human_readable_size(); 49 | archive_info_dict['path'] = archive_file_name(); 50 | archive_info_dict['description'] = 'OCLint ' + version.oclint_version() + ' dev build for ' + environment.kernel() + '/' + environment.arch() 51 | return 'var ' + var_name + ' = ' + json.dumps(archive_info_dict) + ';' 52 | 53 | def run_command(cmd): 54 | process.call(cmd) 55 | --------------------------------------------------------------------------------