mirror of
https://github.com/Automattic/harper.git
synced 2025-12-05 19:26:55 -06:00
feat: add solidity support (#1443)
* feat(harper-comments): add solidity support * feat(harper-tree-sitter): merge overlapping spans * feat(harper-comments): add specific solidity parser * perf(harper-comments): early return * test(harper-comments): add multiline solidity test * test(harper-comments): add ignore test * feat(vscode-plugin): add solidity support * docs: add Solidity to documentation * test: fix offset * test: comment out solidity tests for vscode-plugin * chore: fix justfile to use /usr/bin/env The commands don't work on nixOS * chore: fix more commands * fix: return Dart support --------- Co-authored-by: Elijah Potter <me@elijahpotter.dev>
This commit is contained in:
877
Cargo.lock
generated
877
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -11,29 +11,30 @@ repository = "https://github.com/automattic/harper"
|
||||
harper-core = { path = "../harper-core", version = "0.44.0" }
|
||||
harper-html = { path = "../harper-html", version = "0.44.0" }
|
||||
harper-tree-sitter = { path = "../harper-tree-sitter", version = "0.44.0" }
|
||||
tree-sitter = "0.20.10"
|
||||
tree-sitter-rust = "0.20.4"
|
||||
tree-sitter-typescript = "0.20.3"
|
||||
tree-sitter-python = "0.20.4"
|
||||
tree-sitter-javascript = "0.20.1"
|
||||
tree-sitter-go = "0.20.0"
|
||||
tree-sitter-c = "0.20.7"
|
||||
tree-sitter-cpp = "0.20.5"
|
||||
tree-sitter-cmake = "=0.4.1"
|
||||
tree-sitter-ruby = "0.20.1"
|
||||
tree-sitter-swift = "=0.4.0"
|
||||
tree-sitter-c-sharp = "0.20.0"
|
||||
tree-sitter-toml = "0.20.0"
|
||||
tree-sitter-lua = "0.0.19"
|
||||
tree-sitter-bash = "0.20.0"
|
||||
tree-sitter-java = "0.20.0"
|
||||
tree-sitter-nix = "0.0.1"
|
||||
tree-sitter-haskell = "0.15.0"
|
||||
tree-sitter-php = "=0.22.2"
|
||||
tree-sitter-dart = "0.0.4"
|
||||
tree-sitter-scala = "0.20.0"
|
||||
tree-sitter-kotlin = "=0.3.5"
|
||||
itertools = "0.14.0"
|
||||
tree-sitter = "0.25.6"
|
||||
tree-sitter-bash = "0.25.0"
|
||||
tree-sitter-c = "0.24.1"
|
||||
tree-sitter-cmake = "0.7.1"
|
||||
tree-sitter-cpp = "0.23.4"
|
||||
tree-sitter-c-sharp = "0.23.1"
|
||||
tree-sitter-go = "0.23.4"
|
||||
tree-sitter-haskell = "0.23.1"
|
||||
tree-sitter-java = "0.23.5"
|
||||
tree-sitter-javascript = "0.23.1"
|
||||
tree-sitter-kotlin-ng = "1.1.0"
|
||||
tree-sitter-lua = "0.2.0"
|
||||
tree-sitter-nix = "0.0.2"
|
||||
tree-sitter-php = "0.23.11"
|
||||
tree-sitter-python = "0.23.6"
|
||||
tree-sitter-ruby = "0.23.1"
|
||||
tree-sitter-rust = "0.24.0"
|
||||
tree-sitter-scala = "0.24.0"
|
||||
tree-sitter-solidity = "1.2.11"
|
||||
tree-sitter-swift = "0.7.1"
|
||||
tree-sitter-toml-ng = "0.7.0"
|
||||
tree-sitter-typescript = "0.23.2"
|
||||
harper-tree-sitter-dart = "0.0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
paste = "1.0.15"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use comment_parsers::{Go, JavaDoc, JsDoc, Unit};
|
||||
use comment_parsers::{Go, JavaDoc, JsDoc, Solidity, Unit};
|
||||
use harper_core::parsers::{self, MarkdownOptions, Parser};
|
||||
use harper_core::{MutableDictionary, Token};
|
||||
use tree_sitter::Node;
|
||||
@@ -22,44 +22,46 @@ impl CommentParser {
|
||||
markdown_options: MarkdownOptions,
|
||||
) -> Option<Self> {
|
||||
let language = match language_id {
|
||||
"rust" => tree_sitter_rust::language(),
|
||||
"typescriptreact" => tree_sitter_typescript::language_tsx(),
|
||||
"typescript" => tree_sitter_typescript::language_typescript(),
|
||||
"python" => tree_sitter_python::language(),
|
||||
"nix" => tree_sitter_nix::language(),
|
||||
"javascript" => tree_sitter_javascript::language(),
|
||||
"javascriptreact" => tree_sitter_typescript::language_tsx(),
|
||||
"go" => tree_sitter_go::language(),
|
||||
"c" => tree_sitter_c::language(),
|
||||
"cpp" => tree_sitter_cpp::language(),
|
||||
"cmake" => tree_sitter_cmake::language(),
|
||||
"ruby" => tree_sitter_ruby::language(),
|
||||
"swift" => tree_sitter_swift::language(),
|
||||
"csharp" => tree_sitter_c_sharp::language(),
|
||||
"toml" => tree_sitter_toml::language(),
|
||||
"lua" => tree_sitter_lua::language(),
|
||||
"shellscript" => tree_sitter_bash::language(),
|
||||
"java" => tree_sitter_java::language(),
|
||||
"haskell" => tree_sitter_haskell::language(),
|
||||
"php" => tree_sitter_php::language_php(),
|
||||
"dart" => tree_sitter_dart::language(),
|
||||
"scala" => tree_sitter_scala::language(),
|
||||
"kotlin" => tree_sitter_kotlin::language(),
|
||||
"cmake" => tree_sitter_cmake::LANGUAGE,
|
||||
"cpp" => tree_sitter_cpp::LANGUAGE,
|
||||
"csharp" => tree_sitter_c_sharp::LANGUAGE,
|
||||
"c" => tree_sitter_c::LANGUAGE,
|
||||
"dart" => harper_tree_sitter_dart::LANGUAGE,
|
||||
"go" => tree_sitter_go::LANGUAGE,
|
||||
"haskell" => tree_sitter_haskell::LANGUAGE,
|
||||
"javascriptreact" => tree_sitter_typescript::LANGUAGE_TSX,
|
||||
"javascript" => tree_sitter_javascript::LANGUAGE,
|
||||
"java" => tree_sitter_java::LANGUAGE,
|
||||
"kotlin" => tree_sitter_kotlin_ng::LANGUAGE,
|
||||
"lua" => tree_sitter_lua::LANGUAGE,
|
||||
"nix" => tree_sitter_nix::LANGUAGE,
|
||||
"php" => tree_sitter_php::LANGUAGE_PHP,
|
||||
"python" => tree_sitter_python::LANGUAGE,
|
||||
"ruby" => tree_sitter_ruby::LANGUAGE,
|
||||
"rust" => tree_sitter_rust::LANGUAGE,
|
||||
"scala" => tree_sitter_scala::LANGUAGE,
|
||||
"shellscript" => tree_sitter_bash::LANGUAGE,
|
||||
"solidity" => tree_sitter_solidity::LANGUAGE,
|
||||
"swift" => tree_sitter_swift::LANGUAGE,
|
||||
"toml" => tree_sitter_toml_ng::LANGUAGE,
|
||||
"typescriptreact" => tree_sitter_typescript::LANGUAGE_TSX,
|
||||
"typescript" => tree_sitter_typescript::LANGUAGE_TYPESCRIPT,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let comment_parser: Box<dyn Parser> = match language_id {
|
||||
"go" => Box::new(Go::new_markdown(markdown_options)),
|
||||
"java" => Box::new(JavaDoc::default()),
|
||||
"javascriptreact" | "typescript" | "typescriptreact" | "javascript" => {
|
||||
Box::new(JsDoc::new_markdown(markdown_options))
|
||||
}
|
||||
"java" => Box::new(JavaDoc::default()),
|
||||
"go" => Box::new(Go::new_markdown(markdown_options)),
|
||||
"solidity" => Box::new(Solidity::new_markdown(markdown_options)),
|
||||
_ => Box::new(Unit::new_markdown(markdown_options)),
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
inner: parsers::Mask::new(
|
||||
CommentMasker::new(language, Self::node_condition),
|
||||
CommentMasker::new(language.into(), Self::node_condition),
|
||||
comment_parser,
|
||||
),
|
||||
})
|
||||
@@ -77,31 +79,32 @@ impl CommentParser {
|
||||
/// [`Self::new_from_language_id`]
|
||||
fn filename_to_filetype(path: &Path) -> Option<&'static str> {
|
||||
Some(match path.extension()?.to_str()? {
|
||||
"py" => "python",
|
||||
"nix" => "nix",
|
||||
"rs" => "rust",
|
||||
"ts" => "typescript",
|
||||
"tsx" => "typescriptreact",
|
||||
"bash" => "shellscript",
|
||||
"c" => "c",
|
||||
"cmake" => "cmake",
|
||||
"cpp" => "cpp",
|
||||
"cs" => "csharp",
|
||||
"dart" => "dart",
|
||||
"go" => "go",
|
||||
"h" => "cpp",
|
||||
"hs" => "haskell",
|
||||
"java" => "java",
|
||||
"js" => "javascript",
|
||||
"jsx" => "javascriptreact",
|
||||
"go" => "go",
|
||||
"c" => "c",
|
||||
"cpp" => "cpp",
|
||||
"cmake" => "cmake",
|
||||
"h" => "cpp",
|
||||
"rb" => "ruby",
|
||||
"swift" => "swift",
|
||||
"cs" => "csharp",
|
||||
"toml" => "toml",
|
||||
"lua" => "lua",
|
||||
"sh" => "shellscript",
|
||||
"bash" => "shellscript",
|
||||
"java" => "java",
|
||||
"hs" => "haskell",
|
||||
"php" => "php",
|
||||
"dart" => "dart",
|
||||
"scala" | "sbt" | "mill" => "scala",
|
||||
"kt" | "kts" => "kotlin",
|
||||
"lua" => "lua",
|
||||
"nix" => "nix",
|
||||
"php" => "php",
|
||||
"py" => "python",
|
||||
"rb" => "ruby",
|
||||
"rs" => "rust",
|
||||
"scala" | "sbt" | "mill" => "scala",
|
||||
"sh" => "shellscript",
|
||||
"sol" => "solidity",
|
||||
"swift" => "swift",
|
||||
"toml" => "toml",
|
||||
"ts" => "typescript",
|
||||
"tsx" => "typescriptreact",
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
mod go;
|
||||
mod javadoc;
|
||||
mod jsdoc;
|
||||
mod solidity;
|
||||
mod unit;
|
||||
|
||||
pub use go::Go;
|
||||
use harper_core::Span;
|
||||
pub use javadoc::JavaDoc;
|
||||
pub use jsdoc::JsDoc;
|
||||
pub use solidity::Solidity;
|
||||
pub use unit::Unit;
|
||||
|
||||
/// Get the span of a tree-sitter-produced comment that doesn't include the
|
||||
|
||||
80
harper-comments/src/comment_parsers/solidity.rs
Normal file
80
harper-comments/src/comment_parsers/solidity.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use harper_core::Lrc;
|
||||
use harper_core::Span;
|
||||
use harper_core::Token;
|
||||
use harper_core::parsers::{Markdown, MarkdownOptions, Parser};
|
||||
|
||||
use super::without_initiators;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Solidity {
|
||||
inner: Lrc<dyn Parser>,
|
||||
}
|
||||
|
||||
impl Solidity {
|
||||
pub fn new(parser: Lrc<dyn Parser>) -> Self {
|
||||
Self { inner: parser }
|
||||
}
|
||||
|
||||
pub fn new_markdown(markdown_options: MarkdownOptions) -> Self {
|
||||
Self::new(Lrc::new(Markdown::new(markdown_options)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Parser for Solidity {
|
||||
fn parse(&self, source: &[char]) -> Vec<Token> {
|
||||
let mut tokens = Vec::new();
|
||||
|
||||
let mut chars_traversed = 0;
|
||||
|
||||
for line in source.split(|c| *c == '\n') {
|
||||
let mut new_tokens = parse_line(line, self.inner.clone());
|
||||
|
||||
if chars_traversed + line.len() < source.len() {
|
||||
new_tokens.push(Token::new(
|
||||
Span::new_with_len(line.len(), 1),
|
||||
harper_core::TokenKind::Newline(1),
|
||||
));
|
||||
}
|
||||
|
||||
new_tokens
|
||||
.iter_mut()
|
||||
.for_each(|t| t.span.push_by(chars_traversed));
|
||||
|
||||
chars_traversed += line.len() + 1;
|
||||
tokens.append(&mut new_tokens);
|
||||
}
|
||||
|
||||
tokens
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_line(source: &[char], parser: Lrc<dyn Parser>) -> Vec<Token> {
|
||||
let mut actual = without_initiators(source);
|
||||
if actual.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
let mut actual_source = actual.get_content(source);
|
||||
|
||||
// ignore the special SPDX-License-Identifier comment
|
||||
if actual_source.starts_with(&['S', 'P', 'D', 'X', '-']) {
|
||||
let Some(terminator) = source.iter().position(|c| *c == '\n') else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
actual.start += terminator;
|
||||
|
||||
let Some(new_source) = actual.try_get_content(actual_source) else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
actual_source = new_source
|
||||
}
|
||||
|
||||
let mut new_tokens = parser.parse(actual_source);
|
||||
|
||||
new_tokens
|
||||
.iter_mut()
|
||||
.for_each(|t| t.span.push_by(actual.start));
|
||||
|
||||
new_tokens
|
||||
}
|
||||
@@ -42,7 +42,9 @@ macro_rules! create_test {
|
||||
|
||||
create_test!(multiline_comments.cpp, 3);
|
||||
create_test!(multiline_comments.ts, 3);
|
||||
create_test!(multiline_comments.sol, 3);
|
||||
create_test!(clean.rs, 0);
|
||||
create_test!(clean.sol, 0);
|
||||
create_test!(jsdoc.ts, 4);
|
||||
create_test!(issue_96.lua, 0);
|
||||
create_test!(merged_lines.ts, 1);
|
||||
@@ -60,6 +62,7 @@ create_test!(basic_kotlin.kt, 0);
|
||||
// Checks that some comments are masked out
|
||||
create_test!(ignore_comments.rs, 1);
|
||||
create_test!(ignore_comments.c, 1);
|
||||
create_test!(ignore_comments.sol, 1);
|
||||
|
||||
// These are to make sure nothing crashes.
|
||||
create_test!(empty.js, 0);
|
||||
|
||||
27
harper-comments/tests/language_support_sources/clean.sol
Normal file
27
harper-comments/tests/language_support_sources/clean.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
/// This is an example Solidity file that should produce no Harper lints.
|
||||
contract TestContract {
|
||||
/// This is a test function.
|
||||
/// It has a [link](https://example.com) embedded inside
|
||||
function testFunction() external {}
|
||||
|
||||
/**
|
||||
* @notice This is another test function.
|
||||
* @dev It has another [link](https://example.com) embedded inside
|
||||
* @param p This is a parameter
|
||||
* @return fooBar The return value.
|
||||
*/
|
||||
function testFunction2(uint256 p) external returns (address fooBar) {}
|
||||
|
||||
// This is some gibberish to try to trigger a lint for sentences that continue for too long
|
||||
//
|
||||
// This is some gibberish to try to trigger a lint for sentences that continue for too long
|
||||
//
|
||||
// This is some gibberish to try to trigger a lint for sentences that continue for too long
|
||||
//
|
||||
// This is some gibberish to try to trigger a lint for sentences that continue for too long
|
||||
//
|
||||
// This is some gibberish to try to trigger a lint for sentences that continue for too long
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
/// spellcheck:ignore splling error
|
||||
/// Ths applies to the entire comment block
|
||||
contract Testing {
|
||||
// spellchecker: ignore ths contrat isnt done yt
|
||||
uint256 internal foo;
|
||||
|
||||
/// Ths comment block is checked
|
||||
function test() external {}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
/// This is an example of an problematic comment.
|
||||
/// It should produce one error.
|
||||
contract Test {}
|
||||
|
||||
/**
|
||||
* This is an example of a possible error:
|
||||
* these subsequent lines should not be considered a new sentence and should
|
||||
* produce no errors.
|
||||
*/
|
||||
library FooBar {}
|
||||
|
||||
/// Let's aadd a cuple spelling errors for good measure.
|
||||
@@ -9,8 +9,8 @@ repository = "https://github.com/automattic/harper"
|
||||
[dependencies]
|
||||
harper-core = { path = "../harper-core", version = "0.44.0" }
|
||||
harper-tree-sitter = { path = "../harper-tree-sitter", version = "0.44.0" }
|
||||
tree-sitter-html = "0.19.0"
|
||||
tree-sitter = "0.20.10"
|
||||
tree-sitter-html = "0.23.2"
|
||||
tree-sitter = "0.25.6"
|
||||
|
||||
[dev-dependencies]
|
||||
paste = "1.0.15"
|
||||
|
||||
@@ -18,7 +18,7 @@ impl Default for HtmlParser {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
inner: parsers::Mask::new(
|
||||
TreeSitterMasker::new(tree_sitter_html::language(), Self::node_condition),
|
||||
TreeSitterMasker::new(tree_sitter_html::LANGUAGE.into(), Self::node_condition),
|
||||
PlainEnglish,
|
||||
),
|
||||
}
|
||||
|
||||
@@ -8,4 +8,4 @@ repository = "https://github.com/automattic/harper"
|
||||
|
||||
[dependencies]
|
||||
harper-core = { path = "../harper-core", version = "0.44.0" }
|
||||
tree-sitter = "0.20.10"
|
||||
tree-sitter = "0.25.6"
|
||||
|
||||
@@ -20,7 +20,7 @@ impl TreeSitterMasker {
|
||||
|
||||
fn parse_root(&self, text: &str) -> Option<Tree> {
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
parser.set_language(self.language).unwrap();
|
||||
parser.set_language(&self.language).unwrap();
|
||||
|
||||
// TODO: Use incremental parsing
|
||||
parser.parse(text, None)
|
||||
@@ -39,7 +39,7 @@ impl TreeSitterMasker {
|
||||
}
|
||||
});
|
||||
|
||||
byte_spans_to_char_spans(&mut ident_spans, &text);
|
||||
let ident_spans = byte_spans_to_char_spans(ident_spans, &text);
|
||||
|
||||
let mut idents = HashSet::new();
|
||||
|
||||
@@ -101,7 +101,7 @@ impl Masker for TreeSitterMasker {
|
||||
let mut comments_spans = Vec::new();
|
||||
|
||||
self.extract_comments(&mut root.walk(), &mut comments_spans);
|
||||
byte_spans_to_char_spans(&mut comments_spans, &text);
|
||||
let comments_spans = byte_spans_to_char_spans(comments_spans, &text);
|
||||
|
||||
let mut mask = Mask::new_blank();
|
||||
|
||||
@@ -115,29 +115,29 @@ impl Masker for TreeSitterMasker {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a set of byte-indexed [`Span`]s to char-index Spans, in-place.
|
||||
/// Converts a set of byte-indexed [`Span`]s to char-index Spans and returns them.
|
||||
/// NOTE: Will sort the given slice by their [`Span::start`].
|
||||
///
|
||||
/// If any spans overlap, it will remove the second one.
|
||||
fn byte_spans_to_char_spans(byte_spans: &mut Vec<Span>, source: &str) {
|
||||
byte_spans.sort_by_key(|s| s.start);
|
||||
/// If any spans overlap, it will merge them.
|
||||
fn byte_spans_to_char_spans(mut byte_spans: Vec<Span>, source: &str) -> Vec<Span> {
|
||||
byte_spans.sort_unstable_by_key(|s| s.start);
|
||||
|
||||
let cloned = byte_spans.clone();
|
||||
|
||||
let mut i: usize = 0;
|
||||
byte_spans.retain(|cur| {
|
||||
i += 1;
|
||||
if let Some(prev) = cloned.get(i.wrapping_sub(2)) {
|
||||
!cur.overlaps_with(*prev)
|
||||
} else {
|
||||
true
|
||||
// merge overlapping spans
|
||||
let mut spans = Vec::with_capacity(byte_spans.len());
|
||||
for span in byte_spans {
|
||||
match spans.last_mut() {
|
||||
Some(last) if !span.overlaps_with(*last) => spans.push(span),
|
||||
Some(last) => {
|
||||
// ranges overlap, we can merge them
|
||||
last.end = span.end;
|
||||
}
|
||||
None => spans.push(span),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let mut last_byte_pos = 0;
|
||||
let mut last_char_pos = 0;
|
||||
|
||||
byte_spans.iter_mut().for_each(|span| {
|
||||
spans.iter_mut().for_each(|span| {
|
||||
let byte_span = *span;
|
||||
|
||||
last_char_pos += source[last_byte_pos..byte_span.start].chars().count();
|
||||
@@ -147,5 +147,6 @@ fn byte_spans_to_char_spans(byte_spans: &mut Vec<Span>, source: &str) {
|
||||
span.end = last_char_pos;
|
||||
|
||||
last_byte_pos = byte_span.end;
|
||||
})
|
||||
});
|
||||
spans
|
||||
}
|
||||
|
||||
52
justfile
52
justfile
@@ -10,7 +10,7 @@ build-wasm:
|
||||
|
||||
# Build `harper.js` with all size optimizations available.
|
||||
build-harperjs: build-wasm
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
# Removes a duplicate copy of the WASM binary if Vite is left to its devices.
|
||||
@@ -24,7 +24,7 @@ build-harperjs: build-wasm
|
||||
./docs.sh
|
||||
|
||||
test-harperjs: build-harperjs
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
pnpm install
|
||||
@@ -37,7 +37,7 @@ test-harperjs: build-harperjs
|
||||
pnpm start
|
||||
|
||||
test-obsidian: build-obsidian
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
pnpm install
|
||||
@@ -45,7 +45,7 @@ test-obsidian: build-obsidian
|
||||
pnpm test
|
||||
|
||||
dev-wp: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
@@ -56,7 +56,7 @@ dev-wp: build-harperjs
|
||||
|
||||
# Build the WordPress plugin
|
||||
build-wp: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd "{{justfile_directory()}}/packages/wordpress-plugin"
|
||||
@@ -66,7 +66,7 @@ build-wp: build-harperjs
|
||||
|
||||
# Compile the website's dependencies and start a development server. Note that if you make changes to `harper-wasm`, you will have to re-run this command.
|
||||
dev-web: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd "{{justfile_directory()}}/packages/web"
|
||||
@@ -75,7 +75,7 @@ dev-web: build-harperjs
|
||||
|
||||
# Build the Harper website.
|
||||
build-web: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd "{{justfile_directory()}}/packages/web"
|
||||
@@ -84,7 +84,7 @@ build-web: build-harperjs
|
||||
|
||||
# Build the Harper Obsidian plugin.
|
||||
build-obsidian: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd "{{justfile_directory()}}/packages/obsidian-plugin"
|
||||
@@ -96,7 +96,7 @@ build-obsidian: build-harperjs
|
||||
|
||||
# Build the Chrome extension.
|
||||
build-chrome-plugin: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd "{{justfile_directory()}}/packages/chrome-plugin"
|
||||
@@ -106,7 +106,7 @@ build-chrome-plugin: build-harperjs
|
||||
|
||||
# Start a development server for the Chrome extension.
|
||||
dev-chrome-plugin: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd "{{justfile_directory()}}/packages/chrome-plugin"
|
||||
@@ -116,7 +116,7 @@ dev-chrome-plugin: build-harperjs
|
||||
|
||||
# Build the Firefox extension.
|
||||
build-firefox-plugin: build-harperjs
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd "{{justfile_directory()}}/packages/chrome-plugin"
|
||||
@@ -125,7 +125,7 @@ build-firefox-plugin: build-harperjs
|
||||
pnpm zip-for-firefox
|
||||
|
||||
test-chrome-plugin: build-chrome-plugin
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
pnpm install
|
||||
@@ -135,7 +135,7 @@ test-chrome-plugin: build-chrome-plugin
|
||||
|
||||
# Run VSCode plugin unit and integration tests.
|
||||
test-vscode:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
ext_dir="{{justfile_directory()}}/packages/vscode-plugin"
|
||||
@@ -162,7 +162,7 @@ test-vscode:
|
||||
# Build and package the Visual Studio Code extension.
|
||||
# If `target` is passed, it is assumed that `harper-ls` has been compiled beforehand and is in `packages/vscode-plugin/bin`. This is used in CI.
|
||||
package-vscode target="":
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
ext_dir="{{justfile_directory()}}/packages/vscode-plugin"
|
||||
@@ -190,7 +190,7 @@ package-vscode target="":
|
||||
fi
|
||||
|
||||
update-vscode-linters:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
linters=$(
|
||||
@@ -223,7 +223,7 @@ update-vscode-linters:
|
||||
|
||||
# Run Rust formatting and linting.
|
||||
check-rust:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cargo fmt -- --check
|
||||
@@ -231,7 +231,7 @@ check-rust:
|
||||
|
||||
# Perform format and type checking.
|
||||
check: check-rust build-web
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
pnpm install
|
||||
@@ -246,7 +246,7 @@ setup: build-harperjs test-harperjs test-vscode build-web build-wp build-obsidia
|
||||
|
||||
# Perform full format and type checking, build all projects and run all tests. Run this before pushing your code.
|
||||
precommit: check test build-harperjs build-obsidian build-web build-wp build-firefox-plugin build-chrome-plugin
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cargo build --all-targets
|
||||
@@ -259,7 +259,7 @@ install:
|
||||
|
||||
# Run `harper-cli` on the Harper repository
|
||||
dogfood:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
cargo build --release
|
||||
for file in `fd -e rs`
|
||||
do
|
||||
@@ -285,7 +285,7 @@ spans file:
|
||||
|
||||
# Add a noun to Harper's curated dictionary.
|
||||
addnoun noun:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
DICT_FILE=./harper-core/dictionary.dict
|
||||
|
||||
cat $DICT_FILE | grep "^{{noun}}/"
|
||||
@@ -314,7 +314,7 @@ addnoun noun:
|
||||
|
||||
# Search Harper's curated dictionary for a specific word
|
||||
searchdictfor word:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
if command -v rg > /dev/null; then
|
||||
cargo run --bin harper-cli -- words | rg {{word}}
|
||||
else
|
||||
@@ -323,7 +323,7 @@ searchdictfor word:
|
||||
|
||||
# Find words in the user's `harper-ls/dictionary.txt` for words already in the curated dictionary.
|
||||
userdictoverlap:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
USER_DICT_FILE="$HOME/.config/harper-ls/dictionary.txt"
|
||||
|
||||
while read -r line; do
|
||||
@@ -338,7 +338,7 @@ getforms word:
|
||||
cargo run --bin harper-cli -- forms {{word}}
|
||||
# Get a random sample of words from Harper's dictionary and list all forms of each.
|
||||
sampleforms count:
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
DICT_FILE=./harper-core/dictionary.dict
|
||||
# USER_DICT_FILE="$HOME/.config/harper-ls/dictionary.txt"
|
||||
@@ -364,7 +364,7 @@ sampleforms count:
|
||||
cargo run --bin harper-cli -- forms $words
|
||||
|
||||
bump-versions: update-vscode-linters
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cargo ws version --no-git-push --no-git-tag --force '*'
|
||||
@@ -397,7 +397,7 @@ bump-versions: update-vscode-linters
|
||||
|
||||
# Enter an infinite loop of property testing until a bug is found.
|
||||
fuzz:
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
while true
|
||||
do
|
||||
@@ -408,7 +408,7 @@ fuzz:
|
||||
done
|
||||
|
||||
registerlinter module name:
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
D="{{justfile_directory()}}/harper-core/src/linting"
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
"onLanguage:cmake",
|
||||
"onLanguage:cpp",
|
||||
"onLanguage:csharp",
|
||||
"onLanguage:dart",
|
||||
"onLanguage:git-commit",
|
||||
"onLanguage:go",
|
||||
"onLanguage:haskell",
|
||||
@@ -41,6 +40,7 @@
|
||||
"onLanguage:literate haskell",
|
||||
"onLanguage:lua",
|
||||
"onLanguage:markdown",
|
||||
"onLanguage:dart",
|
||||
"onLanguage:nix",
|
||||
"onLanguage:php",
|
||||
"onLanguage:plaintext",
|
||||
@@ -48,6 +48,7 @@
|
||||
"onLanguage:ruby",
|
||||
"onLanguage:rust",
|
||||
"onLanguage:shellscript",
|
||||
"onLanguage:solidity",
|
||||
"onLanguage:swift",
|
||||
"onLanguage:toml",
|
||||
"onLanguage:typescript",
|
||||
|
||||
7
packages/vscode-plugin/src/tests/fixtures/languages/solidity.sol
vendored
Normal file
7
packages/vscode-plugin/src/tests/fixtures/languages/solidity.sol
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
/// Errorz
|
||||
contract Test {
|
||||
uint256 internal test;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ describe('Languages >', () => {
|
||||
// Uncomment when #265 is fixed.
|
||||
// { type: 'JavaScript JSX', file: 'javascriptreact.jsx', row: 1, column: 36 },
|
||||
|
||||
// VS Code doesn't support CMake, Haskell, Literate Haskell, Nix, TOML, and Typst files out of
|
||||
// VS Code doesn't support CMake, Haskell, Literate Haskell, Nix, Solidity, TOML, and Typst files out of
|
||||
// the box. Uncomment when you figure out how to support them during testing.
|
||||
// { type: 'CMake', file: 'CMakeLists.txt', row: 2, column: 30 },
|
||||
// { type: 'Haskell', file: 'haskell.hs', row: 1, column: 3 },
|
||||
@@ -23,6 +23,7 @@ describe('Languages >', () => {
|
||||
// { type: 'Nix', file: 'nix.nix', row: 1, column: 2 },
|
||||
// { type: 'TOML', file: 'toml.toml', row: 1, column: 2 },
|
||||
// { type: 'Typst', file: 'typst.typ', row: 2, column: 1 },
|
||||
// { type: 'Solidity', file: 'solidity.sol', row: 3, column: 4 },
|
||||
|
||||
{ type: 'C', file: 'c.c', row: 2, column: 3 },
|
||||
{ type: 'C++', file: 'cpp.cpp', row: 3, column: 5 },
|
||||
|
||||
@@ -282,6 +282,7 @@ These configs are under the `markdown` key:
|
||||
| Rust | `rust` | ✅ |
|
||||
| Scala | `scala` | ✅ |
|
||||
| Shell/Bash Script | `shellscript` | ✅ |
|
||||
| Solidity | `solidity` | ✅ |
|
||||
| Swift | `swift` | ✅ |
|
||||
| TOML | `toml` | ✅ |
|
||||
| TypeScript | `typescript` | ✅ |
|
||||
|
||||
Reference in New Issue
Block a user