quick-lint / quick-lint-js Goto Github PK
View Code? Open in Web Editor NEWquick-lint-js finds bugs in JavaScript programs
Home Page: https://quick-lint-js.com
License: GNU General Public License v3.0
quick-lint-js finds bugs in JavaScript programs
Home Page: https://quick-lint-js.com
License: GNU General Public License v3.0
The following file causes our Vim ALE integration to crash:
let = 3;
x = 4;
Error detected while processing function <SNR>67_VimCloseCallback[11]..<SNR>67_VimExitCallback[14]..<S
NR>63_HandleExit[43]..quick_lint_js_ale#parse_command_output:
line 9:
E491: json decode error at '../src/include/quick-lint-js/parse.h:177: fatal: token not implemented in
parse_and_visit_statement: equal on line 1 column 5]}'
Hello, Mr. Strager.
I was looking for a fast way to lint our large javascript project when I came across this tool. This looks great, unfortunately I have some pretty strong issues about the name of your default branch.
The master
branch is a term from when slave-masters would force their slaves to write their tests and maintenance tickets, as well as updating their dependencies.
Since slavery has been abolished, I feel that it is best to remove this vestige of slavery by giving the main branch more inclusive name like main, prod, or release.
Thank you for taking the time to read this. And if this racist code can be cleaned up a bit, I hope our team can start adopting quick-lint
It'd be cool if we could set up continuous or occasional fuzzing. Perhaps Microsoft's new service might help?
The command-line parser uses char
. This is [likely] problematic on Windows if command-line arguments contain non-ASCII characters. Make the command-line parser support wchar_t
and WinMain
.
This change might have ripple effects, such as the CreateFileA
call in read_file
. We should probably do some UTF-16-to-UTF-8 conversions to ease the transition.
Add a --help
option to the quick-lint-js
command-line utility which lists other supported options.
Detect --help
in options.cpp, add a variable to the option
struct in options.cpp, test the option parsing in test-option.cpp, and print the help message in main.cpp.
Inspired by issue #53.
In the following code, the programmer probably intends to escape the newline with a backslash or use a template literal:
let x = "hello
world";
Currently, quick-lint-js will interpret this code as having the following tokens:
kw_let
identifier
(x
)equal
string
("hello
)identifier
(world
)string
(";
)Ideally, instead, it'd interpret this code as having the following tokens:
kw_let
identifier
(x
)equal
string
("helloworld"
)semicolon
We can't just munch until the next "
, 'cus that would be poor error recovery for code like this:
console.log("starting se
startServer(port);
Idea: if we see an end-of-line when parsing a string literal, check the following line. If the following line has exactly one matching "
or '
, treat that matching quote as the end of the current string. Otherwise, treat the end-of-line as the end of the current string.
The code for string literal parsing is in lex.cpp, and the existing tests are in test-lex.cpp.
We could run some precise benchmarks on CI. Examples:
Valgrind might help a lot.
Also, we need to store the collected data somewhere, and have some fancy dashboards to present the data.
JavaScript loops can have labels, and break
and continue
statements can refer to those labels:
outer: for (let y of ys) {
for (let x of xs) {
if (x == y) {
break outer;
}
}
}
quick-lint-js currently doesn't ensure labels in break
and continue
statements refer to breakable or continuable loops. Teach the variable analyzer (or something else) to detect problems related to loop labels, such as the following:
break
/continue
: label doesn't exist at all in the current functionbreak
/continue
: Label is attached to an unrelated loopThe parser doesn't report visits for a lot of information needed to do this analysis (such as the labels themselves, or loop structures), so this is a decently involved task.
When linting the following file
from;
I expect quick-lint-js to tell me:
hello.js:1:1: error: use of undeclared variable: from
But instead it tells me:
<...>/quick-lint-js/src/include/quick-lint-js/parse.h:179: fatal: token not implemented in parse_and_visit_statement: kw_from on line 1 column 1
quick-lint-js understands hexadecimal, binary, and decimal number literals, but doesn't understand octal number literals.
Teach quick-lint-js to parse octal number literals in lex.cpp and in test-lex.cpp.
This code:
let i = "test
";
results in this output on my system:
/home/frank/tmp/test.js:1:9: error: unclosed string literal
/home/frank/tmp/test.js:2:1: error: unclosed string literal
../src/parse.cpp:563: fatal: token not implemented in parse_expression_remainder: string on line 2 column 1
Illegal instruction
Looks like the program crashed with an "illegal instruction".
({ foo })
is a valid JavaScript expression, but ({ 42 })
is not. Make quick-lint-js report an error for the latter code. Look at parse-expression.cpp, parse.cpp, and error.h. (There's a TODO comment in parse.cpp.)
When linting the following file
let get;
I expect quick-lint-js to produce no diagnostics.
But instead it tells me:
get.js:1:1: error: let with no bindings
get.js:1:4: error: missing semicolon after expression
<...>/src/./quick-lint-js/parse.h:210: fatal: token not implemented in parse_and_visit_statement: kw_get on line 1 column 5
This issue feels distinct from #28 because it produces two erroneous diagnostics before crashing.
Note: I think this task needs a bit more C++ skill than other good-first-issue issues.
Currently, all issues reported by quick-lint-js are called "errors". Some issues, such as use-of-undeclared-variable, are really warnings, not errors. Make quick-lint-js label such issues as warnings.
Relevant code exists in error.h, error-formatter.h, *-error-reporter.cpp, and test-*-error-reporter.cpp.
JavaScript has a rarely-used with
statement. Make quick-lint-js parse such statements (instead of crashing) by augmenting parse.h.
I think with
statements have a very similar syntax to while
statements, so we might be able to copy-paste code to parse with
statements.
Teaching the linter the semantics of with
statements is out of scope for this task.
Note: I think this task needs a bit more C++ skill than other good-first-issue issues.
If quick-lint-js's CLI reports an error in a JavaScript program, it should return a non-zero exit code like other linters. Our CLI currently returns zero always.
Idea for implementation:
error_reporter
-derived class which tracks if any errors were detected, forwarding errors to another error_reporter
object.error_reporter
created in step 1.If a regular expression literal contains invalid flags (/hello/q4
), quick-lint-js should report an error.
See the ECMAScript standard RegExpInitialize for an explanation of what flags are valid.
See lex.cpp, error.h, and test-lex.cpp for implementation.
JavaScript allows <!--
and -->
for comments. quick-lint-js doesn't understand such comments. Edit lex.cpp and test-lex.cpp. See skip_block_comment and skip_line_comment for related code.
<!--
-->
If you run quick-lint-js on the following program, the linter reports two issues:
x += 4;
hello.js:1:1: error: use of undeclared variable: x
hello.js:1:1: error: assignment to undeclared variable
quick-lint-js should instead report just one error. For example:
hello.js:1:1: error: use and assignment of undeclared variable: x
Tweak variable-analyzer.cpp, diagnostic-types.h, and test-variable-analyzer.cpp to make quick-lint-js be less noisy.
The "build and test web demo" workflow is spewing warnings:
The
add-path
command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
Example run: https://github.com/quick-lint/quick-lint-js/actions/runs/305701526
Let's fix this warning.
JavaScript interprets the literal 9999999999999999
as the number 10000000000000000
. Report a warning in this case.
Let's see if GNU gettext is a good fit for translations.
etra0 had issues building quick-lint-js with GCC 8. In their words:
Used instructions in the README, which are:
$ cmake .
$ cmake --build .
and throws linking errors. Using the ones in travis.yml works:
$ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=YES -S . -B .
$ cmake --build . --config Debug
$ CXX=g++-8 cmake .
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 8.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/g++-8
-- Check for working CXX compiler: /usr/bin/g++-8 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test QUICK_LINT_JS_COMPILER_SUPPORTS_DESIGNATED_INITIALIZERS
-- Performing Test QUICK_LINT_JS_COMPILER_SUPPORTS_DESIGNATED_INITIALIZERS - Success
-- Performing Test QUICK_LINT_JS_HAVE_FCHAR8_T
-- Performing Test QUICK_LINT_JS_HAVE_FCHAR8_T - Failed
-- Failed to find LLVM FileCheck
-- Found Git: /usr/bin/git (found version "2.17.1")
-- git Version: v0.0.0
-- Version: 0.0.0
-- Performing Test HAVE_CXX_FLAG_STD_CXX11
-- Performing Test HAVE_CXX_FLAG_STD_CXX11 - Success
-- Performing Test HAVE_CXX_FLAG_WALL
-- Performing Test HAVE_CXX_FLAG_WALL - Success
-- Performing Test HAVE_CXX_FLAG_WEXTRA
-- Performing Test HAVE_CXX_FLAG_WEXTRA - Success
-- Performing Test HAVE_CXX_FLAG_WSHADOW
-- Performing Test HAVE_CXX_FLAG_WSHADOW - Success
-- Performing Test HAVE_CXX_FLAG_WERROR
-- Performing Test HAVE_CXX_FLAG_WERROR - Success
-- Performing Test HAVE_CXX_FLAG_WSHORTEN_64_TO_32
-- Performing Test HAVE_CXX_FLAG_WSHORTEN_64_TO_32 - Failed
-- Performing Test HAVE_CXX_FLAG_FSTRICT_ALIASING
-- Performing Test HAVE_CXX_FLAG_FSTRICT_ALIASING - Success
-- Performing Test HAVE_CXX_FLAG_WNO_DEPRECATED_DECLARATIONS
-- Performing Test HAVE_CXX_FLAG_WNO_DEPRECATED_DECLARATIONS - Success
-- Performing Test HAVE_CXX_FLAG_WNO_DEPRECATED
-- Performing Test HAVE_CXX_FLAG_WNO_DEPRECATED - Success
-- Performing Test HAVE_CXX_FLAG_FNO_EXCEPTIONS
-- Performing Test HAVE_CXX_FLAG_FNO_EXCEPTIONS - Success
-- Performing Test HAVE_CXX_FLAG_WSTRICT_ALIASING
-- Performing Test HAVE_CXX_FLAG_WSTRICT_ALIASING - Success
-- Performing Test HAVE_CXX_FLAG_WD654
-- Performing Test HAVE_CXX_FLAG_WD654 - Failed
-- Performing Test HAVE_CXX_FLAG_WTHREAD_SAFETY
-- Performing Test HAVE_CXX_FLAG_WTHREAD_SAFETY - Failed
-- Performing Test HAVE_CXX_FLAG_COVERAGE
-- Performing Test HAVE_CXX_FLAG_COVERAGE - Success
-- Performing Test HAVE_STD_REGEX
-- Performing Test HAVE_STD_REGEX
-- Performing Test HAVE_STD_REGEX -- success
-- Performing Test HAVE_GNU_POSIX_REGEX
-- Performing Test HAVE_GNU_POSIX_REGEX
-- Performing Test HAVE_GNU_POSIX_REGEX -- failed to compile
-- Performing Test HAVE_POSIX_REGEX
-- Performing Test HAVE_POSIX_REGEX
-- Performing Test HAVE_POSIX_REGEX -- success
-- Performing Test HAVE_STEADY_CLOCK
-- Performing Test HAVE_STEADY_CLOCK
-- Performing Test HAVE_STEADY_CLOCK -- success
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WNO_NULL_POINTER_ARITHMETIC
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WNO_NULL_POINTER_ARITHMETIC - Success
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WNO_MISSING_INCLUDE_DIRS
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WNO_MISSING_INCLUDE_DIRS - Success
-- Found PythonInterp: /home/etra/miniconda3/bin/python (found version "3.8.5")
-- JsonCpp Version: 1.9.3
-- Looking for C++ include clocale
-- Looking for C++ include clocale - found
-- Looking for localeconv
-- Looking for localeconv - found
-- Looking for C++ include sys/types.h
-- Looking for C++ include sys/types.h - found
-- Looking for C++ include stdint.h
-- Looking for C++ include stdint.h - found
-- Looking for C++ include stddef.h
-- Looking for C++ include stddef.h - found
-- Check size of lconv
-- Check size of lconv - done
-- Performing Test HAVE_DECIMAL_POINT
-- Performing Test HAVE_DECIMAL_POINT - Success
-- Performing Test QUICK_LINT_JS_HAVE_STD_FILESYSTEM_WITH_STDCXXFS
-- Performing Test QUICK_LINT_JS_HAVE_STD_FILESYSTEM_WITH_STDCXXFS - Success
-- Performing Test QUICK_LINT_JS_HAVE_STD_EXPERIMENTAL_FILESYSTEM_WITH_STDCXXFS
-- Performing Test QUICK_LINT_JS_HAVE_STD_EXPERIMENTAL_FILESYSTEM_WITH_STDCXXFS - Success
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WD26495
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WD26495 - Failed
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WD26812
-- Performing Test QUICK_LINT_JS_HAVE_WARNING_OPTION__WD26812 - Failed
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/c/Users/Sebastian/Documents/work/quick-lint-js
Scanning dependencies of target benchmark
[ 1%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/benchmark.cc.o
[ 2%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/benchmark_api_internal.cc.o
[ 3%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/benchmark_name.cc.o
[ 4%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/benchmark_register.cc.o
[ 5%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/benchmark_runner.cc.o
[ 7%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/colorprint.cc.o
[ 8%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/commandlineflags.cc.o
[ 9%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/complexity.cc.o
[ 10%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/console_reporter.cc.o
[ 11%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/counter.cc.o
[ 12%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/csv_reporter.cc.o
[ 14%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/json_reporter.cc.o
[ 15%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/reporter.cc.o
[ 16%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/sleep.cc.o
[ 17%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/statistics.cc.o
[ 18%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/string_util.cc.o
[ 20%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/sysinfo.cc.o
[ 21%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark.dir/timers.cc.o
[ 22%] Linking CXX static library libbenchmark.a
[ 22%] Built target benchmark
Scanning dependencies of target benchmark_main
[ 23%] Building CXX object vendor/benchmark/src/CMakeFiles/benchmark_main.dir/benchmark_main.cc.o
[ 24%] Linking CXX static library libbenchmark_main.a
[ 24%] Built target benchmark_main
Scanning dependencies of target boost_container
[ 25%] Building CXX object vendor/boost/libs/container/CMakeFiles/boost_container.dir/src/dlmalloc.cpp.o
[ 27%] Building CXX object vendor/boost/libs/container/CMakeFiles/boost_container.dir/src/global_resource.cpp.o
[ 28%] Building CXX object vendor/boost/libs/container/CMakeFiles/boost_container.dir/src/monotonic_buffer_resource.cpp.o
[ 29%] Building CXX object vendor/boost/libs/container/CMakeFiles/boost_container.dir/src/pool_resource.cpp.o
[ 30%] Building CXX object vendor/boost/libs/container/CMakeFiles/boost_container.dir/src/synchronized_pool_resource.cpp.o
[ 31%] Building CXX object vendor/boost/libs/container/CMakeFiles/boost_container.dir/src/unsynchronized_pool_resource.cpp.o
[ 32%] Building C object vendor/boost/libs/container/CMakeFiles/boost_container.dir/src/alloc_lib.c.o
[ 34%] Linking CXX static library libboost_container.a
[ 34%] Built target boost_container
Scanning dependencies of target gtest
[ 35%] Building CXX object vendor/googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
[ 36%] Linking CXX static library ../../../lib/libgtest.a
[ 36%] Built target gtest
Scanning dependencies of target gmock
[ 37%] Building CXX object vendor/googletest/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o
[ 38%] Linking CXX static library ../../../lib/libgmock.a
[ 38%] Built target gmock
Scanning dependencies of target gmock_main
[ 40%] Building CXX object vendor/googletest/googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.o
[ 41%] Linking CXX static library ../../../lib/libgmock_main.a
[ 41%] Built target gmock_main
Scanning dependencies of target gtest_main
[ 42%] Building CXX object vendor/googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
[ 43%] Linking CXX static library ../../../lib/libgtest_main.a
[ 43%] Built target gtest_main
Scanning dependencies of target jsoncpp_lib
[ 44%] Building CXX object vendor/jsoncpp/src/lib_json/CMakeFiles/jsoncpp_lib.dir/json_reader.cpp.o
[ 45%] Building CXX object vendor/jsoncpp/src/lib_json/CMakeFiles/jsoncpp_lib.dir/json_value.cpp.o
[ 47%] Building CXX object vendor/jsoncpp/src/lib_json/CMakeFiles/jsoncpp_lib.dir/json_writer.cpp.o
[ 48%] Linking CXX static library libjsoncpp.a
[ 48%] Built target jsoncpp_lib
Scanning dependencies of target quick-lint-js-lib
[ 49%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/assert.cpp.o
[ 50%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/char8.cpp.o
[ 51%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/error.cpp.o
[ 52%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/file.cpp.o
[ 54%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/integer.cpp.o
[ 55%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/language.cpp.o
[ 56%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/lex-keyword.cpp.o
[ 57%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/lex.cpp.o
[ 58%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/lint.cpp.o
[ 60%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/location.cpp.o
[ 61%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/options.cpp.o
[ 62%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/padded-string.cpp.o
[ 63%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/parse.cpp.o
[ 64%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/text-error-reporter.cpp.o
[ 65%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/vector.cpp.o
[ 67%] Building CXX object src/CMakeFiles/quick-lint-js-lib.dir/vim-qflist-json-error-reporter.cpp.o
[ 68%] Linking CXX static library libquick-lint-js-lib.a
[ 68%] Built target quick-lint-js-lib
Scanning dependencies of target quick-lint-js-benchmark-location
[ 69%] Building CXX object benchmark/CMakeFiles/quick-lint-js-benchmark-location.dir/benchmark-location.cpp.o
[ 70%] Linking CXX executable quick-lint-js-benchmark-location
[ 70%] Built target quick-lint-js-benchmark-location
Scanning dependencies of target quick-lint-js-benchmark-lex
[ 71%] Building CXX object benchmark/CMakeFiles/quick-lint-js-benchmark-lex.dir/benchmark-lex.cpp.o
[ 72%] Linking CXX executable quick-lint-js-benchmark-lex
[ 72%] Built target quick-lint-js-benchmark-lex
Scanning dependencies of target quick-lint-js-benchmark-parse
[ 74%] Building CXX object benchmark/CMakeFiles/quick-lint-js-benchmark-parse.dir/benchmark-parse.cpp.o
[ 75%] Linking CXX executable quick-lint-js-benchmark-parse
[ 75%] Built target quick-lint-js-benchmark-parse
Scanning dependencies of target quick-lint-js
[ 76%] Building CXX object src/CMakeFiles/quick-lint-js.dir/main.cpp.o
[ 77%] Linking CXX executable quick-lint-js
[ 77%] Built target quick-lint-js
Scanning dependencies of target quick-lint-js-test
[ 78%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/error-collector.cpp.o
[ 80%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/spy-visitor.cpp.o
[ 81%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-assert.cpp.o
[ 82%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-buffering-visitor.cpp.o
[ 83%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o
[ 84%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-integer.cpp.o
[ 85%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-lex.cpp.o
[ 87%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-lint-parse.cpp.o
[ 88%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-lint.cpp.o
[ 89%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-location.cpp.o
[ 90%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-narrow-cast.cpp.o
[ 91%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-options.cpp.o
[ 92%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-padded-string.cpp.o
[ 94%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-parse-expression.cpp.o
[ 95%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-parse.cpp.o
[ 96%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-text-error-reporter.cpp.o
[ 97%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-vector.cpp.o
[ 98%] Building CXX object test/CMakeFiles/quick-lint-js-test.dir/test-vim-qflist-json-error-reporter.cpp.o
[100%] Linking CXX executable quick-lint-js-test
CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o: In function `quick_lint_js::(anonymous namespace)::make_temporary_directory()':
test-file.cpp:(.text+0x1aa1): undefined reference to `std::filesystem::temp_directory_path[abi:cxx11]()'
CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o: In function `std::filesystem::__cxx11::path::path(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::filesystem::__cxx11::path::format)':
test-file.cpp:(.text._ZNSt10filesystem7__cxx114pathC2EONSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS1_6formatE[_ZNSt10filesystem7__cxx114pathC5EONSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS1_6formatE]+0x4f): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o: In function `std::filesystem::__cxx11::path::operator/=(std::filesystem::__cxx11::path const&)':
test-file.cpp:(.text._ZNSt10filesystem7__cxx114pathdVERKS1_[_ZNSt10filesystem7__cxx114pathdVERKS1_]+0x3d): undefined reference to `std::filesystem::__cxx11::path::has_filename() const'
test-file.cpp:(.text._ZNSt10filesystem7__cxx114pathdVERKS1_[_ZNSt10filesystem7__cxx114pathdVERKS1_]+0x98): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o: In function `std::filesystem::__cxx11::path::is_absolute() const':
test-file.cpp:(.text._ZNKSt10filesystem7__cxx114path11is_absoluteEv[_ZNKSt10filesystem7__cxx114path11is_absoluteEv]+0x14): undefined reference to `std::filesystem::__cxx11::path::has_root_directory() const'
CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o: In function `std::filesystem::__cxx11::path::path<char [8], std::filesystem::__cxx11::path>(char const (&) [8], std::filesystem::__cxx11::path::format)':
test-file.cpp:(.text._ZNSt10filesystem7__cxx114pathC2IA8_cS1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5IA8_cS1_EERKT_NS1_6formatE]+0x6d): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o: In function `std::filesystem::__cxx11::path::path<char [18], std::filesystem::__cxx11::path>(char const (&) [18], std::filesystem::__cxx11::path::format)':
test-file.cpp:(.text._ZNSt10filesystem7__cxx114pathC2IA18_cS1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5IA18_cS1_EERKT_NS1_6formatE]+0x6d): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
CMakeFiles/quick-lint-js-test.dir/test-file.cpp.o: In function `std::filesystem::__cxx11::path::path<char [21], std::filesystem::__cxx11::path>(char const (&) [21], std::filesystem::__cxx11::path::format)':
test-file.cpp:(.text._ZNSt10filesystem7__cxx114pathC2IA21_cS1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5IA21_cS1_EERKT_NS1_6formatE]+0x6d): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status
make[2]: *** [test/quick-lint-js-test] Error 1
test/CMakeFiles/quick-lint-js-test.dir/build.make:544: recipe for target 'test/quick-lint-js-test' failed
make[1]: *** [test/CMakeFiles/quick-lint-js-test.dir/all] Error 2
CMakeFiles/Makefile2:1990: recipe for target 'test/CMakeFiles/quick-lint-js-test.dir/all' failed
make: *** [all] Error 2
Makefile:140: recipe for target 'all' failed
For the following snippet of code, quick-lint-js reports two errors:
x = 42;
const x;
hello.js:1:1: error: assignment to const variable
hello.js:2:7: note: const variable declared here
hello.js:1:1: error: variable assigned before its declaration
hello.js:2:7: note: variable declared here
Edit error.h, lint.cpp, and test-lint.cpp to combine these errors into a new type of error to reduce noise. For example:
hello.js:1:1: error: assignment to const variable before its declaration
hello.js:2:7: note: const variable declared here
The following snippets of code are invalid JavaScript:
throw;
throw
new Error();
Unfortunately, quick-lint-js accepts these snippets without reporting an error. Teach quick-lint-js to report an error by editing parse.h, test-parse.cpp, and error.h.
JavaScript has a debugger
keyword which is used for ... debugging. quick-lint-js gets confused when it sees a debugger
statement.
debugger
is a keyword, not a normal identifier. See lex.h, lex-keyword.gperf, and test-lex.cpp.debugger
statements. See parse.h and test-parse.cpp. debugger
statements should have no impact on the linter (I think).JavaScript number literals can contain underscores. quick-lint-js doesn't parse these as numbers, but it should.
Change lex.cpp and test-lex.cpp to teach quick-lint-js about number literals like 1_234_567.
quick-lint-js reports an error if a decimal or binary number literal contains bogus digits:
// hello.js:2:5: error: unexpected characters in number literal
1234abcd
Give hexadecimal literals the same error-reporting treatment. See parse_binary_number in lex.cpp, and tests in test-lex.cpp.
Add a --version
option to the quick-lint-js command-line utility which prints quick-lint-js' version number and exits without linting.
Detect --version
in options.cpp, add a variable to the option
struct in options.cpp, test the option parsing in test-option.cpp, and print the version message in main.cpp.
See also the --help
option introduced in PR #20.
The GitHub Actions workflows for building and testing only run on my branches, not on pull requests. Make them run on pull requests, too.
Previous attempt: strager@e55b699
quick-lint-js should build with C++ exceptions and RTTI disabled. To make sure this remains true, add variants to CI which build quick-lint-js with these features disabled.
For GCC and Clang, I think the options we need are -fno-exceptions
and -fno-rtti
.
CI rules are inside the .github/ directory.
JavaScript allows certain non-ASCII characters in identifiers. For example:
let Ƞ = "hello";
console.log(Ƞ); // Prints 'hello'.
This confuses quick-lint-js. Make our lexer parse UTF-8 properly and recognize identifier characters.
String literals can contain hexadecimal escape sequences (starting with \x
). If the escape sequence is invalid, quick-lint-js should report an error. Teach quick-lint-js about such errors in lex.cpp, error.h, and test-lex.cpp.
quick-lint-js gives incorrect column numbers when the source code contains non-ASCII characters:
/*☃*/x
Expected:
$ ./build/quick-lint-js hello.js
hello.js:1:6: error: use of undeclared variable: x
Observed:
$ ./build/quick-lint-js hello.js
hello.js:1:8: error: use of undeclared variable: x
quick-lint-js' locator should count ☃ as one column, not three.
If a number literal has trailing underscores (123_), the syntax is invalid. quick-lint-js should report an error for such constructs. Edit error.h, lex.cpp, and test-lex.cpp to make quick-lint-js help users find this bug.
JavaScript's strict mode affects many things which a linter cares about, such as the parsing of identifiers and octal literals. Detect strict mode and implement some rules.
Strict mode is tricky. It's lexically scoped. There are several ways a program can opt into strict mode, such as in a class
declaration or expression, a "use strict";
expression statement, or a module.
JavaScript string literals and template literals can contain backslash-escaped newlines:
let s = "hello\
world";
let t = `hello\
world`;
Make sure these parse correctly as part of the string/template. Test in test-lex.cpp, fix in lex.cpp.
When quick-lint-js encounters an identifier with an escape sequence, it replaces the escape sequence with the escaped character:
let a = "hello";
console.log(\u{61}); // Prints 'hello'. '\u{61}' is replaced with 'a' in-place during lexing.
Currently, we only support ASCII characters. We should support non-ASCII characters:
let \u{0220} = "hello";
console.log(\u{61}); // Prints 'hello'. '\u{0220}' should be replaced with bytes 0xC8 0xA0 in-place during lexing.
Note: Recognizing unescaped non-ASCII characters is out of scope for this task.
For the following code, the linter can't do a good job with what the parser gives it:
let x = x;
Current behavior of parser:
Desired behavior of parser:
quick-lint-js' command-line options parser supports --help
, but not -h
. Teach it to parse -h
as if it was --help
. Same with --version
and -v
.
If a number literal has doubled underscores (123__456
) or trailing underscores (123_
), the syntax is invalid. quick-lint-js should report an error for such constructs. Edit error.h, lex.cpp, and test-lex.cpp to make quick-lint-js help users find this bug.
In debug builds, quick-lint-js crashes on the following JavaScript snippets:
let x = 0x;
let y = 0b;
This is because quick-lint-js assumes that a digit follows 0x
or 0b
, which is not necessarily true.
Teach quick-lint-js to report a user-friendly error on incomplete number literals. For example:
hello.js:1:9: binary number literal has no digits
Note: support for 0o
-prefixed octal number literals will be added in #7.
Related to Issue #12
Running quick-lint-js-test.exe creates temp folders.
If temp folder hits QLJ64.tmp and then quick quick-lint-test.exe is run it will complain: 'failed to create temporary directory'.
Note: You can access temp folder by using %temp%
quick-lint-js/src/parse.cpp:504: fatal: token not implemented in parse_expression_remainder: kw_const on line 3 column 1
I'm parsing a file with const
in it ... I guess that is the issue. This was on master
.
quick-lint-js should support UTF-8 input files, not just ASCII input files.
JavaScript supports underscores in number literals, including hex literals. quick-lint-js understands underscores in decimal literals (123_456
), but doesn't understand underscores in hexadecimal literals (0x1234_5678
).
Edit lex.cpp and test-lex.cpp to teach quick-lint-js to ignore underscores in hex literals.
When building qljs with cmake --build .
, the executable is placed at src/quick-lint-js
.
Not familiar other projects' patterns, but wondering if it is normal to place the compiled target in the src
directory.
But, truth is, this whole issue was just an excuse to use GitHub CLI to create an issue. And it was a resounding success
The tests in test-file.cpp create a temporary directory on the file system, but they don't clean up when they're done. When a test finishes, delete the temporary directory and any files which might exist inside.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.