crate dos to md-book (#6)
Some checks are pending
rust-clippy analyze / Run rust-clippy analyzing (push) Waiting to run
Deploy mdBook site to Pages / build (x86_64-unknown-linux-gnu, stable) (push) Waiting to run
Deploy mdBook site to Pages / deploy (push) Blocked by required conditions
Rust / build (src-lang, wasm32-unknown-unknown, nightly) (push) Waiting to run
Rust / build (src-lang, wasm32-unknown-unknown, stable) (push) Waiting to run
Rust / build (src-lang, x86_64-unknown-linux-gnu, nightly) (push) Waiting to run
Rust / build (src-lang, x86_64-unknown-linux-gnu, stable) (push) Waiting to run

Reviewed-on: #6
This commit is contained in:
sevki 2024-07-17 03:54:49 +00:00
parent fdf0b9e89f
commit 8ef278eaa3
37 changed files with 2568 additions and 1221 deletions

View file

@ -35,8 +35,6 @@ jobs:
matrix:
targets:
- x86_64-unknown-linux-gnu
packages:
- srclang
toolchains:
- stable
@ -60,6 +58,10 @@ jobs:
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: build_docs
run: |
cargo doc
cargo build
- name: Build with mdBook
run: mdbook build
- name: Build the ide

View file

@ -19,8 +19,9 @@ jobs:
matrix:
targets:
- x86_64-unknown-linux-gnu
- wasm32-unknown-unknown
packages:
- srclang
- src-lang
toolchains:
- stable
- nightly

2
.gitignore vendored
View file

@ -5,3 +5,5 @@ packages/app/assets/wasm/src_lsp_browser.d.ts
packages/app/assets/wasm/src_lsp_browser.js
packages/app/assets/wasm/src_lsp_browser_bg.wasm
packages/app/assets/wasm/src_lsp_browser_bg.wasm.d.ts
docs/crates/src_*

715
Cargo.lock generated
View file

@ -44,6 +44,61 @@ version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "any_ascii"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70033777eb8b5124a81a1889416543dddef2de240019b674c81285a2635a7e1e"
[[package]]
name = "anyhow"
version = "1.0.86"
@ -140,6 +195,15 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bit-set"
version = "0.5.3"
@ -179,6 +243,16 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
[[package]]
name = "caseless"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808dab3318747be122cb31d36de18d4d1c81277a76f8332a02b81a3d73463d7f"
dependencies = [
"regex",
"unicode-normalization",
]
[[package]]
name = "cc"
version = "1.1.5"
@ -191,6 +265,53 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
"terminal_size",
]
[[package]]
name = "clap_derive"
version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.71",
]
[[package]]
name = "clap_lex"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]]
name = "colorchoice"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "colored"
version = "1.9.4"
@ -212,6 +333,27 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "comrak"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ab67843c57df5a4ee29d610740828dbc928cc64ecf0f2a1d5cd0e98e107a9"
dependencies = [
"caseless",
"clap",
"derive_builder",
"entities",
"memchr",
"once_cell",
"regex",
"shell-words",
"slug",
"syntect",
"typed-arena",
"unicode_categories",
"xdg",
]
[[package]]
name = "console"
version = "0.15.8"
@ -331,6 +473,41 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "darling"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.71",
]
[[package]]
name = "darling_macro"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn 2.0.71",
]
[[package]]
name = "dashmap"
version = "5.5.3"
@ -344,6 +521,52 @@ dependencies = [
"parking_lot_core",
]
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
]
[[package]]
name = "derive_builder"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.71",
]
[[package]]
name = "derive_builder_macro"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
dependencies = [
"derive_builder_core",
"syn 2.0.71",
]
[[package]]
name = "deunicode"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00"
[[package]]
name = "diff"
version = "0.1.13"
@ -401,6 +624,12 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "entities"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca"
[[package]]
name = "equivalent"
version = "1.0.1"
@ -433,6 +662,16 @@ dependencies = [
"once_cell",
]
[[package]]
name = "fancy-regex"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
dependencies = [
"bit-set",
"regex",
]
[[package]]
name = "fastrand"
version = "2.1.0"
@ -464,6 +703,16 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -479,6 +728,16 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "futf"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843"
dependencies = [
"mac",
"new_debug_unreachable",
]
[[package]]
name = "futures"
version = "0.3.30"
@ -596,6 +855,12 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -627,6 +892,12 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.3.9"
@ -639,12 +910,43 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "html5ever"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4"
dependencies = [
"log",
"mac",
"markup5ever",
"proc-macro2",
"quote",
"syn 2.0.71",
]
[[package]]
name = "html_to_markdown"
version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#868455f9782a50c2ed05c7a25a52f41bfc8f9f4d"
dependencies = [
"anyhow",
"html5ever",
"markup5ever_rcdom",
"regex",
]
[[package]]
name = "httparse"
version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.5.0"
@ -669,6 +971,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
"serde",
]
[[package]]
@ -710,6 +1013,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]]
name = "itertools"
version = "0.11.0"
@ -771,6 +1080,15 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lexical-sort"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c09e4591611e231daf4d4c685a66cb0410cc1e502027a20ae55f2bb9e997207a"
dependencies = [
"any_ascii",
]
[[package]]
name = "libc"
version = "0.2.155"
@ -846,6 +1164,38 @@ dependencies = [
"url",
]
[[package]]
name = "mac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "markup5ever"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45"
dependencies = [
"log",
"phf",
"phf_codegen 0.11.2",
"string_cache",
"string_cache_codegen",
"tendril",
]
[[package]]
name = "markup5ever_rcdom"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edaa21ab3701bfee5099ade5f7e1f84553fd19228cf332f13cd6e964bf59be18"
dependencies = [
"html5ever",
"markup5ever",
"tendril",
"xml5ever",
]
[[package]]
name = "memchr"
version = "2.7.4"
@ -878,6 +1228,12 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-traits"
version = "0.2.19"
@ -950,6 +1306,28 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "onig"
version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
dependencies = [
"bitflags 1.3.2",
"libc",
"once_cell",
"onig_sys",
]
[[package]]
name = "onig_sys"
version = "69.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "parking_lot"
version = "0.12.3"
@ -995,14 +1373,33 @@ dependencies = [
"indexmap 2.2.6",
]
[[package]]
name = "phf"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
"phf_shared 0.11.2",
]
[[package]]
name = "phf_codegen"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
dependencies = [
"phf_generator",
"phf_shared",
"phf_generator 0.10.0",
"phf_shared 0.10.0",
]
[[package]]
name = "phf_codegen"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
dependencies = [
"phf_generator 0.11.2",
"phf_shared 0.11.2",
]
[[package]]
@ -1011,7 +1408,17 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
dependencies = [
"phf_shared",
"phf_shared 0.10.0",
"rand",
]
[[package]]
name = "phf_generator"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
dependencies = [
"phf_shared 0.11.2",
"rand",
]
@ -1024,6 +1431,15 @@ dependencies = [
"siphasher",
]
[[package]]
name = "phf_shared"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.5.0"
@ -1062,6 +1478,31 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "plist"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
dependencies = [
"base64",
"indexmap 2.2.6",
"quick-xml",
"serde",
"time",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -1143,6 +1584,15 @@ version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quick-xml"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2"
dependencies = [
"memchr",
]
[[package]]
name = "quote"
version = "1.0.36"
@ -1193,9 +1643,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.2"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
dependencies = [
"bitflags 2.6.0",
]
@ -1262,6 +1712,19 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustdoc-to-markdown"
version = "0.1.0"
dependencies = [
"anyhow",
"html_to_markdown",
"indexmap 1.9.3",
"indoc",
"pretty_assertions",
"serde",
"strum",
]
[[package]]
name = "rustix"
version = "0.38.34"
@ -1325,7 +1788,7 @@ source = "registry+https://ok.software/ok/_cargo-index.git"
checksum = "df076c3acde46611a88aae39e80660165369e6a86b6d9a0ebac2e4789a932a67"
dependencies = [
"eyre",
"heck",
"heck 0.4.1",
"proc-macro2",
"quote",
"syn 1.0.109",
@ -1388,6 +1851,12 @@ dependencies = [
"syn 2.0.71",
]
[[package]]
name = "shell-words"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
@ -1418,6 +1887,16 @@ dependencies = [
"autocfg",
]
[[package]]
name = "slug"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4"
dependencies = [
"deunicode",
"wasm-bindgen",
]
[[package]]
name = "smallvec"
version = "1.13.2"
@ -1461,7 +1940,34 @@ version = "0.1.0"
dependencies = [
"okstd",
"src-derive",
"srclang",
"src-lang",
]
[[package]]
name = "src-lang"
version = "0.1.0"
dependencies = [
"anyhow",
"bitflags 2.6.0",
"comrak",
"getrandom",
"glob",
"hashbrown 0.14.5",
"insta",
"lalrpop",
"lalrpop-util",
"lexical-sort",
"okstd",
"paste",
"phf_codegen 0.10.0",
"proptest",
"ropey",
"rustdoc-to-markdown",
"salsa-2022",
"salsa-2022-macros",
"src-derive",
"syn 2.0.71",
"tiny-keccak",
]
[[package]]
@ -1471,8 +1977,8 @@ dependencies = [
"console_error_panic_hook",
"futures",
"js-sys",
"src-lang",
"src-lsp-server",
"srclang",
"tower-lsp",
"wasm-bindgen",
"wasm-bindgen-futures",
@ -1500,7 +2006,7 @@ dependencies = [
"salsa-2022-macros",
"serde_json",
"src-collections",
"srclang",
"src-lang",
"thiserror",
"tower-lsp",
"wasm-bindgen",
@ -1509,29 +2015,6 @@ dependencies = [
"web-sys",
]
[[package]]
name = "srclang"
version = "0.1.0"
dependencies = [
"anyhow",
"bitflags 2.6.0",
"getrandom",
"hashbrown 0.14.5",
"insta",
"lalrpop",
"lalrpop-util",
"okstd",
"paste",
"phf_codegen",
"proptest",
"ropey",
"salsa-2022",
"salsa-2022-macros",
"src-derive",
"syn 2.0.71",
"tiny-keccak",
]
[[package]]
name = "str_indices"
version = "0.4.3"
@ -1547,8 +2030,49 @@ dependencies = [
"new_debug_unreachable",
"once_cell",
"parking_lot",
"phf_shared",
"phf_shared 0.10.0",
"precomputed-hash",
"serde",
]
[[package]]
name = "string_cache_codegen"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
dependencies = [
"phf_generator 0.10.0",
"phf_shared 0.10.0",
"proc-macro2",
"quote",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.71",
]
[[package]]
@ -1573,6 +2097,29 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "syntect"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1"
dependencies = [
"bincode",
"bitflags 1.3.2",
"fancy-regex",
"flate2",
"fnv",
"once_cell",
"onig",
"plist",
"regex-syntax",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"walkdir",
"yaml-rust",
]
[[package]]
name = "tempfile"
version = "3.10.1"
@ -1585,6 +2132,17 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "tendril"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0"
dependencies = [
"futf",
"mac",
"utf-8",
]
[[package]]
name = "term"
version = "0.7.0"
@ -1605,6 +2163,16 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
dependencies = [
"rustix",
"windows-sys 0.48.0",
]
[[package]]
name = "thiserror"
version = "1.0.62"
@ -1625,6 +2193,37 @@ dependencies = [
"syn 2.0.71",
]
[[package]]
name = "time"
version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
@ -1738,6 +2337,12 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "typed-arena"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
[[package]]
name = "typed-index-collections"
version = "3.1.0"
@ -1783,6 +2388,12 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "unicode_categories"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "url"
version = "2.5.2"
@ -1795,6 +2406,18 @@ dependencies = [
"serde",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "version_check"
version = "0.9.4"
@ -2086,6 +2709,32 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "xdg"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
[[package]]
name = "xml5ever"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bbb26405d8e919bc1547a5aa9abc95cbfa438f04844f5fdd9dc7596b748bf69"
dependencies = [
"log",
"mac",
"markup5ever",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "yansi"
version = "0.5.1"

View file

@ -1,15 +1,16 @@
[package]
name = "srclang"
name = "src-lang"
version = "0.1.0"
edition = "2021"
[workspace]
members = [
"crates/src-collections",
"crates/src-derive",
"crates/src-derive-test",
"crates/src-lsp-browser",
"crates/src-lsp-server",
"crates/rustdoc-to-markdown",
"crates/src-collections",
"crates/src-derive",
"crates/src-derive-test",
"crates/src-lsp-browser",
"crates/src-lsp-server",
]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -21,6 +22,10 @@ lalrpop = { version = "0.20.2", optional = true }
anyhow = "1.0.45"
phf_codegen = "0.10"
tiny-keccak = { version = "2", features = ["sha3"] }
rustdoc-to-markdown = { version = "0.1.0", path = "crates/rustdoc-to-markdown", registry = "oksoftware" }
glob = "0.3.1"
comrak = "0.26.0"
lexical-sort = "0.3.1"
[dependencies]
getrandom = { version = "0.2", features = ["js"] }
@ -28,7 +33,7 @@ salsa = { version = "0.1.0", registry = "oksoftware", package = "salsa-2022" }
salsa-macros = { version = "0.1.0", registry = "oksoftware", package = "salsa-2022-macros" }
lalrpop-util = { version = "0.20.2", features = ["lexer", "unicode"] }
okstd = { features = [
"macros",
"macros",
], default-features = false, registry = "oksoftware", version = "0.1.9" }
syn = "2.0.60"
bitflags = "2.5.0"

View file

@ -3,7 +3,7 @@ authors = ["@sevki"]
language = "en"
multilingual = true
src = "docs"
create-missing = false
# additional css https://raw.githubusercontent.com/oknotokcomputer/okcss/main/ok.css
[output.html]
additional-css = ["ok.css", "skill-tree.css"]
@ -11,7 +11,9 @@ theme = "docs/theme"
default-theme = "dark"
git-repository-url = "https://ok.software/ok/src"
preferred-dark-theme = "rust"
additional-js =["viz.js", "full.render.js", "panzoom.min.js", "skill-tree.js"]
additional-js = ["viz.js", "full.render.js", "panzoom.min.js", "skill-tree.js"]
no-section-label = false
create-missing = false
# [preprocessor.svgbob]

289
build.rs
View file

@ -1,8 +1,14 @@
use core::panic;
use std::fmt::Write as _;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
use comrak::nodes::{Ast, AstNode, NodeValue};
use comrak::{format_html, parse_document, Arena, Options};
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::error::Error;
use std::ffi::OsString;
use std::fmt::{format, Write as _};
use std::fs::{self, File};
use std::io::{BufRead, BufReader, Read, Write};
use std::os;
use std::path::{Component, PathBuf};
use tiny_keccak::{Hasher, Sha3};
const SOURCE: &str = "src/parser/src.lalrpop";
@ -13,6 +19,8 @@ fn main() -> anyhow::Result<()> {
try_lalrpop(SOURCE, TARGET)?;
try_write_down_versions_info()?;
try_make_books()?;
Ok(())
}
@ -99,3 +107,274 @@ fn sha_equal(expected_sha3_str: &str, actual_sha3: &[u8; 32]) -> bool {
}
*actual_sha3 == expected_sha3
}
fn try_write_down_versions_info() -> std::result::Result<(), std::io::Error> {
// get git commit hash
let commit_hash = std::process::Command::new("git")
.args(&["rev-parse", "HEAD"])
.output()
.expect("failed to execute git")
.stdout;
// get version or tag
let version = std::process::Command::new("git")
.args(&["describe", "--tags", "--always"])
.output()
.expect("failed to execute git")
.stdout;
// write to file
let mut file = File::create("versions.txt")?;
file.write_all(b"commit: ")?;
file.write_all(&commit_hash)?;
file.write_all(b"version: ")?;
file.write_all(&version)?;
Ok(())
}
fn try_make_books() -> std::result::Result<(), std::io::Error> {
// open index.html from target/doc/*/index.html
// CARGO_BUILD_TARGET_DIR
let target_dir = "target";
let docs_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join(target_dir)
.join("doc");
let mut org_docs = [
"0intro.md",
"language/0intro.md",
"examples.md",
"playground/index.md",
"skill-tree.md",
"research.md",
"crates/index.md",
]
.map(|s| PathBuf::from(s))
.to_vec();
let mut docs: Vec<_> =
glob::glob(format!("{}/**/*.html", docs_path.as_path().to_string_lossy()).as_str())
.expect("Failed to read glob pattern")
.map(|entry| entry.unwrap())
.collect();
docs.sort_unstable();
let mut docs = docs.iter().flat_map(|entry| {
let full_path = entry.as_path();
let last = full_path.with_extension("md");
if last.ends_with("all.md")
// || full_path.ends_with("index.md")
{
return None;
}
// make it relative to docs_path
let last = last.strip_prefix(docs_path.clone()).unwrap();
let base_name: Vec<_> = last.components().map(|c| c.as_os_str()).collect();
let base_name = base_name[..base_name.len() - 1]
.into_iter()
.flat_map(|c| c.to_str())
.collect::<Vec<&str>>()
.join("/");
if !base_name.as_str().starts_with("src_lang")
&& !base_name.as_str().starts_with("src_derive")
{
return None;
}
let outpath = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("docs/crates/")
.join(last);
let target_base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("docs/crates/")
.join(base_name.clone());
// if basename doesn't exist mkdir -p it into existence
if fs::read_dir(target_base_path.clone()).is_err() {
fs::create_dir_all(target_base_path.clone()).expect("mkdir -p");
}
let html =
File::open(full_path).expect(format!("index.html not found: {:?}", full_path).as_str());
let reso = rustdoc_to_markdown::convert_rustdoc_to_markdown(html);
let reso = reso.unwrap();
let md = reso.0;
// lets do some simple replacements.
// we should have here a set of transformers that are fn(&mut str)
std::fs::write(outpath.clone(), md).expect("book");
let rel_path: PathBuf = outpath
.strip_prefix(concat!(env!("CARGO_MANIFEST_DIR"), "/docs/"))
.unwrap()
.into();
Some(rel_path)
});
let mut docs = docs.collect::<Vec<_>>();
docs.sort_unstable();
docs.sort_by(|a, b| {
// strip index.md from the end for both a and b
let a = a
.to_str()
.unwrap_or("")
.strip_suffix("index.md")
.unwrap_or(a.to_str().unwrap());
let b = b
.to_str()
.unwrap_or("")
.strip_suffix("index.md")
.unwrap_or(b.to_str().unwrap());
a.cmp(b)
});
// org_docs.append(&mut docs);
// let mut docs = org_docs;
// docs.sort_unstable();
let mut file = File::create("docs/SUMMARY.md")?;
let write_docs = |docs: Vec<PathBuf>, mut file: File, indent: usize| -> Option<File> {
let docs = docs.into_iter().map(|doc| PathBuf::from(doc));
for doc in docs {
let components = doc.components();
let count = components.clone().count();
// first print components.len() - 1 tabs
// then print the last component
let a = components.collect::<Vec<_>>();
let a = a[0..count].iter().map(|c| c.as_os_str().to_str().unwrap());
let name = a.map(|f| f.to_string()).collect::<Vec<String>>();
let full_path =
env!("CARGO_MANIFEST_DIR").to_string() + "/docs/" + doc.to_str().unwrap();
let mut title = get_title(full_path.as_str());
if !full_path.ends_with("playground/index.md") && title.is_empty() {
println!("title is empty for: {:?}", full_path);
continue;
}
if full_path.ends_with("playground/index.md") {
title = "src Playground".to_string();
}
for c in name.iter().enumerate() {
let header_level = c.0;
for _ in 3..header_level {
// write!(file, "\t")?;
}
if c.0 == name.len() - 1 {
break;
}
// write!(
// file,
// "- [{}](#?{})\n",
// title[count - 1],
// title[0..count - 1].join("/")
// )?;
}
let title_splat = title.split(" ");
let firstbit = title_splat.clone().next().unwrap();
let lastbit = title_splat.clone().last().unwrap();
let lastbit_splat = lastbit.split("::");
let lastbit_count = lastbit_splat.clone().count();
for _ in 0..lastbit_count - 1 + indent {
write!(file, "\t").unwrap_or(())
}
let ti = if lastbit_count == 1 {
title.clone()
} else {
lastbit_splat.last().unwrap().to_string()
};
let icon = match firstbit {
"Struct" => r#"℘"#,
"Enum" => "",
"Trait" => "",
"Function" => "𝑓",
"Type" => "τ",
"Macro" => "",
"Constant" => "𝑐",
"Module" => "",
"Crate" => "",
"Crates" => "🦀",
_ => "",
};
writeln!(file, "- [{} {}]({})", icon, ti, doc.to_str().unwrap()).unwrap_or(());
}
Some(file)
};
write_docs(docs, write_docs(org_docs, file, 0).unwrap(), 1).unwrap();
Ok(())
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct ItemPath {
components: Vec<String>,
}
impl PartialOrd for ItemPath {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
eprintln!("partial_cmp: {:?} {:?}", self, other);
for (a, b) in self.components.iter().zip(other.components.iter()) {
match a.cmp(b) {
Ordering::Equal => {
continue;
}
x => return Some(x),
}
}
None
}
}
impl Ord for ItemPath {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap_or(Ordering::Equal)
}
}
fn parsed_title(path: &str) -> Option<ItemPath> {
let title = get_title(path);
let title = title.split(" ").last().unwrap().split("::");
let components: Vec<_> = title.map(|c| c.to_string()).collect();
// filter out empty strings
let components: Vec<_> = components.into_iter().filter(|c| !c.is_empty()).collect();
if components.is_empty() {
return None;
}
Some(ItemPath { components })
}
fn parse_title(contents: &str) -> String {
let arena = Arena::new();
let root = parse_document(&arena, &contents, &Options::default());
let mut title = String::new();
for node in root.descendants() {
match node.data.borrow().value {
NodeValue::Heading(_) => {
let mut txt_buf = String::new();
for text_node in node.descendants() {
match text_node.data.borrow().value {
NodeValue::Text(ref text) => {
txt_buf.push_str(text);
}
_ => {}
}
}
title = txt_buf;
break;
}
_ => {}
}
}
title
}
fn get_title(path: &str) -> String {
let file = File::open(path).expect(format!("file not found: {:?}", path).as_str());
// read all the file
let mut reader = BufReader::new(file);
let mut contents = String::new();
reader.read_to_string(&mut contents).expect("read failed");
parse_title(&contents)
}

View file

@ -0,0 +1,14 @@
[package]
name = "rustdoc-to-markdown"
version = "0.1.0"
edition = "2021"
publish = ["oksoftware"]
[dependencies]
anyhow = "1.0.86"
html_to_markdown = { git = "https://github.com/zed-industries/zed" }
indexmap = { version = "1.6.2", features = ["serde"] }
pretty_assertions = "1.4.0"
serde = { version = "1.0.204", features = ["derive"] }
strum = { version = "0.25.0", features = ["derive"] }
indoc = "1"

View file

@ -0,0 +1,82 @@
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use strum::EnumIter;
#[derive(
Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize, EnumIter,
)]
#[serde(rename_all = "snake_case")]
pub enum RustdocItemKind {
Mod,
Macro,
Struct,
Enum,
Constant,
Trait,
Function,
TypeAlias,
AttributeMacro,
DeriveMacro,
}
impl RustdocItemKind {
pub(crate) const fn class(&self) -> &'static str {
match self {
Self::Mod => "mod",
Self::Macro => "macro",
Self::Struct => "struct",
Self::Enum => "enum",
Self::Constant => "constant",
Self::Trait => "trait",
Self::Function => "fn",
Self::TypeAlias => "type",
Self::AttributeMacro => "attr",
Self::DeriveMacro => "derive",
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
pub struct RustdocItem {
pub kind: RustdocItemKind,
/// The item path, up until the name of the item.
pub path: Vec<Arc<str>>,
/// The name of the item.
pub name: Arc<str>,
}
impl RustdocItem {
pub fn display(&self) -> String {
let mut path_segments = self.path.clone();
path_segments.push(self.name.clone());
path_segments.join("::")
}
pub fn url_path(&self) -> String {
let name = &self.name;
let mut path_components = self.path.clone();
match self.kind {
RustdocItemKind::Mod => {
path_components.push(name.clone());
path_components.push("index.html".into());
}
RustdocItemKind::Macro
| RustdocItemKind::Struct
| RustdocItemKind::Enum
| RustdocItemKind::Constant
| RustdocItemKind::Trait
| RustdocItemKind::Function
| RustdocItemKind::TypeAlias
| RustdocItemKind::AttributeMacro
| RustdocItemKind::DeriveMacro => {
path_components
.push(format!("{kind}.{name}.html", kind = self.kind.class()).into());
}
}
path_components.join("/")
}
}

View file

@ -0,0 +1,673 @@
pub mod item;
use std::cell::RefCell;
use std::io::Read;
use std::rc::Rc;
use anyhow::Result;
use html_to_markdown::markdown::{
// HeadingHandler,
ListHandler,
ParagraphHandler,
StyledTextHandler,
TableHandler,
};
use html_to_markdown::{
convert_html_to_markdown, HandleTag, HandlerOutcome, HtmlElement, MarkdownWriter,
StartTagOutcome, TagHandler,
};
use indexmap::IndexSet;
use strum::IntoEnumIterator;
use item::{RustdocItem, RustdocItemKind};
pub struct HeadingHandler;
impl HandleTag for HeadingHandler {
fn should_handle(&self, tag: &str) -> bool {
match tag {
"h1" | "h2" | "h3" | "h4" | "h5" | "h6" => true,
_ => false,
}
}
fn handle_tag_start(
&mut self,
tag: &HtmlElement,
writer: &mut MarkdownWriter,
) -> StartTagOutcome {
match tag.tag() {
"h1" => writer.push_str("\n\n# "),
"h2" => writer.push_str("\n\n## "),
"h3" => writer.push_str("\n\n### `"),
"h4" => writer.push_str("\n\n#### `"),
"h5" => writer.push_str("\n\n##### "),
"h6" => writer.push_str("\n\n###### "),
_ => {}
}
StartTagOutcome::Continue
}
fn handle_tag_end(&mut self, tag: &HtmlElement, writer: &mut MarkdownWriter) {
match tag.tag() {
"h3" | "h4" => {
writer.push_str("`");
writer.push_blank_line();
}
"h1" | "h2" | "h5" | "h6" => writer.push_blank_line(),
_ => {}
}
}
}
/// Converts the provided rustdoc HTML to Markdown.
pub fn convert_rustdoc_to_markdown(html: impl Read) -> Result<(String, Vec<RustdocItem>)> {
let item_collector = Rc::new(RefCell::new(RustdocItemCollector::new()));
let mut handlers: Vec<TagHandler> = vec![
Rc::new(RefCell::new(ParagraphHandler)),
Rc::new(RefCell::new(HeadingHandler)),
Rc::new(RefCell::new(ListHandler)),
Rc::new(RefCell::new(TableHandler::new())),
Rc::new(RefCell::new(StyledTextHandler)),
Rc::new(RefCell::new(RustdocChromeRemover)),
Rc::new(RefCell::new(RustdocHeadingHandler)),
Rc::new(RefCell::new(RustdocCodeHandler)),
Rc::new(RefCell::new(RustdocItemHandler)),
item_collector.clone(),
];
let markdown = convert_html_to_markdown(html, &mut handlers)?;
let items = item_collector
.borrow()
.items
.iter()
.cloned()
.collect::<Vec<_>>();
Ok((markdown, items))
}
pub struct RustdocHeadingHandler;
impl HandleTag for RustdocHeadingHandler {
fn should_handle(&self, _tag: &str) -> bool {
// We're only handling text, so we don't need to visit any tags.
false
}
fn handle_text(&mut self, text: &str, writer: &mut MarkdownWriter) -> HandlerOutcome {
if writer.is_inside("h1")
|| writer.is_inside("h2")
|| writer.is_inside("h3")
|| writer.is_inside("h4")
|| writer.is_inside("h5")
|| writer.is_inside("h6")
{
let text = text
.trim_matches(|char| char == '\n' || char == '\r')
.replace('\n', " ");
writer.push_str(&text);
return HandlerOutcome::Handled;
}
HandlerOutcome::NoOp
}
}
pub struct RustdocCodeHandler;
impl HandleTag for RustdocCodeHandler {
fn should_handle(&self, tag: &str) -> bool {
match tag {
"pre" | "code" => true,
_ => false,
}
}
fn handle_tag_start(
&mut self,
tag: &HtmlElement,
writer: &mut MarkdownWriter,
) -> StartTagOutcome {
match tag.tag() {
"code" => {
if !writer.is_inside("pre") {
writer.push_str("`");
}
}
"pre" => {
let classes = tag.classes();
let is_rust = classes.iter().any(|class| class == "rust");
let language = is_rust
.then(|| "rs")
.or_else(|| {
classes.iter().find_map(|class| {
if let Some((_, language)) = class.split_once("language-") {
Some(language.trim())
} else {
None
}
})
})
.unwrap_or("");
writer.push_str(&format!("\n\n```{language}\n"));
}
_ => {}
}
StartTagOutcome::Continue
}
fn handle_tag_end(&mut self, tag: &HtmlElement, writer: &mut MarkdownWriter) {
match tag.tag() {
"code" => {
if !writer.is_inside("pre") {
writer.push_str("`");
}
}
"pre" => writer.push_str("\n```\n"),
_ => {}
}
}
fn handle_text(&mut self, text: &str, writer: &mut MarkdownWriter) -> HandlerOutcome {
if writer.is_inside("pre") {
writer.push_str(&text);
return HandlerOutcome::Handled;
}
HandlerOutcome::NoOp
}
}
const RUSTDOC_ITEM_NAME_CLASS: &str = "item-name";
pub struct RustdocItemHandler;
impl RustdocItemHandler {
/// Returns whether we're currently inside of an `.item-name` element, which
/// rustdoc uses to display Rust items in a list.
fn is_inside_item_name(writer: &MarkdownWriter) -> bool {
writer
.current_element_stack()
.iter()
.any(|element| element.has_class(RUSTDOC_ITEM_NAME_CLASS))
}
}
impl HandleTag for RustdocItemHandler {
fn should_handle(&self, tag: &str) -> bool {
match tag {
"div" | "span" => true,
_ => false,
}
}
fn handle_tag_start(
&mut self,
tag: &HtmlElement,
writer: &mut MarkdownWriter,
) -> StartTagOutcome {
match tag.tag() {
"div" | "span" => {
if Self::is_inside_item_name(writer) && tag.has_class("stab") {
writer.push_str(" [");
}
}
_ => {}
}
StartTagOutcome::Continue
}
fn handle_tag_end(&mut self, tag: &HtmlElement, writer: &mut MarkdownWriter) {
match tag.tag() {
"div" | "span" => {
if tag.has_class(RUSTDOC_ITEM_NAME_CLASS) {
writer.push_str(": ");
}
if Self::is_inside_item_name(writer) && tag.has_class("stab") {
writer.push_str("]");
}
}
_ => {}
}
}
fn handle_text(&mut self, text: &str, writer: &mut MarkdownWriter) -> HandlerOutcome {
if Self::is_inside_item_name(writer)
&& !writer.is_inside("span")
&& !writer.is_inside("code")
{
writer.push_str(&format!("`{text}`"));
return HandlerOutcome::Handled;
}
HandlerOutcome::NoOp
}
}
pub struct RustdocChromeRemover;
impl HandleTag for RustdocChromeRemover {
fn should_handle(&self, tag: &str) -> bool {
match tag {
"head" | "script" | "nav" | "summary" | "button" | "a" | "div" | "span" => true,
_ => false,
}
}
fn handle_tag_start(
&mut self,
tag: &HtmlElement,
_writer: &mut MarkdownWriter,
) -> StartTagOutcome {
match tag.tag() {
"head" | "script" | "nav" => return StartTagOutcome::Skip,
"summary" => {
if tag.has_class("hideme") {
return StartTagOutcome::Skip;
}
}
"button" => {
if tag.attr("id").as_deref() == Some("copy-path") {
return StartTagOutcome::Skip;
}
}
"a" => {
if tag.has_any_classes(&["anchor", "doc-anchor", "src"]) {
return StartTagOutcome::Skip;
}
}
"div" | "span" => {
if tag.has_any_classes(&["nav-container", "sidebar-elems", "out-of-band"]) {
return StartTagOutcome::Skip;
}
}
_ => {}
}
StartTagOutcome::Continue
}
}
pub struct RustdocItemCollector {
pub items: IndexSet<RustdocItem>,
}
impl RustdocItemCollector {
pub fn new() -> Self {
Self {
items: IndexSet::new(),
}
}
fn parse_item(tag: &HtmlElement) -> Option<RustdocItem> {
if tag.tag() != "a" {
return None;
}
let href = tag.attr("href")?;
if href.starts_with('#') || href.starts_with("https://") || href.starts_with("../") {
return None;
}
for kind in RustdocItemKind::iter() {
if tag.has_class(kind.class()) {
let mut parts = href.trim_end_matches("/index.html").split('/');
if let Some(last_component) = parts.next_back() {
let last_component = match last_component.split_once('#') {
Some((component, _fragment)) => component,
None => last_component,
};
let name = last_component
.trim_start_matches(&format!("{}.", kind.class()))
.trim_end_matches(".html");
return Some(RustdocItem {
kind,
name: name.into(),
path: parts.map(Into::into).collect(),
});
}
}
}
None
}
}
impl HandleTag for RustdocItemCollector {
fn should_handle(&self, tag: &str) -> bool {
tag == "a"
}
fn handle_tag_start(
&mut self,
tag: &HtmlElement,
writer: &mut MarkdownWriter,
) -> StartTagOutcome {
match tag.tag() {
"a" => {
let is_reexport = writer.current_element_stack().iter().any(|element| {
if let Some(id) = element.attr("id") {
id.starts_with("reexport.") || id.starts_with("method.")
} else {
false
}
});
if !is_reexport {
if let Some(item) = Self::parse_item(tag) {
self.items.insert(item);
}
}
}
_ => {}
}
StartTagOutcome::Continue
}
}
#[cfg(test)]
mod tests {
use html_to_markdown::{convert_html_to_markdown, TagHandler};
use indoc::indoc;
use pretty_assertions::assert_eq;
use super::*;
fn rustdoc_handlers() -> Vec<TagHandler> {
vec![
Rc::new(RefCell::new(ParagraphHandler)),
Rc::new(RefCell::new(HeadingHandler)),
Rc::new(RefCell::new(ListHandler)),
Rc::new(RefCell::new(TableHandler::new())),
Rc::new(RefCell::new(StyledTextHandler)),
Rc::new(RefCell::new(RustdocChromeRemover)),
Rc::new(RefCell::new(RustdocHeadingHandler)),
Rc::new(RefCell::new(RustdocCodeHandler)),
Rc::new(RefCell::new(RustdocItemHandler)),
]
}
#[test]
fn test_main_heading_buttons_get_removed() {
let html = indoc! {r##"
<div class="main-heading">
<h1>Crate <a class="mod" href="#">serde</a><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1>
<span class="out-of-band">
<a class="src" href="../src/serde/lib.rs.html#1-340">source</a> · <button id="toggle-all-docs" title="collapse all docs">[<span></span>]</button>
</span>
</div>
"##};
let expected = indoc! {"
# Crate serde
"}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
#[test]
fn test_single_paragraph() {
let html = indoc! {r#"
<p>In particular, the last point is what sets <code>axum</code> apart from other frameworks.
<code>axum</code> doesnt have its own middleware system but instead uses
<a href="https://docs.rs/tower-service/0.3.2/x86_64-unknown-linux-gnu/tower_service/trait.Service.html" title="trait tower_service::Service"><code>tower::Service</code></a>. This means <code>axum</code> gets timeouts, tracing, compression,
authorization, and more, for free. It also enables you to share middleware with
applications written using <a href="http://crates.io/crates/hyper"><code>hyper</code></a> or <a href="http://crates.io/crates/tonic"><code>tonic</code></a>.</p>
"#};
let expected = indoc! {"
In particular, the last point is what sets `axum` apart from other frameworks. `axum` doesnt have its own middleware system but instead uses `tower::Service`. This means `axum` gets timeouts, tracing, compression, authorization, and more, for free. It also enables you to share middleware with applications written using `hyper` or `tonic`.
"}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
#[test]
fn test_multiple_paragraphs() {
let html = indoc! {r##"
<h2 id="serde"><a class="doc-anchor" href="#serde">§</a>Serde</h2>
<p>Serde is a framework for <em><strong>ser</strong></em>ializing and <em><strong>de</strong></em>serializing Rust data
structures efficiently and generically.</p>
<p>The Serde ecosystem consists of data structures that know how to serialize
and deserialize themselves along with data formats that know how to
serialize and deserialize other things. Serde provides the layer by which
these two groups interact with each other, allowing any supported data
structure to be serialized and deserialized using any supported data format.</p>
<p>See the Serde website <a href="https://serde.rs/">https://serde.rs/</a> for additional documentation and
usage examples.</p>
<h3 id="design"><a class="doc-anchor" href="#design">§</a>Design</h3>
<p>Where many other languages rely on runtime reflection for serializing data,
Serde is instead built on Rusts powerful trait system. A data structure
that knows how to serialize and deserialize itself is one that implements
Serdes <code>Serialize</code> and <code>Deserialize</code> traits (or uses Serdes derive
attribute to automatically generate implementations at compile time). This
avoids any overhead of reflection or runtime type information. In fact in
many situations the interaction between data structure and data format can
be completely optimized away by the Rust compiler, leaving Serde
serialization to perform the same speed as a handwritten serializer for the
specific selection of data structure and data format.</p>
"##};
let expected = indoc! {"
## Serde
Serde is a framework for _**ser**_ializing and _**de**_serializing Rust data structures efficiently and generically.
The Serde ecosystem consists of data structures that know how to serialize and deserialize themselves along with data formats that know how to serialize and deserialize other things. Serde provides the layer by which these two groups interact with each other, allowing any supported data structure to be serialized and deserialized using any supported data format.
See the Serde website https://serde.rs/ for additional documentation and usage examples.
### Design
Where many other languages rely on runtime reflection for serializing data, Serde is instead built on Rusts powerful trait system. A data structure that knows how to serialize and deserialize itself is one that implements Serdes `Serialize` and `Deserialize` traits (or uses Serdes derive attribute to automatically generate implementations at compile time). This avoids any overhead of reflection or runtime type information. In fact in many situations the interaction between data structure and data format can be completely optimized away by the Rust compiler, leaving Serde serialization to perform the same speed as a handwritten serializer for the specific selection of data structure and data format.
"}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
#[test]
fn test_styled_text() {
let html = indoc! {r#"
<p>This text is <strong>bolded</strong>.</p>
<p>This text is <em>italicized</em>.</p>
"#};
let expected = indoc! {"
This text is **bolded**.
This text is _italicized_.
"}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
#[test]
fn test_rust_code_block() {
let html = indoc! {r#"
<pre class="rust rust-example-rendered"><code><span class="kw">use </span>axum::extract::{Path, Query, Json};
<span class="kw">use </span>std::collections::HashMap;
<span class="comment">// `Path` gives you the path parameters and deserializes them.
</span><span class="kw">async fn </span>path(Path(user_id): Path&lt;u32&gt;) {}
<span class="comment">// `Query` gives you the query parameters and deserializes them.
</span><span class="kw">async fn </span>query(Query(params): Query&lt;HashMap&lt;String, String&gt;&gt;) {}
<span class="comment">// Buffer the request body and deserialize it as JSON into a
// `serde_json::Value`. `Json` supports any type that implements
// `serde::Deserialize`.
</span><span class="kw">async fn </span>json(Json(payload): Json&lt;serde_json::Value&gt;) {}</code></pre>
"#};
let expected = indoc! {"
```rs
use axum::extract::{Path, Query, Json};
use std::collections::HashMap;
// `Path` gives you the path parameters and deserializes them.
async fn path(Path(user_id): Path<u32>) {}
// `Query` gives you the query parameters and deserializes them.
async fn query(Query(params): Query<HashMap<String, String>>) {}
// Buffer the request body and deserialize it as JSON into a
// `serde_json::Value`. `Json` supports any type that implements
// `serde::Deserialize`.
async fn json(Json(payload): Json<serde_json::Value>) {}
```
"}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
#[test]
fn test_toml_code_block() {
let html = indoc! {r##"
<h2 id="required-dependencies"><a class="doc-anchor" href="#required-dependencies">§</a>Required dependencies</h2>
<p>To use axum there are a few dependencies you have to pull in as well:</p>
<div class="example-wrap"><pre class="language-toml"><code>[dependencies]
axum = &quot;&lt;latest-version&gt;&quot;
tokio = { version = &quot;&lt;latest-version&gt;&quot;, features = [&quot;full&quot;] }
tower = &quot;&lt;latest-version&gt;&quot;
</code></pre></div>
"##};
let expected = indoc! {r#"
## Required dependencies
To use axum there are a few dependencies you have to pull in as well:
```toml
[dependencies]
axum = "<latest-version>"
tokio = { version = "<latest-version>", features = ["full"] }
tower = "<latest-version>"
```
"#}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
#[test]
fn test_item_table() {
let html = indoc! {r##"
<h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2>
<ul class="item-table">
<li><div class="item-name"><a class="struct" href="struct.Error.html" title="struct axum::Error">Error</a></div><div class="desc docblock-short">Errors that can happen when using axum.</div></li>
<li><div class="item-name"><a class="struct" href="struct.Extension.html" title="struct axum::Extension">Extension</a></div><div class="desc docblock-short">Extractor and response for extensions.</div></li>
<li><div class="item-name"><a class="struct" href="struct.Form.html" title="struct axum::Form">Form</a><span class="stab portability" title="Available on crate feature `form` only"><code>form</code></span></div><div class="desc docblock-short">URL encoded extractor and response.</div></li>
<li><div class="item-name"><a class="struct" href="struct.Json.html" title="struct axum::Json">Json</a><span class="stab portability" title="Available on crate feature `json` only"><code>json</code></span></div><div class="desc docblock-short">JSON Extractor / Response.</div></li>
<li><div class="item-name"><a class="struct" href="struct.Router.html" title="struct axum::Router">Router</a></div><div class="desc docblock-short">The router type for composing handlers and services.</div></li></ul>
<h2 id="functions" class="section-header">Functions<a href="#functions" class="anchor">§</a></h2>
<ul class="item-table">
<li><div class="item-name"><a class="fn" href="fn.serve.html" title="fn axum::serve">serve</a><span class="stab portability" title="Available on crate feature `tokio` and (crate features `http1` or `http2`) only"><code>tokio</code> and (<code>http1</code> or <code>http2</code>)</span></div><div class="desc docblock-short">Serve the service with the supplied listener.</div></li>
</ul>
"##};
let expected = indoc! {r#"
## Structs
- `Error`: Errors that can happen when using axum.
- `Extension`: Extractor and response for extensions.
- `Form` [`form`]: URL encoded extractor and response.
- `Json` [`json`]: JSON Extractor / Response.
- `Router`: The router type for composing handlers and services.
## Functions
- `serve` [`tokio` and (`http1` or `http2`)]: Serve the service with the supplied listener.
"#}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
#[test]
fn test_table() {
let html = indoc! {r##"
<h2 id="feature-flags"><a class="doc-anchor" href="#feature-flags">§</a>Feature flags</h2>
<p>axum uses a set of <a href="https://doc.rust-lang.org/cargo/reference/features.html#the-features-section">feature flags</a> to reduce the amount of compiled and
optional dependencies.</p>
<p>The following optional features are available:</p>
<div><table><thead><tr><th>Name</th><th>Description</th><th>Default?</th></tr></thead><tbody>
<tr><td><code>http1</code></td><td>Enables hypers <code>http1</code> feature</td><td>Yes</td></tr>
<tr><td><code>http2</code></td><td>Enables hypers <code>http2</code> feature</td><td>No</td></tr>
<tr><td><code>json</code></td><td>Enables the <a href="struct.Json.html" title="struct axum::Json"><code>Json</code></a> type and some similar convenience functionality</td><td>Yes</td></tr>
<tr><td><code>macros</code></td><td>Enables optional utility macros</td><td>No</td></tr>
<tr><td><code>matched-path</code></td><td>Enables capturing of every requests router path and the <a href="extract/struct.MatchedPath.html" title="struct axum::extract::MatchedPath"><code>MatchedPath</code></a> extractor</td><td>Yes</td></tr>
<tr><td><code>multipart</code></td><td>Enables parsing <code>multipart/form-data</code> requests with <a href="extract/struct.Multipart.html" title="struct axum::extract::Multipart"><code>Multipart</code></a></td><td>No</td></tr>
<tr><td><code>original-uri</code></td><td>Enables capturing of every requests original URI and the <a href="extract/struct.OriginalUri.html" title="struct axum::extract::OriginalUri"><code>OriginalUri</code></a> extractor</td><td>Yes</td></tr>
<tr><td><code>tokio</code></td><td>Enables <code>tokio</code> as a dependency and <code>axum::serve</code>, <code>SSE</code> and <code>extract::connect_info</code> types.</td><td>Yes</td></tr>
<tr><td><code>tower-log</code></td><td>Enables <code>tower</code>s <code>log</code> feature</td><td>Yes</td></tr>
<tr><td><code>tracing</code></td><td>Log rejections from built-in extractors</td><td>Yes</td></tr>
<tr><td><code>ws</code></td><td>Enables WebSockets support via <a href="extract/ws/index.html" title="mod axum::extract::ws"><code>extract::ws</code></a></td><td>No</td></tr>
<tr><td><code>form</code></td><td>Enables the <code>Form</code> extractor</td><td>Yes</td></tr>
<tr><td><code>query</code></td><td>Enables the <code>Query</code> extractor</td><td>Yes</td></tr>
</tbody></table>
"##};
let expected = indoc! {r#"
## Feature flags
axum uses a set of feature flags to reduce the amount of compiled and optional dependencies.
The following optional features are available:
| Name | Description | Default? |
| --- | --- | --- |
| `http1` | Enables hypers `http1` feature | Yes |
| `http2` | Enables hypers `http2` feature | No |
| `json` | Enables the `Json` type and some similar convenience functionality | Yes |
| `macros` | Enables optional utility macros | No |
| `matched-path` | Enables capturing of every requests router path and the `MatchedPath` extractor | Yes |
| `multipart` | Enables parsing `multipart/form-data` requests with `Multipart` | No |
| `original-uri` | Enables capturing of every requests original URI and the `OriginalUri` extractor | Yes |
| `tokio` | Enables `tokio` as a dependency and `axum::serve`, `SSE` and `extract::connect_info` types. | Yes |
| `tower-log` | Enables `tower`s `log` feature | Yes |
| `tracing` | Log rejections from built-in extractors | Yes |
| `ws` | Enables WebSockets support via `extract::ws` | No |
| `form` | Enables the `Form` extractor | Yes |
| `query` | Enables the `Query` extractor | Yes |
"#}
.trim();
assert_eq!(
convert_html_to_markdown(html.as_bytes(), &mut rustdoc_handlers()).unwrap(),
expected
)
}
}

View file

@ -8,8 +8,4 @@ publish = ["oksoftware"]
okstd = { version = "0.1.9", registry = "oksoftware", features = ["macros"] }
src-derive = { version = "0.1.0", path = "../src-derive", registry = "oksoftware" }
srclang = { version = "0.1.0", path = "../..", registry = "oksoftware" }
# [[bin]]
# name = "src-derive-test"
# path = "expanded.rs"
src-lang = { version = "0.1.0", path = "../..", registry = "oksoftware" }

View file

@ -1,6 +1,19 @@
use proc_macro::TokenStream;
mod node;
/// Defines a node.
/// ```rust,ignore
/// #[node]
/// struct MyNode {
/// field: Type,
/// }
/// ```
/// which will expand to:
/// ```rust,ignore
/// struct MyNode {
/// field: Spanned<Type>,
/// }
/// ```
#[proc_macro_attribute]
pub fn node(_attr: TokenStream, item: TokenStream) -> TokenStream {
node::define_nodes(_attr, item)

View file

@ -18,13 +18,13 @@ js-sys = "0.3.57"
tower-lsp = { version = "0.17.0", default-features = false }
wasm-bindgen = "0.2.81"
wasm-bindgen-futures = { version = "0.4.30", features = [
"futures-core-03-stream",
"futures-core-03-stream",
] }
wasm-streams = "0.2.3"
srclang = { version = "0.1.0", path = "../..", registry = "oksoftware" }
src-lang = { version = "0.1.0", path = "../..", registry = "oksoftware" }
web-sys = { version = "0.3.69", features = [
"console",
"HtmlTextAreaElement",
"ReadableStream",
"WritableStream",
"console",
"HtmlTextAreaElement",
"ReadableStream",
"WritableStream",
] }

View file

@ -1,5 +1,5 @@
use js_sys::JsString;
use srclang::lexer::{self};
use src_lang::lexer::{self};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
@ -99,7 +99,7 @@ pub fn token_type_as_js_string(token_type: TokenType) -> JsString {
#[wasm_bindgen]
pub fn tokenize(input: &str) -> Result<Vec<TokenSpan>, JsValue> {
let lexer = srclang::lexer::Lexer::new(input, 0);
let lexer = src_lang::lexer::Lexer::new(input, 0);
let tokens: Vec<TokenSpan> = lexer
.map(|token| TokenSpan {

View file

@ -23,13 +23,15 @@ lsp = { version = "0.93", package = "lsp-types" }
lsp-text = "0.9"
ropey = "1.6.1"
serde_json = "1.0"
srclang = { version = "0.1.0", path = "../..", registry = "oksoftware" }
salsa = { version = "0.1.0", registry = "oksoftware", package = "salsa-2022" }
salsa-macros = { version = "0.1.0", registry = "oksoftware" , package = "salsa-2022-macros" }
src-lang = { version = "0.1.0", path = "../..", registry = "oksoftware" }
salsa = { version = "0.1.0", registry = "oksoftware", package = "salsa-2022" }
salsa-macros = { version = "0.1.0", registry = "oksoftware", package = "salsa-2022-macros" }
thiserror = "1.0"
tower-lsp = { version = "0.17.0", default-features = false }
wasm-bindgen = "0.2.81"
wasm-bindgen-futures = { version = "0.4.30", features = ["futures-core-03-stream"] }
wasm-bindgen-futures = { version = "0.4.30", features = [
"futures-core-03-stream",
] }
wasm-streams = "0.2.3"
src-collections = { version = "0.1.0", path = "../src-collections", registry = "oksoftware" }
lazy_static = "1.4.0"
@ -37,10 +39,10 @@ lazy_static = "1.4.0"
[dependencies.web-sys]
version = "0.3.57"
features = [
"console",
"CssStyleDeclaration",
"Document",
"ReadableStream",
"Window",
"WritableStream",
"console",
"CssStyleDeclaration",
"Document",
"ReadableStream",
"Window",
"WritableStream",
]

View file

@ -3,7 +3,7 @@ use lsp::{InitializeParams, InitializeResult, Url};
use lsp_text::RopeExt;
use salsa::function::DynDb;
use src_collections::Map;
use srclang::{
use src_lang::{
analyzer::{self, span_text},
compiler::text::{self, Document, SourceProgram},
parser::{
@ -18,13 +18,13 @@ use tower_lsp::{jsonrpc, LanguageServer};
use crate::update_channel;
pub struct LspServerDatabase {
db: Mutex<srclang::analyzer::db::Database>,
db: Mutex<src_lang::analyzer::db::Database>,
}
impl LspServerDatabase {
pub fn new() -> Self {
Self {
db: Mutex::new(srclang::analyzer::db::Database::default()),
db: Mutex::new(src_lang::analyzer::db::Database::default()),
}
}
}

View file

@ -7,8 +7,8 @@ mod server;
mod db;
use srclang::compiler;
use src_lang::compiler;
pub use server::*;
pub use srclang::Jar;
pub use src_lang::Jar;

View file

@ -1,5 +1,5 @@
use anyhow::anyhow;
use srclang::parser;
use src_lang::parser;
use std::result::Result::Ok;
use std::sync::Arc;
use tower_lsp::{jsonrpc, lsp_types::*, LanguageServer};

View file

@ -3,17 +3,20 @@
# src Language
> [!NOTE]
> {{#include ../versions.txt}}
`src` is a domain specific language for manipulating source code and building, progressively distiributed apps or [PDA](https://fistfulofbytes.com/progressive-distributed-apps/).
It draws a lot of inspiration from [Effekt](https://www.effekt-lang.org/) and [Koka](https://koka-lang.github.io/koka/doc/kokaspec.html) languages.
`src` is main aim is to provide a gradually distributed programming
environment for building software.
environment for building software.
It tries to achive these goals by providing a thin veneer over the operating systems `libc` or equivalent by treating the syscalls to the operating system as effects.
Therefore the operating system becomes the [effect handler](https://effect-handlers.org/) for the execution environment.
```src
use { host } from std
@ -51,4 +54,4 @@ Building upon the incredible work of the Rust community and many others, src wou
- [tower-lsp-web-demo](https://github.com/silvanshade/tower-lsp-web-demo)
- [tower-lsp-boilerplate](https://github.com/IWANABETHATGUY/tower-lsp-boilerplate)
- [tower-lsp](https:://github.com/tower-rs/tower-lsp)
- [gluon-lang](https://gluon-lang.org/)
- [gluon-lang](https://gluon-lang.org/)

View file

@ -1,21 +1,132 @@
# Summary
- [Intro](0intro.md)
# Language
- [Specification](language/0intro.md)
- [Examples](examples.md)
# Playground
* [Compiler Explorer](playground/index.md)
# Skills
- [Skills](skill-tree.md)
# Research Notes
- [Research](research.md)
- [ src Language](0intro.md)
- [ Language Specification](language/0intro.md)
- [ Examples](examples.md)
- [ src Playground](playground/index.md)
- [ Skills](skill-tree.md)
- [ Research](research.md)
- [🦀 Crates](crates/index.md)
- [⊂ Crate src_derive](crates/src_derive/index.md)
- [ node](crates/src_derive/attr.node.md)
- [⊂ Crate src_lang](crates/src_lang/index.md)
- [⟰ analyzer](crates/src_lang/analyzer/index.md)
- [⟰ db](crates/src_lang/analyzer/db/index.md)
- [℘ Database](crates/src_lang/analyzer/db/struct.Database.md)
- [𝑓 add_file](crates/src_lang/analyzer/fn.add_file.md)
- [𝑓 get_symbol](crates/src_lang/analyzer/fn.get_symbol.md)
- [𝑓 span_text](crates/src_lang/analyzer/fn.span_text.md)
- [℘ SyntaxTree](crates/src_lang/analyzer/struct.SyntaxTree.md)
- [℘ Url](crates/src_lang/analyzer/struct.Url.md)
- [℘ add_file](crates/src_lang/analyzer/struct.add_file.md)
- [℘ get_symbol](crates/src_lang/analyzer/struct.get_symbol.md)
- [℘ span_text](crates/src_lang/analyzer/struct.span_text.md)
- [⟰ ast](crates/src_lang/ast/index.md)
- [∈ Kw](crates/src_lang/ast/enum.Kw.md)
- [∈ Literal](crates/src_lang/ast/enum.Literal.md)
- [∈ Node](crates/src_lang/ast/enum.Node.md)
- [∈ Operator](crates/src_lang/ast/enum.Operator.md)
- [∈ Visibility](crates/src_lang/ast/enum.Visibility.md)
- [℘ Field](crates/src_lang/ast/struct.Field.md)
- [℘ Ident](crates/src_lang/ast/struct.Ident.md)
- [℘ Keyword](crates/src_lang/ast/struct.Keyword.md)
- [∃ FieldVisitor](crates/src_lang/ast/trait.FieldVisitor.md)
- [∃ IdentVisitor](crates/src_lang/ast/trait.IdentVisitor.md)
- [∃ KeywordVisitor](crates/src_lang/ast/trait.KeywordVisitor.md)
- [⟰ compiler](crates/src_lang/compiler/index.md)
- [⟰ errors](crates/src_lang/compiler/errors/index.md)
- [℘ Errors](crates/src_lang/compiler/errors/struct.Errors.md)
- [𝑓 add_imports](crates/src_lang/compiler/fn.add_imports.md)
- [𝑓 compile](crates/src_lang/compiler/fn.compile.md)
- [𝑓 compile_effect](crates/src_lang/compiler/fn.compile_effect.md)
- [⟰ ir](crates/src_lang/compiler/ir/index.md)
- [℘ EffectDef](crates/src_lang/compiler/ir/struct.EffectDef.md)
- [℘ Function](crates/src_lang/compiler/ir/struct.Function.md)
- [℘ Import](crates/src_lang/compiler/ir/struct.Import.md)
- [℘ InternedEffect](crates/src_lang/compiler/ir/struct.InternedEffect.md)
- [℘ Mangled](crates/src_lang/compiler/ir/struct.Mangled.md)
- [℘ Program](crates/src_lang/compiler/ir/struct.Program.md)
- [℘ Symbol](crates/src_lang/compiler/ir/struct.Symbol.md)
- [℘ __EffectDefConfig](crates/src_lang/compiler/ir/struct.__EffectDefConfig.md)
- [℘ __FunctionConfig](crates/src_lang/compiler/ir/struct.__FunctionConfig.md)
- [℘ __ImportConfig](crates/src_lang/compiler/ir/struct.__ImportConfig.md)
- [℘ __InternedEffectData](crates/src_lang/compiler/ir/struct.__InternedEffectData.md)
- [℘ __MangledData](crates/src_lang/compiler/ir/struct.__MangledData.md)
- [℘ __ProgramConfig](crates/src_lang/compiler/ir/struct.__ProgramConfig.md)
- [℘ __SymbolData](crates/src_lang/compiler/ir/struct.__SymbolData.md)
- [℘ add_imports](crates/src_lang/compiler/struct.add_imports.md)
- [℘ compile](crates/src_lang/compiler/struct.compile.md)
- [℘ compile_effect](crates/src_lang/compiler/struct.compile_effect.md)
- [⟰ text](crates/src_lang/compiler/text/index.md)
- [𝑓 calculate_line_lengths](crates/src_lang/compiler/text/fn.calculate_line_lengths.md)
- [𝑓 cmp_range](crates/src_lang/compiler/text/fn.cmp_range.md)
- [𝑓 to_spans](crates/src_lang/compiler/text/fn.to_spans.md)
- [℘ Document](crates/src_lang/compiler/text/struct.Document.md)
- [℘ Position](crates/src_lang/compiler/text/struct.Position.md)
- [℘ SourceMap](crates/src_lang/compiler/text/struct.SourceMap.md)
- [℘ SourceProgram](crates/src_lang/compiler/text/struct.SourceProgram.md)
- [℘ Span](crates/src_lang/compiler/text/struct.Span.md)
- [℘ SpanOverlap](crates/src_lang/compiler/text/struct.SpanOverlap.md)
- [℘ Spanned](crates/src_lang/compiler/text/struct.Spanned.md)
- [℘ __PositionData](crates/src_lang/compiler/text/struct.__PositionData.md)
- [℘ __SourceMapConfig](crates/src_lang/compiler/text/struct.__SourceMapConfig.md)
- [℘ __SpanData](crates/src_lang/compiler/text/struct.__SpanData.md)
- [℘ __SpannedData](crates/src_lang/compiler/text/struct.__SpannedData.md)
- [℘ calculate_line_lengths](crates/src_lang/compiler/text/struct.calculate_line_lengths.md)
- [℘ to_spans](crates/src_lang/compiler/text/struct.to_spans.md)
- [⟰ lexer](crates/src_lang/lexer/index.md)
- [∈ LexicalError](crates/src_lang/lexer/enum.LexicalError.md)
- [∈ Token](crates/src_lang/lexer/enum.Token.md)
- [∈ Variable](crates/src_lang/lexer/enum.Variable.md)
- [∈ Word](crates/src_lang/lexer/enum.Word.md)
- [℘ Lexer](crates/src_lang/lexer/struct.Lexer.md)
- [℘ Location](crates/src_lang/lexer/struct.Location.md)
- [℘ Position](crates/src_lang/lexer/struct.Position.md)
- [℘ Spanned](crates/src_lang/lexer/struct.Spanned.md)
- [℘ TripleIterator](crates/src_lang/lexer/struct.TripleIterator.md)
- [↦ span](crates/src_lang/macro.span.md)
- [⟰ ops](crates/src_lang/ops/index.md)
- [⟰ traversal](crates/src_lang/ops/traversal/index.md)
- [∈ Control](crates/src_lang/ops/traversal/enum.Control.md)
- [⟰ parser](crates/src_lang/parser/index.md)
- [⟰ ast](crates/src_lang/parser/ast/index.md)
- [𝑐 ANON_FN_NAME](crates/src_lang/parser/ast/constant.ANON_FN_NAME.md)
- [∈ FnArg](crates/src_lang/parser/ast/enum.FnArg.md)
- [∈ Keyword](crates/src_lang/parser/ast/enum.Keyword.md)
- [∈ Literal](crates/src_lang/parser/ast/enum.Literal.md)
- [∈ Node](crates/src_lang/parser/ast/enum.Node.md)
- [∈ Operator](crates/src_lang/parser/ast/enum.Operator.md)
- [∈ Value](crates/src_lang/parser/ast/enum.Value.md)
- [∈ Visibility](crates/src_lang/parser/ast/enum.Visibility.md)
- [∈ Whitespace](crates/src_lang/parser/ast/enum.Whitespace.md)
- [℘ Array](crates/src_lang/parser/ast/struct.Array.md)
- [℘ BinaryOperation](crates/src_lang/parser/ast/struct.BinaryOperation.md)
- [℘ Binding](crates/src_lang/parser/ast/struct.Binding.md)
- [℘ Block](crates/src_lang/parser/ast/struct.Block.md)
- [℘ BranchDef](crates/src_lang/parser/ast/struct.BranchDef.md)
- [℘ EffectDef](crates/src_lang/parser/ast/struct.EffectDef.md)
- [℘ FieldAccess](crates/src_lang/parser/ast/struct.FieldAccess.md)
- [℘ FieldDef](crates/src_lang/parser/ast/struct.FieldDef.md)
- [℘ FnCall](crates/src_lang/parser/ast/struct.FnCall.md)
- [℘ FnDef](crates/src_lang/parser/ast/struct.FnDef.md)
- [℘ FnIdent](crates/src_lang/parser/ast/struct.FnIdent.md)
- [℘ Ident](crates/src_lang/parser/ast/struct.Ident.md)
- [℘ ImplDef](crates/src_lang/parser/ast/struct.ImplDef.md)
- [℘ KeywordAndVisibility](crates/src_lang/parser/ast/struct.KeywordAndVisibility.md)
- [℘ Module](crates/src_lang/parser/ast/struct.Module.md)
- [℘ Prototype](crates/src_lang/parser/ast/struct.Prototype.md)
- [℘ StringLit](crates/src_lang/parser/ast/struct.StringLit.md)
- [℘ StructDef](crates/src_lang/parser/ast/struct.StructDef.md)
- [℘ Tuple](crates/src_lang/parser/ast/struct.Tuple.md)
- [℘ UseDef](crates/src_lang/parser/ast/struct.UseDef.md)
- [⟰ span](crates/src_lang/parser/span/index.md)
- [∈ ByteOrLineColOrCoord](crates/src_lang/parser/span/enum.ByteOrLineColOrCoord.md)
- [℘ ByteOrLineColOrCoordInterned](crates/src_lang/parser/span/struct.ByteOrLineColOrCoordInterned.md)
- [℘ SourceMap](crates/src_lang/parser/span/struct.SourceMap.md)
- [℘ Spanned](crates/src_lang/parser/span/struct.Spanned.md)
- [℘ __SourceMapConfig](crates/src_lang/parser/span/struct.__SourceMapConfig.md)
- [∃ HasChildSpans](crates/src_lang/parser/span/trait.HasChildSpans.md)
- [∃ Spanning](crates/src_lang/parser/span/trait.Spanning.md)
- [⟰ src](crates/src_lang/parser/src/index.md)
- [℘ SourceParser](crates/src_lang/parser/src/struct.SourceParser.md)
- [∃ __ToTriple](crates/src_lang/parser/src/trait.__ToTriple.md)
- [℘ Jar](crates/src_lang/struct.Jar.md)
- [∃ Db](crates/src_lang/trait.Db.md)

4
docs/crates/index.md Normal file
View file

@ -0,0 +1,4 @@
# Crates
- [src_derive](./src_derive)
- [src_lang](./src_lang)

View file

@ -1,6 +1,5 @@
# Language
# Language Specification
## Specification
```rust,ignore
{{#include ../../src/parser/src.lalrpop}}
```
```

View file

@ -1,4 +1,8 @@
<div id="container">
<div style="display:none;">
# IDE
</div>
<div id="container">
<div id="cell-editor">
<label for="editor">editor</label>
<div id="editor"></div>
@ -19,4 +23,4 @@
<label for="channel-console">console</label>
<textarea id="channel-console" autocomplete="off" spellcheck="off" wrap="off" readonly rows="3"></textarea>
</div>
</div>
</div>

37
docs/theme/index.hbs vendored
View file

@ -51,6 +51,10 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Allura&family=Inclusive+Sans:ital@0;1&display=swap" rel="stylesheet">
<!-- prefetch taocp.png -->
<link rel="prefetch" href="taocp.png">
<!-- add https://microsoft.github.io/vscode-codicons/dist/codicon.css -->
<link rel="stylesheet" href="https://microsoft.github.io/vscode-codicons/dist/codicon.css">
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
@ -165,7 +169,10 @@
{{/if}}
</div>
<h1 class="menu-title">{{ book_title }}</h1>
<h1 class="menu-title">
<img src="{{ path_to_root }}taocp.png" width="48px"/>
src lang
</h1>
<div class="right-buttons">
{{#if print_enable}}
@ -218,16 +225,16 @@
<!-- Mobile navigation buttons -->
{{#previous}}
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC"
style=" rotate: 270deg; width: 94px"
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC"
style=" rotate: 270deg; width: 94px"
/>
</a>
{{/previous}}
{{#next}}
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC"
style=" rotate: 90deg; width: 94px"
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC"
style=" rotate: 90deg; width: 94px"
/>
</a>
{{/next}}
@ -238,11 +245,11 @@
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
{{#previous}}
{{#previous}}
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"
style="display: flex; justify-content: middle; align-items: center; width: 50%">
&lt;
</a>
{{/previous}}
@ -346,7 +353,23 @@
</script>
{{/if}}
{{/if}}
<script>
document.addEventListener("DOMContentLoaded", function() {
const elements = document.querySelectorAll('em');
elements.forEach(function(element) {
const match = element.textContent.trim().match(/^codicon-(.*)$/);
if (match) {
const newElement = document.createElement('i');
newElement.classList.add('codicon', 'codicon-' + match[1]);
newElement.style.fontSize = '2em';
newElement.ariaHidden = true;
// Replace the <em> element with the new <i> element
element.parentNode.replaceChild(newElement, element);
}
});
});
</script>
</div>
</body>
</html>

1426
ok.css

File diff suppressed because it is too large Load diff

1
package-lock.json generated
View file

@ -6480,6 +6480,7 @@
}
},
"packages/app": {
"name": "monaco-lsp-streams",
"version": "0.0.0",
"license": "Apache-2.0 WITH LLVM-exception",
"dependencies": {

View file

@ -1,11 +1,6 @@
/* tslint:disable */
/* eslint-disable */
/**
* @param {ServerConfig} config
* @returns {Promise<void>}
*/
export function serve(config: ServerConfig): Promise<void>;
/**
* @param {TokenType} token_type
* @returns {string}
*/
@ -16,6 +11,11 @@ export function token_type_as_js_string(token_type: TokenType): string;
*/
export function tokenize(input: string): (TokenSpan)[];
/**
* @param {ServerConfig} config
* @returns {Promise<void>}
*/
export function serve(config: ServerConfig): Promise<void>;
/**
*/
export enum TokenType {
Pipe = 0,
@ -176,9 +176,6 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly __wbg_serverconfig_free: (a: number) => void;
readonly serverconfig_new: (a: number, b: number) => number;
readonly serve: (a: number) => number;
readonly __wbg_tokenspan_free: (a: number) => void;
readonly __wbg_get_tokenspan_start: (a: number) => number;
readonly __wbg_set_tokenspan_start: (a: number, b: number) => void;
@ -188,13 +185,24 @@ export interface InitOutput {
readonly __wbg_set_tokenspan_scope: (a: number, b: number) => void;
readonly token_type_as_js_string: (a: number) => number;
readonly tokenize: (a: number, b: number, c: number) => void;
readonly __wbg_serverconfig_free: (a: number) => void;
readonly serverconfig_new: (a: number, b: number) => number;
readonly serve: (a: number) => number;
readonly __wbg_intounderlyingbytesource_free: (a: number) => void;
readonly intounderlyingbytesource_type: (a: number) => number;
readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
readonly intounderlyingbytesource_start: (a: number, b: number) => void;
readonly intounderlyingbytesource_pull: (a: number, b: number) => number;
readonly intounderlyingbytesource_cancel: (a: number) => void;
readonly __wbg_intounderlyingsource_free: (a: number) => void;
readonly intounderlyingsource_pull: (a: number, b: number) => number;
readonly intounderlyingsource_cancel: (a: number) => void;
readonly __wbg_queuingstrategy_free: (a: number) => void;
readonly queuingstrategy_highWaterMark: (a: number) => number;
readonly __wbg_intounderlyingsink_free: (a: number) => void;
readonly intounderlyingsink_write: (a: number, b: number) => number;
readonly intounderlyingsink_close: (a: number) => number;
readonly intounderlyingsink_abort: (a: number, b: number) => number;
readonly __wbg_intounderlyingsource_free: (a: number) => void;
readonly intounderlyingsource_pull: (a: number, b: number) => number;
readonly intounderlyingsource_cancel: (a: number) => void;
readonly __wbg_readablestreamgetreaderoptions_free: (a: number) => void;
readonly readablestreamgetreaderoptions_mode: (a: number) => number;
readonly __wbg_pipeoptions_free: (a: number) => void;
@ -202,22 +210,14 @@ export interface InitOutput {
readonly pipeoptions_preventCancel: (a: number) => number;
readonly pipeoptions_preventAbort: (a: number) => number;
readonly pipeoptions_signal: (a: number) => number;
readonly __wbg_queuingstrategy_free: (a: number) => void;
readonly queuingstrategy_highWaterMark: (a: number) => number;
readonly __wbg_intounderlyingbytesource_free: (a: number) => void;
readonly intounderlyingbytesource_type: (a: number) => number;
readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
readonly intounderlyingbytesource_start: (a: number, b: number) => void;
readonly intounderlyingbytesource_pull: (a: number, b: number) => number;
readonly intounderlyingbytesource_cancel: (a: number) => void;
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_export_2: WebAssembly.Table;
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hef4ca354c23a4fc7: (a: number, b: number, c: number) => void;
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h544499b60125df46: (a: number, b: number, c: number) => void;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
readonly __wbindgen_exn_store: (a: number) => void;
readonly wasm_bindgen__convert__closures__invoke2_mut__hd246805203d2bb11: (a: number, b: number, c: number, d: number) => void;
readonly wasm_bindgen__convert__closures__invoke2_mut__h9a3b6e60a7c15fa9: (a: number, b: number, c: number, d: number) => void;
}
export type SyncInitInput = BufferSource | WebAssembly.Module;

View file

@ -213,25 +213,8 @@ function makeMutClosure(arg0, arg1, dtor, f) {
CLOSURE_DTORS.register(real, state, state);
return real;
}
function __wbg_adapter_20(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hef4ca354c23a4fc7(arg0, arg1, addHeapObject(arg2));
}
function _assertClass(instance, klass) {
if (!(instance instanceof klass)) {
throw new Error(`expected instance of ${klass.name}`);
}
return instance.ptr;
}
/**
* @param {ServerConfig} config
* @returns {Promise<void>}
*/
export function serve(config) {
_assertClass(config, ServerConfig);
var ptr0 = config.__destroy_into_raw();
const ret = wasm.serve(ptr0);
return takeObject(ret);
function __wbg_adapter_24(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h544499b60125df46(arg0, arg1, addHeapObject(arg2));
}
/**
@ -287,6 +270,23 @@ export function tokenize(input) {
}
}
function _assertClass(instance, klass) {
if (!(instance instanceof klass)) {
throw new Error(`expected instance of ${klass.name}`);
}
return instance.ptr;
}
/**
* @param {ServerConfig} config
* @returns {Promise<void>}
*/
export function serve(config) {
_assertClass(config, ServerConfig);
var ptr0 = config.__destroy_into_raw();
const ret = wasm.serve(ptr0);
return takeObject(ret);
}
function handleError(f, args) {
try {
return f.apply(this, args);
@ -294,8 +294,8 @@ function handleError(f, args) {
wasm.__wbindgen_exn_store(addHeapObject(e));
}
}
function __wbg_adapter_99(arg0, arg1, arg2, arg3) {
wasm.wasm_bindgen__convert__closures__invoke2_mut__hd246805203d2bb11(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
function __wbg_adapter_111(arg0, arg1, arg2, arg3) {
wasm.wasm_bindgen__convert__closures__invoke2_mut__h9a3b6e60a7c15fa9(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
}
/**
@ -669,9 +669,6 @@ async function __wbg_load(module, imports) {
function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbindgen_cb_drop = function(arg0) {
const obj = takeObject(arg0).original;
if (obj.cnt-- == 1) {
@ -685,20 +682,26 @@ function __wbg_get_imports() {
const ret = TokenSpan.__wrap(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
const ret = getStringFromWasm0(arg0, arg1);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof(obj) === 'string' ? obj : undefined;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
imports.wbg.__wbg_respond_f4778bef04e912a6 = function(arg0, arg1) {
getObject(arg0).respond(arg1 >>> 0);
};
imports.wbg.__wbg_write_f6d68f54a7b41f92 = function(arg0, arg1) {
const ret = getObject(arg0).write(takeObject(arg1));
imports.wbg.__wbg_byobRequest_a3c74c3694777d1b = function(arg0) {
const ret = getObject(arg0).byobRequest;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_view_d1a31268af734e5d = function(arg0) {
const ret = getObject(arg0).view;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_bytesliteral_efe7d360639bf32b = function() {
const ret = bytes_literal();
return addHeapObject(ret);
};
imports.wbg.__wbg_getWriter_6cdcca9cf3b715dc = function() { return handleError(function (arg0) {
@ -713,11 +716,24 @@ function __wbg_get_imports() {
const ret = getObject(arg0).close();
return addHeapObject(ret);
};
imports.wbg.__wbg_write_f6d68f54a7b41f92 = function(arg0, arg1) {
const ret = getObject(arg0).write(takeObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_releaseLock_0d3bce87e07d43f6 = function(arg0) {
getObject(arg0).releaseLock();
};
imports.wbg.__wbg_respond_f4778bef04e912a6 = function(arg0, arg1) {
getObject(arg0).respond(arg1 >>> 0);
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof(obj) === 'string' ? obj : undefined;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_close_a41954830b65c455 = function(arg0) {
getObject(arg0).close();
@ -725,17 +741,9 @@ function __wbg_get_imports() {
imports.wbg.__wbg_enqueue_3a8a8e67e44d2567 = function(arg0, arg1) {
getObject(arg0).enqueue(getObject(arg1));
};
imports.wbg.__wbg_byobRequest_a3c74c3694777d1b = function(arg0) {
const ret = getObject(arg0).byobRequest;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_close_045ed342139beb7d = function(arg0) {
getObject(arg0).close();
};
imports.wbg.__wbg_view_d1a31268af734e5d = function(arg0) {
const ret = getObject(arg0).view;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_buffer_610b70c8fd30da2d = function(arg0) {
const ret = getObject(arg0).buffer;
return addHeapObject(ret);
@ -748,14 +756,6 @@ function __wbg_get_imports() {
const ret = getObject(arg0).byteLength;
return ret;
};
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbg_bytesliteral_efe7d360639bf32b = function() {
const ret = bytes_literal();
return addHeapObject(ret);
};
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
const ret = new Error();
return addHeapObject(ret);
@ -781,6 +781,21 @@ function __wbg_get_imports() {
imports.wbg.__wbg_log_5bb5f88f245d7762 = function(arg0) {
console.log(getObject(arg0));
};
imports.wbg.__wbg_queueMicrotask_481971b0d87f3dd4 = function(arg0) {
queueMicrotask(getObject(arg0));
};
imports.wbg.__wbg_queueMicrotask_3cbae2ec6b6cd3d6 = function(arg0) {
const ret = getObject(arg0).queueMicrotask;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_is_function = function(arg0) {
const ret = typeof(getObject(arg0)) === 'function';
return ret;
};
imports.wbg.__wbg_newnoargs_e258087cd0daa0ea = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_is_object = function(arg0) {
const val = getObject(arg0);
const ret = typeof(val) === 'object' && val !== null;
@ -794,6 +809,30 @@ function __wbg_get_imports() {
const ret = getObject(arg0).value;
return addHeapObject(ret);
};
imports.wbg.__wbg_call_27c0f87801dedf93 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).call(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_self_ce0dbfc45cf2f5be = function() { return handleError(function () {
const ret = self.self;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_window_c6fb939a7f436783 = function() { return handleError(function () {
const ret = window.window;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_globalThis_d1e6af4856ba331b = function() { return handleError(function () {
const ret = globalThis.globalThis;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_global_207b558942527489 = function() { return handleError(function () {
const ret = global.global;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbindgen_is_undefined = function(arg0) {
const ret = getObject(arg0) === undefined;
return ret;
};
imports.wbg.__wbg_new_28c511d9baebfa89 = function(arg0, arg1) {
const ret = new Error(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
@ -817,7 +856,7 @@ function __wbg_get_imports() {
const a = state0.a;
state0.a = 0;
try {
return __wbg_adapter_99(a, state0.b, arg0, arg1);
return __wbg_adapter_111(a, state0.b, arg0, arg1);
} finally {
state0.a = a;
}
@ -883,8 +922,8 @@ function __wbg_get_imports() {
const ret = wasm.memory;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper4516 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1550, __wbg_adapter_20);
imports.wbg.__wbindgen_closure_wrapper4454 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1540, __wbg_adapter_24);
return addHeapObject(ret);
};

View file

@ -1,9 +1,6 @@
/* tslint:disable */
/* eslint-disable */
export const memory: WebAssembly.Memory;
export function __wbg_serverconfig_free(a: number): void;
export function serverconfig_new(a: number, b: number): number;
export function serve(a: number): number;
export function __wbg_tokenspan_free(a: number): void;
export function __wbg_get_tokenspan_start(a: number): number;
export function __wbg_set_tokenspan_start(a: number, b: number): void;
@ -13,13 +10,24 @@ export function __wbg_get_tokenspan_scope(a: number): number;
export function __wbg_set_tokenspan_scope(a: number, b: number): void;
export function token_type_as_js_string(a: number): number;
export function tokenize(a: number, b: number, c: number): void;
export function __wbg_serverconfig_free(a: number): void;
export function serverconfig_new(a: number, b: number): number;
export function serve(a: number): number;
export function __wbg_intounderlyingbytesource_free(a: number): void;
export function intounderlyingbytesource_type(a: number): number;
export function intounderlyingbytesource_autoAllocateChunkSize(a: number): number;
export function intounderlyingbytesource_start(a: number, b: number): void;
export function intounderlyingbytesource_pull(a: number, b: number): number;
export function intounderlyingbytesource_cancel(a: number): void;
export function __wbg_intounderlyingsource_free(a: number): void;
export function intounderlyingsource_pull(a: number, b: number): number;
export function intounderlyingsource_cancel(a: number): void;
export function __wbg_queuingstrategy_free(a: number): void;
export function queuingstrategy_highWaterMark(a: number): number;
export function __wbg_intounderlyingsink_free(a: number): void;
export function intounderlyingsink_write(a: number, b: number): number;
export function intounderlyingsink_close(a: number): number;
export function intounderlyingsink_abort(a: number, b: number): number;
export function __wbg_intounderlyingsource_free(a: number): void;
export function intounderlyingsource_pull(a: number, b: number): number;
export function intounderlyingsource_cancel(a: number): void;
export function __wbg_readablestreamgetreaderoptions_free(a: number): void;
export function readablestreamgetreaderoptions_mode(a: number): number;
export function __wbg_pipeoptions_free(a: number): void;
@ -27,19 +35,11 @@ export function pipeoptions_preventClose(a: number): number;
export function pipeoptions_preventCancel(a: number): number;
export function pipeoptions_preventAbort(a: number): number;
export function pipeoptions_signal(a: number): number;
export function __wbg_queuingstrategy_free(a: number): void;
export function queuingstrategy_highWaterMark(a: number): number;
export function __wbg_intounderlyingbytesource_free(a: number): void;
export function intounderlyingbytesource_type(a: number): number;
export function intounderlyingbytesource_autoAllocateChunkSize(a: number): number;
export function intounderlyingbytesource_start(a: number, b: number): void;
export function intounderlyingbytesource_pull(a: number, b: number): number;
export function intounderlyingbytesource_cancel(a: number): void;
export function __wbindgen_malloc(a: number, b: number): number;
export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number;
export const __wbindgen_export_2: WebAssembly.Table;
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hef4ca354c23a4fc7(a: number, b: number, c: number): void;
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h544499b60125df46(a: number, b: number, c: number): void;
export function __wbindgen_add_to_stack_pointer(a: number): number;
export function __wbindgen_free(a: number, b: number, c: number): void;
export function __wbindgen_exn_store(a: number): void;
export function wasm_bindgen__convert__closures__invoke2_mut__hd246805203d2bb11(a: number, b: number, c: number, d: number): void;
export function wasm_bindgen__convert__closures__invoke2_mut__h9a3b6e60a7c15fa9(a: number, b: number, c: number, d: number): void;

View file

@ -9,8 +9,7 @@ if [ ! -d "$OUT_DIR" ]; then
OUT_DIR="../../target"
fi
wasm-bindgen --out-dir assets/wasm --target web --typescript ${OUT_DIR}/wasm32-unknown-unknown/release/src_lsp_browser.wasm;
wasm-bindgen --out-dir assets/wasm --target web --typescript ${OUT_DIR}/wasm32-unknown-unknown/release/src_lsp_browser.wasm;
webpack;
mv ../../book/playground/*.wasm ../../book
mv ../../book/playground/*.ttf ../../book

View file

@ -67,7 +67,7 @@ const config = {
// ],
// }),
new HtmlWebpackPlugin({
template: "../../book/playground/index.html",
template: path.resolve(__dirname, "../../book/playground/index.html"),
scriptLoading: "module",
title: "src-lsp Playground",
}),

View file

@ -4,6 +4,7 @@ use salsa::DebugWithDb;
#[derive(Default)]
#[salsa::db(crate::Jar)]
/// The salsa database for the compiler.
pub struct Database {
storage: salsa::Storage<Self>,

View file

@ -1,6 +1,6 @@
use crate::lexer::Location;
use crate::ops;
use crate::parser::span::Spanned;
use crate::{ops};
use src_derive::node;
use std::fmt::Display;
use std::ops::Range;
@ -30,21 +30,35 @@ pub enum Literal {
#[derive(Debug)]
pub enum Kw {
/// The `None` keyword.
None,
/// The `Some` keyword.
Some,
/// The `let` keyword.
Let,
/// The `pub` keyword.
Public,
/// The `priv` keyword.
Private,
/// The `fn` keyword.
Fn,
/// The `if` keyword.
If,
/// The `else` keyword.
Else,
/// The `match` keyword.
Match,
/// The `while` keyword.
Arrow,
/// The `struct` keyword.
Struct,
/// The `self` keyword.
SelfValue,
When,
/// The `effect` keyword.
Effect,
/// The `impl` keyword.
Impl,
/// The `use` keyword.
Use,
}

View file

@ -1,8 +1,20 @@
//! # src-lang
//! src-lang is a compiler is a language and a specification for a domain specific language
//! that is aimed at manipulating source code.
//!
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
/// `analyzer` is responsible for analyzing the syntax tree and building the symbol table.
pub mod analyzer;
/// `ast` contains the abstract syntax tree for the src-lang.
pub mod ast;
/// `compiler` contains the compiler for the src-lang.
pub mod compiler;
/// `lexer` contains the intermediate representation for the src-lang.
pub mod lexer;
/// `ops` contains the operations tree traversal operations for the src-lang.
pub mod ops;
/// `parser` contains the parser for the src-lang, which is written in LALRPOP.
pub mod parser;
use compiler::text;
@ -10,6 +22,8 @@ use compiler::text;
use crate::compiler::ir;
#[salsa::jar(db = Db)]
/// The salsa database for the compiler.
/// The default convention is to implement this at the crate level.
pub struct Jar(
parser::span::ByteOrLineColOrCoordInterned,
parser::span::SourceMap,
@ -38,6 +52,10 @@ pub struct Jar(
analyzer::span_text,
);
/// The Db trait is a marker trait that is used to ensure that the Jar struct is a valid salsa database.
/// The default convention is to implement this at the crate level.
pub trait Db: salsa::DbWithJar<Jar> {}
/// Implement the Db trait for the Jar struct.
/// The default convention is to implement this at the crate level.
impl<DB> Db for DB where DB: ?Sized + salsa::DbWithJar<Jar> {}

View file

@ -114,8 +114,9 @@ impl Spanning for &Range<Location> {
}
}
// span macro
#[macro_export]
/// A macro to create a `Spanned<T>` object
/// Heavily used in `src.lalrpop to create a Spanned object
macro_rules! span {
($coord:expr, $expr:expr) => {
Spanned($coord, $expr, $coord)

2
versions.txt Normal file
View file

@ -0,0 +1,2 @@
commit: c9f68b625741bf0635c4198ab93fa7d250c9e2ae
version: c9f68b6