diff --git a/.arclint b/.arclint index 710fcd0c1..d713e538e 100644 --- a/.arclint +++ b/.arclint @@ -1,298 +1,302 @@ { "linters": { "generated": { "type": "generated" }, "clang-format": { "type": "clang-format", "version": ">=11.0", "bin": ["clang-format-11", "clang-format"], "include": "(^src/.*\\.(h|c|cpp|mm)$)", "exclude": [ "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, "autopep8": { "type": "autopep8", "version": ">=1.3.4", "include": "(\\.py$)", "exclude": [ "(^contrib/gitian-builder/)", "(^contrib/apple-sdk-tools/)" ], "flags": [ "--aggressive", "--ignore=W503,W504" ] }, "flake8": { "type": "flake8", "version": ">=3.0", "include": "(\\.py$)", "exclude": [ "(^contrib/gitian-builder/)", "(^contrib/apple-sdk-tools/)" ], "flags": [ "--ignore=E303,E305,E501,E704,W503,W504" ] }, "lint-format-strings": { "type": "lint-format-strings", "include": "(^src/.*\\.(h|c|cpp)$)", "exclude": [ "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)", "(^src/test/fuzz/strprintf.cpp$)" ] }, "check-doc": { "type": "check-doc", "include": "(^src/.*\\.(h|c|cpp)$)" }, "lint-tests": { "type": "lint-tests", "include": "(^src/(seeder/|rpc/|wallet/)?test/.*\\.(cpp)$)" }, "lint-python-format": { "type": "lint-python-format", "include": "(\\.py$)", "exclude": [ "(^test/lint/lint-python-format\\.py$)", "(^contrib/gitian-builder/)", "(^contrib/apple-sdk-tools/)" ] }, "phpcs": { "type": "phpcs", "include": "(\\.php$)", "exclude": [ "(^arcanist/__phutil_library_.+\\.php$)" ], "phpcs.standard": "arcanist/phpcs.xml" }, "lint-locale-dependence": { "type": "lint-locale-dependence", "include": "(^src/.*\\.(h|cpp)$)", "exclude": [ "(^src/(crypto/ctaes/|leveldb/|secp256k1/|tinyformat.h|univalue/))", "(^src/bench/nanobench.h$)" ] }, "lint-cheader": { "type": "lint-cheader", "include": "(^src/.*\\.(h|cpp)$)", "exclude": [ "(^src/(crypto/ctaes|secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, "spelling": { "type": "spelling", "exclude": [ "(^build-aux/m4/)", "(^depends/)", "(^doc/release-notes/)", "(^contrib/gitian-builder/)", "(^src/(qt/locale|secp256k1|univalue|leveldb)/)", "(^test/lint/dictionary/)", "(package-lock.json)" ], "spelling.dictionaries": [ "test/lint/dictionary/english.json" ] }, "lint-assert-with-side-effects": { "type": "lint-assert-with-side-effects", "include": "(^src/.*\\.(h|cpp)$)", "exclude": [ "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, "lint-include-quotes": { "type": "lint-include-quotes", "include": "(^src/.*\\.(h|cpp)$)", "exclude": [ "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, "lint-include-guard": { "type": "lint-include-guard", "include": "(^src/.*\\.h$)", "exclude": [ "(^src/(crypto/ctaes|secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)", "(^src/tinyformat.h$)" ] }, "lint-include-source": { "type": "lint-include-source", "include": "(^src/.*\\.(h|c|cpp)$)", "exclude": [ "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, + "lint-std-chrono": { + "type": "lint-std-chrono", + "include": "(^src/.*\\.(h|cpp)$)" + }, "lint-stdint": { "type": "lint-stdint", "include": "(^src/.*\\.(h|c|cpp)$)", "exclude": [ "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)", "(^src/compat/assumptions.h$)" ] }, "lint-source-filename": { "type": "lint-source-filename", "include": "(^src/.*\\.(h|c|cpp)$)", "exclude": [ "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, "lint-boost-dependencies": { "type": "lint-boost-dependencies", "include": "(^src/.*\\.(h|cpp)$)" }, "lint-python-encoding": { "type": "lint-python-encoding", "include": "(\\.py$)", "exclude": [ "(^contrib/gitian-builder/)", "(^contrib/apple-sdk-tools/)" ] }, "lint-python-shebang": { "type": "lint-python-shebang", "include": "(\\.py$)", "exclude": [ "(__init__\\.py$)", "(^contrib/gitian-builder/)", "(^contrib/apple-sdk-tools/)" ] }, "lint-bash-shebang": { "type": "lint-bash-shebang", "include": "(\\.sh$)", "exclude": [ "(^contrib/gitian-builder/)" ] }, "shellcheck": { "type": "shellcheck", "version": ">=0.7.0", "flags": [ "--external-sources", "--source-path=SCRIPTDIR" ], "include": "(\\.sh$)", "exclude": [ "(^contrib/gitian-builder/)", "(^src/(secp256k1|univalue)/)" ] }, "lint-shell-locale": { "type": "lint-shell-locale", "include": "(\\.sh$)", "exclude": [ "(^contrib/gitian-builder/)", "(^src/(secp256k1|univalue)/)", "(^cmake/utils/log-and-print-on-failure.sh)" ] }, "lint-cpp-void-parameters": { "type": "lint-cpp-void-parameters", "include": "(^src/.*\\.(h|cpp)$)", "exclude": [ "(^src/(crypto/ctaes|secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)", "(^src/compat/glibc_compat.cpp$)" ] }, "lint-logs": { "type": "lint-logs", "include": "(^src/.*\\.(h|cpp)$)" }, "lint-qt": { "type": "lint-qt", "include": "(^src/qt/.*\\.(h|cpp)$)", "exclude": [ "(^src/qt/(locale|forms|res)/)" ] }, "lint-doxygen": { "type": "lint-doxygen", "include": "(^src/.*\\.(h|c|cpp)$)", "exclude": [ "(^src/(crypto/ctaes|secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, "lint-whitespace": { "type": "lint-whitespace", "include": "(\\.(ac|am|cmake|conf|in|include|json|m4|md|openrc|php|pl|sh|txt|yml)$)", "exclude": [ "(^contrib/gitian-builder/)", "(^src/(secp256k1|univalue|leveldb)/)", "(^src/bench/nanobench.h$)" ] }, "yamllint": { "type": "yamllint", "include": "(\\.(yml|yaml)$)", "exclude": "(^src/(secp256k1|univalue|leveldb)/)" }, "lint-check-nonfatal": { "type": "lint-check-nonfatal", "include": [ "(^src/rpc/.*\\.(h|c|cpp)$)", "(^src/wallet/rpc*.*\\.(h|c|cpp)$)" ], "exclude": "(^src/rpc/server.cpp)" }, "lint-markdown": { "type": "lint-markdown", "include": [ "(\\.md$)" ], "exclude": "(^contrib/gitian-builder/)" }, "lint-python-mypy": { "type": "lint-python-mypy", "version": ">=0.780", "include": "(\\.py$)", "exclude": "(^contrib/)", "flags": [ "--ignore-missing-imports" ] }, "lint-python-mutable-default": { "type": "lint-python-mutable-default", "include": "(\\.py$)", "exclude": [ "(^contrib/gitian-builder/)", "(^contrib/apple-sdk-tools/)" ] }, "prettier": { "type": "prettier", "version":">=2.4.1", "include": "(^web/.*\\.(css|html|js|json|jsx|md|scss|ts|tsx)$)", "exclude": "(^web/.*/translations/.*\\.json$)" }, "lint-python-isort": { "type": "lint-python-isort", "version": ">=5.6.4", "include": "(\\.py$)", "exclude": "(^contrib/)" }, "rustfmt": { "type": "rustfmt", "version": ">=1.5.1", "include": "(\\.rs$)" } } } diff --git a/arcanist/__phutil_library_map__.php b/arcanist/__phutil_library_map__.php index d43be6db4..68fb3aa05 100644 --- a/arcanist/__phutil_library_map__.php +++ b/arcanist/__phutil_library_map__.php @@ -1,96 +1,98 @@ 2, 'class' => array( 'AbstractGlobalExternalLinter' => 'linter/AbstractGlobalExternalLinter.php', 'ArcanistBitcoinABCConfiguration' => 'configuration/ArcanistBitcoinABCConfiguration.php', 'ArcanistLandBotWorkflow' => 'workflow/ArcanistLandBotWorkflow.php', 'AssertWithSideEffectsLinter' => 'linter/AssertWithSideEffectsLinter.php', 'AutoPEP8FormatLinter' => 'linter/AutoPEP8Linter.php', 'BashShebangLinter' => 'linter/BashShebangLinter.php', 'BoostDependenciesLinter' => 'linter/BoostDependenciesLinter.php', 'CHeaderLinter' => 'linter/CHeaderLinter.php', 'CheckDocLinter' => 'linter/CheckDocLinter.php', 'CheckNonFatalOverAssertInRpc' => 'linter/CheckNonFatalOverAssertInRpc.php', 'ClangFormatLinter' => 'linter/ClangFormatLinter.php', 'CppVoidParameterLinter' => 'linter/CppVoidParameterLinter.php', 'DoxygenLinter' => 'linter/DoxygenLinter.php', 'ExtendedConfigurationDrivenLintEngine' => 'engine/ExtendedConfigurationDrivenLintEngine.php', 'FileNameLinter' => 'linter/FileNameLinter.php', 'FormatStringLinter' => 'linter/FormatStringLinter.php', 'ISortFormatLinter' => 'linter/ISortLinter.php', 'IncludeGuardLinter' => 'linter/IncludeGuardLinter.php', 'IncludeQuotesLinter' => 'linter/IncludeQuotesLinter.php', 'IncludeSourceLinter' => 'linter/IncludeSourceLinter.php', 'LintOnceInterface' => 'linter/LintOnceInterface.php', 'LocaleDependenceLinter' => 'linter/LocaleDependenceLinter.php', 'LogLinter' => 'linter/LogLinter.php', 'MarkdownLinter' => 'linter/MarkdownLinter.php', 'MyPyLinter' => 'linter/MyPyLinter.php', 'PrettierLinter' => 'linter/PrettierLinter.php', 'PythonFileEncodingLinter' => 'linter/PythonFileEncodingLinter.php', 'PythonFormatLinter' => 'linter/PythonFormatLinter.php', 'PythonMutableDefaultLinter' => 'linter/PythonMutableDefaultLinter.php', 'PythonShebangLinter' => 'linter/PythonShebangLinter.php', 'Qt5Linter' => 'linter/Qt5Linter.php', 'RustfmtLinter' => 'linter/RustfmtLinter.php', 'ShellCheckLinter' => 'linter/ShellCheckLinter.php', 'ShellLocaleLinter' => 'linter/ShellLocaleLinter.php', + 'StdChronoLinter' => 'linter/StdChronoLinter.php', 'StdintLinter' => 'linter/StdintLinter.php', 'TestsLinter' => 'linter/TestsLinter.php', 'WhitespaceLinter' => 'linter/WhitespaceLinter.php', 'YamllintLinter' => 'linter/YamllintLinter.php', ), 'function' => array( 'startsWith' => 'linter/MarkdownLinter.php', ), 'xmap' => array( 'AbstractGlobalExternalLinter' => array( 'ArcanistExternalLinter', 'LintOnceInterface', ), 'ArcanistBitcoinABCConfiguration' => 'ArcanistConfiguration', 'ArcanistLandBotWorkflow' => 'ArcanistWorkflow', 'AssertWithSideEffectsLinter' => 'ArcanistLinter', 'AutoPEP8FormatLinter' => 'ArcanistExternalLinter', 'BashShebangLinter' => 'ArcanistLinter', 'BoostDependenciesLinter' => 'AbstractGlobalExternalLinter', 'CHeaderLinter' => 'ArcanistLinter', 'CheckDocLinter' => 'AbstractGlobalExternalLinter', 'CheckNonFatalOverAssertInRpc' => 'ArcanistLinter', 'ClangFormatLinter' => 'ArcanistExternalLinter', 'CppVoidParameterLinter' => 'ArcanistLinter', 'DoxygenLinter' => 'ArcanistLinter', 'ExtendedConfigurationDrivenLintEngine' => 'ArcanistLintEngine', 'FileNameLinter' => 'ArcanistLinter', 'FormatStringLinter' => 'ArcanistExternalLinter', 'ISortFormatLinter' => 'ArcanistExternalLinter', 'IncludeGuardLinter' => 'ArcanistLinter', 'IncludeQuotesLinter' => 'ArcanistLinter', 'IncludeSourceLinter' => 'ArcanistLinter', 'LocaleDependenceLinter' => 'ArcanistLinter', 'LogLinter' => 'ArcanistLinter', 'MarkdownLinter' => 'ArcanistLinter', 'MyPyLinter' => 'ArcanistExternalLinter', 'PrettierLinter' => 'ArcanistExternalLinter', 'PythonFileEncodingLinter' => 'ArcanistLinter', 'PythonFormatLinter' => 'ArcanistExternalLinter', 'PythonMutableDefaultLinter' => 'ArcanistLinter', 'PythonShebangLinter' => 'ArcanistLinter', 'Qt5Linter' => 'ArcanistLinter', 'RustfmtLinter' => 'ArcanistExternalLinter', 'ShellCheckLinter' => 'ArcanistExternalLinter', 'ShellLocaleLinter' => 'ArcanistLinter', + 'StdChronoLinter' => 'ArcanistLinter', 'StdintLinter' => 'ArcanistLinter', 'TestsLinter' => 'ArcanistExternalLinter', 'WhitespaceLinter' => 'ArcanistLinter', 'YamllintLinter' => 'ArcanistExternalLinter', ), )); diff --git a/arcanist/linter/StdChronoLinter.php b/arcanist/linter/StdChronoLinter.php new file mode 100644 index 000000000..f5b57682c --- /dev/null +++ b/arcanist/linter/StdChronoLinter.php @@ -0,0 +1,60 @@ + ArcanistLintSeverity::SEVERITY_ERROR, + ); + } + + public function getLintNameMap() { + return array( + self::BAD_DURATION_CONSTRUCTOR => pht( + 'Uninitialized chrono::duration constructor'), + ); + } + + public function lintPath($path) { + $absPath = Filesystem::resolvePath($path, $this->getProjectRoot()); + $fileContent = Filesystem::readFile($absPath); + + if (preg_match_all( + '/std::chrono::(?:'. + 'duration|hours|minutes|seconds|milliseconds|microseconds|nanoseconds)'. + '(?:<.*>)?\(\)/', $fileContent, $matches, PREG_OFFSET_CAPTURE)) { + foreach ($matches[0] as $match) { + list($durationConstructor, $offset) = $match; + $this->raiseLintAtOffset( + $offset, + self::BAD_DURATION_CONSTRUCTOR, + pht($durationConstructor." without an explicit initialized value ". + "may lead to undesired behavior."), + $durationConstructor, + substr_replace($durationConstructor, '0', -1, 0) + ); + } + } + } +}