Unvendor tree-sitter-elm (#893)

Co-authored-by: Wilfred Hughes <me@wilfred.me.uk>
pull/894/head
Antonin Delpeuch 2025-10-06 22:53:57 +07:00 committed by GitHub
parent 35f63d1015
commit 3e8e78c991
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
76 changed files with 18 additions and 70189 deletions

@ -2,7 +2,7 @@
### Parsing
Added support for protocol buffer files. Updated CMake, Solidity, HCL, Dart, Devicetree and R parsers.
Added support for protocol buffer files. Updated CMake, Solidity, HCL, Dart, Elm, Devicetree and R parsers.
### Display

11
Cargo.lock generated

@ -284,6 +284,7 @@ dependencies = [
"tree-sitter-dart-orchard",
"tree-sitter-devicetree",
"tree-sitter-elixir",
"tree-sitter-elm",
"tree-sitter-erlang",
"tree-sitter-fsharp",
"tree-sitter-go",
@ -1103,6 +1104,16 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-elm"
version = "5.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accee95d95c001e53f5ab1a1168f1ed1c6ec763a17fb48b43acf5bf4ff9e3423"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-erlang"
version = "0.13.0"

@ -85,6 +85,7 @@ tree-sitter-css = "0.23.1"
tree-sitter-dart-orchard = "0.2.1"
tree-sitter-devicetree = "0.14.1"
tree-sitter-elixir = "0.3.4"
tree-sitter-elm = "5.8.0"
tree-sitter-erlang = "0.13.0"
tree-sitter-fsharp = "0.1.0"
tree-sitter-go = "0.23.4"

@ -87,11 +87,6 @@ fn main() {
src_dir: "vendored_parsers/tree-sitter-elisp-src",
extra_files: vec![],
},
TreeSitterParser {
name: "tree-sitter-elm",
src_dir: "vendored_parsers/tree-sitter-elm-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser {
name: "tree-sitter-elvish",
src_dir: "vendored_parsers/tree-sitter-elvish-src",

@ -74,7 +74,6 @@ extern "C" {
fn tree_sitter_clojure() -> ts::Language;
fn tree_sitter_commonlisp() -> ts::Language;
fn tree_sitter_elisp() -> ts::Language;
fn tree_sitter_elm() -> ts::Language;
fn tree_sitter_elvish() -> ts::Language;
fn tree_sitter_gleam() -> ts::Language;
fn tree_sitter_hare() -> ts::Language;
@ -321,16 +320,15 @@ pub(crate) fn from_language(language: guess::Language) -> TreeSitterConfig {
}
}
Elm => {
let language = unsafe { tree_sitter_elm() };
let language_fn = tree_sitter_elm::LANGUAGE;
let language = tree_sitter::Language::new(language_fn);
TreeSitterConfig {
language: language.clone(),
atom_nodes: ["string_constant_expr"].into_iter().collect(),
delimiter_tokens: vec![("{", "}"), ("[", "]"), ("(", ")")],
highlight_query: ts::Query::new(
&language,
include_str!("../../vendored_parsers/highlights/elm.scm"),
)
.unwrap(),
highlight_query: ts::Query::new(&language, tree_sitter_elm::HIGHLIGHTS_QUERY)
.unwrap(),
sub_languages: vec![],
}
}

@ -1 +0,0 @@
../tree-sitter-elm/queries/highlights.scm

@ -1 +0,0 @@
tree-sitter-elm/src

@ -1,17 +0,0 @@
# https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.txt]
indent_size = 4
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

@ -1 +0,0 @@
/src/** linguist-vendored

@ -1,19 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

@ -1,22 +0,0 @@
name: Fuzz Parser
on:
push:
paths:
- src/scanner.c
pull_request:
paths:
- src/scanner.c
workflow_dispatch:
jobs:
test:
name: Parser fuzzing
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: vigoux/tree-sitter-fuzz-action@v1
with:
language: elm
external-scanner: src/scanner.c
time: 60

@ -1,50 +0,0 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
name: Node.js Package
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- run: npm i
- run: npm run build
- run: npm run test-only
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://registry.npmjs.org/
- run: npm i
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
publish-gpr:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://npm.pkg.github.com/
- run: npm i
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}

@ -1,18 +0,0 @@
name: Publish crates.io
on:
release:
types: [created]
jobs:
cargo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- run: cargo login ${CRATES_IO_TOKEN}
env:
CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
- run: cargo publish

@ -1,39 +0,0 @@
name: Test full Linux
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Npm install
run: |
npm i
- name: Unit tests
run: |
npm test
- name: Test examples
continue-on-error: true
run: |
script/parse-examples-full

@ -1,61 +0,0 @@
name: Test Linux
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
node:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Npm install
run: |
npm i
- name: Unit tests
run: |
npm test
- name: Test examples
run: |
script/parse-examples
shell: bash
rust:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: lint
uses: actions-rs/cargo@v1
with:
command: clippy
- name: test
uses: actions-rs/cargo@v1
with:
command: test

@ -1,44 +0,0 @@
name: Validate that changes doesn't break elm-language-server
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
with:
path: "tree-sitter-elm"
- uses: actions/checkout@v4
name: Checkout main branch of elm-language-server
with:
repository: "elm-tooling/elm-language-server"
path: "elm-language-server"
- name: Install tree-sitter dependencies and generate wasm bundle
run: |
cd tree-sitter-elm/
npm i
npm run build
npx tree-sitter build-wasm
mv ./tree-sitter-elm.wasm ../elm-language-server/tree-sitter-elm.wasm -f
- name: Install elm-language-server dependencies, compile, and run tests
run: |
cd elm-language-server/
npm i
npm run compile
npm install -g elm-format
npm test

@ -1,15 +0,0 @@
package-lock.json
Cargo.lock
node_modules
build
*.log
.idea
.vscode/ipch
target/
/.build/
# Examples generated during automated tests
examples/**
examples-full/**
!examples/Basic.elm
!examples/Test.elm

@ -1,13 +0,0 @@
.vscode
.github
.gitattributes
.editorconfig
test
elm-stuff
examples
examples-full
build
script
HOW_TO_RELEASE.md
rust
Cargo.toml

@ -1,42 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "parse",
"problemMatcher": []
},
{
"type": "npm",
"script": "build",
"problemMatcher": []
},
{
"type": "npm",
"script": "parse-1",
"problemMatcher": []
},
{
"type": "npm",
"script": "parse-asset",
"problemMatcher": []
},
{
"type": "npm",
"script": "parse-article",
"problemMatcher": []
},
{
"type": "npm",
"script": "parse-basic",
"problemMatcher": []
},
{
"type": "npm",
"script": "parse-test",
"problemMatcher": []
}
]
}

@ -1,34 +0,0 @@
[package]
name = "tree-sitter-elm"
description = "elm grammar for the tree-sitter parsing library"
authors = [
"Harry Sarson <harry.sarson@hotmail.co.uk>",
"Kolja Lampe <razzeee@gmail.com>"
]
homepage = "https://tree-sitter.github.io/tree-sitter/"
repository = "https://github.com/elm-tooling/tree-sitter-elm"
keywords = ["elm", "tree", "sitter", "parsing", "incremental"]
categories = ["parser-implementations", "api-bindings", "text-editors", "parsing"]
edition = "2018"
license = "MIT"
build = "bindings/rust/build.rs"
include = [
"bindings/rust/*",
"grammar.js",
"queries/*",
"src/*",
"LICENSE.md",
]
# Keep in sync with package.json
version = "5.7.0"
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "0.20.10"
[build-dependencies]
cc = "1.0"

@ -1,6 +0,0 @@
1. Increase the version number in the package.json and the Cargo.toml
2. Run `npm run generate-wasm`
3. Push the code to main
4. Wait for tests to be successful
5. Create a release on github with the name being the version number from before prefixed with `v` for e.g. `v1.1.0`
6. Enjoy, builds should appear on that release as soon as the CI is done running them.

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2018 Kolja Lampe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,43 +0,0 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TreeSitterElm",
platforms: [.macOS(.v10_13), .iOS(.v11)],
products: [
.library(name: "TreeSitterElm", targets: ["TreeSitterElm"]),
],
dependencies: [],
targets: [
.target(name: "TreeSitterElm",
path: ".",
exclude: [
"binding.gyp",
"bindings",
"Cargo.toml",
"docs",
"examples",
"grammar.js",
"HOW_TO_RELEASE.md",
"index.d.ts",
"LICENSE.md",
"package.json",
"README.md",
"script",
"src/grammar.json",
"src/node-types.json",
"test",
"tsconfig.json",
],
sources: [
"src/parser.c",
"src/scanner.c",
],
resources: [
.copy("queries")
],
publicHeadersPath: "bindings/swift",
cSettings: [.headerSearchPath("src")])
]
)

@ -1,31 +0,0 @@
[![Build Status](https://github.com/elm-tooling/tree-sitter-elm/actions/workflows/test.yml/badge.svg)](https://github.com/elm-tooling/tree-sitter-elm/actions/workflows/test.yml)
# Elm tree sitter
## Why am I doing this?
I believe that Elm would greatly benefit from better tooling, the ultimate goal is to write a language server integration. This is a possible building block for that.
What it brings to the table:
- Very fast parsing, should enable parsing on each keystroke.
- Resilient, even if you use wrong syntax, most of the file should still be recognized alright.
- Should also be useful to the elm atom maintainers, as atom is using tree sitter as the new default for code highlighting (our ast might be too expressive). Highlight implementation still needs to be done if wanted.
## What is this tested with?
This is tested against the tests included in the repo and:
- [elm-spa-example](https://github.com/rtfeldman/elm-spa-example)
- All core elm packets from [here](https://github.com/elm)
So it should work fine for a fair amount of code. What's not tested right now is behavior in error cases.
## Thanks
Very very big thanks goes out to @klazuka and the people of [intellij-elm](https://github.com/klazuka/intellij-elm/) as I basically stole [how they're creating their parser](https://github.com/klazuka/intellij-elm/blob/master/src/main/grammars/ElmParser.bnf) minus the GLSL implementation.
## Want to help?
Help writing some tests or simply find valid elm files, that fail parsing.
Test are located in the `test` folder and separated in parser tests and highlighting tests.

@ -1,19 +0,0 @@
{
"targets": [
{
"target_name": "tree_sitter_elm_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"src/parser.c",
"bindings/node/binding.cc",
"src/scanner.c"
],
"cflags_c": [
"-std=c99",
]
}
]
}

@ -1,28 +0,0 @@
#include "tree_sitter/parser.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * tree_sitter_elm();
namespace {
NAN_METHOD(New) {}
void Init(Local<Object> exports, Local<Object> module) {
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_elm());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("elm").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(tree_sitter_elm_binding, Init)
} // namespace

@ -1,19 +0,0 @@
try {
module.exports = require("../../build/Release/tree_sitter_elm_binding");
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_elm_binding");
} catch (error2) {
if (error2.code !== 'MODULE_NOT_FOUND') {
throw error2;
}
throw error1
}
}
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}

@ -1,19 +0,0 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config.include(src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs");
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
let scanner_path = src_dir.join("scanner.c");
c_config.file(&scanner_path);
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
c_config.compile("parser");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
}

@ -1,52 +0,0 @@
//! This crate provides elm language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! let code = "";
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(tree_sitter_elm::language()).expect("Error loading elm grammar");
//! let tree = parser.parse(code, None).unwrap();
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter::Language;
extern "C" {
fn tree_sitter_elm() -> Language;
}
/// Get the tree-sitter [Language][] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_elm() }
}
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
// Uncomment these to include any queries that this grammar contains
pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(super::language())
.expect("Error loading elm language");
}
}

@ -1,16 +0,0 @@
#ifndef TREE_SITTER_ELM_H_
#define TREE_SITTER_ELM_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
extern TSLanguage *tree_sitter_elm();
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_ELM_H_

@ -1,250 +0,0 @@
<!--
Based on:
- https://github.com/tree-sitter/tree-sitter/blob/master/cli/src/web_ui.html
- https://github.com/stsewd/tree-sitter-rst/blob/master/docs/index.html
Assets from:
- https://github.com/tree-sitter/tree-sitter/blob/master/docs/assets/js/playground.js
- https://github.com/tree-sitter/tree-sitter.github.io/blob/master/tree-sitter.js
- https://github.com/tree-sitter/tree-sitter.github.io/blob/master/tree-sitter.wasm
-->
<head>
<meta charset="utf-8">
<title>Elm grammar for tree-sitter - tree-sitter-elm</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.css">
<link rel="icon" type="image/png" href="https://tree-sitter.github.io/tree-sitter/assets/images/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="https://tree-sitter.github.io/tree-sitter/assets/images/favicon-16x16.png" sizes="16x16" />
</head>
<body>
<div id="playground-container" style="visibility: hidden;">
<header>
<div class=header-item>
<bold>
<a href="https://github.com/elm-tooling/tree-sitter-elm" target="_blank">
tree-sitter-elm
</a>
</bold>
</div>
<div class=header-item>
<label for="logging-checkbox">log</label>
<input id="logging-checkbox" type="checkbox"></input>
</div>
<div class=header-item>
<label for="query-checkbox">query</label>
<input id="query-checkbox" type="checkbox"></input>
</div>
<div class=header-item>
<label for="update-time">parse time: </label>
<span id="update-time"></span>
</div>
<select id="language-select" style="display: none;">
<option value="elm">Parser</option>
</select>
</header>
<main>
<div id="input-pane">
<div id="code-container">
<textarea id="code-input"></textarea>
</div>
<div id="query-container" style="visibility: hidden; position: absolute;">
<textarea id="query-input"></textarea>
</div>
</div>
<div id="output-container-scroll">
<pre id="output-container" class="highlight"></pre>
</div>
</main>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.js"></script>
<script>LANGUAGE_BASE_URL = "js";</script>
<script src=js/tree-sitter.js></script>
<script src=js/playground.js></script>
<script>
(codeExample => {
const handle = setInterval(() => {
const $codeEditor = document.querySelector('.CodeMirror');
if ($codeEditor) {
$codeEditor.CodeMirror.setValue(codeExample);
clearInterval(handle);
}
}, 500);
})(`
module Main exposing (main)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
type alias Model =
{ count : Int }
initialModel : Model
initialModel =
{ count = 0 }
type Msg
= Increment
| Decrement
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
{ model | count = model.count + 1 }
Decrement ->
{ model | count = model.count - 1 }
view : Model -> Html Msg
view model =
div []
[ button [ onClick Increment ] [ text "+1" ]
, div [] [ text <| String.fromInt model.count ]
, button [ onClick Decrement ] [ text "-1" ]
]
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
-- This is a |elm| grammar for tree-sitter_, for contributing or report any bugs
-- check https://tree-sitter.github.io/tree-sitter/.
-- _tree-sitter: https://tree-sitter.github.io/tree-sitter/
`);
</script>
<style>
body {
margin: 0;
padding: 0;
}
#playground-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
header {
box-sizing: border-box;
display: flex;
padding: 20px;
height: 60px;
border-bottom: 1px solid #aaa;
}
main {
flex: 1;
position: relative;
}
#input-pane {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 50%;
display: flex;
flex-direction: column;
}
#code-container,
#query-container {
flex: 1;
position: relative;
overflow: hidden;
border-right: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
#output-container-scroll {
position: absolute;
top: 0;
left: 50%;
bottom: 0;
right: 0;
}
.header-item {
margin-right: 30px;
}
#playground-container .CodeMirror {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
}
#output-container-scroll {
flex: 1;
padding: 0;
overflow: auto;
}
#output-container {
padding: 0 10px;
margin: 0;
}
#logging-checkbox {
vertical-align: middle;
}
.CodeMirror div.CodeMirror-cursor {
border-left: 3px solid red;
}
a {
text-decoration: none;
color: #040404;
padding: 2px;
}
a:hover {
text-decoration: underline;
}
a.highlighted {
background-color: #d9d9d9;
color: red;
border-radius: 3px;
text-decoration: underline;
}
.query-error {
text-decoration: underline red dashed;
}
</style>
</body>

@ -1,461 +0,0 @@
let tree;
(async () => {
const CAPTURE_REGEX = /@\s*([\w\._-]+)/g;
const COLORS_BY_INDEX = [
'blue',
'chocolate',
'darkblue',
'darkcyan',
'darkgreen',
'darkred',
'darkslategray',
'dimgray',
'green',
'indigo',
'navy',
'red',
'sienna',
];
const scriptURL = document.currentScript.getAttribute('src');
const codeInput = document.getElementById('code-input');
const languageSelect = document.getElementById('language-select');
const loggingCheckbox = document.getElementById('logging-checkbox');
const outputContainer = document.getElementById('output-container');
const outputContainerScroll = document.getElementById('output-container-scroll');
const playgroundContainer = document.getElementById('playground-container');
const queryCheckbox = document.getElementById('query-checkbox');
const queryContainer = document.getElementById('query-container');
const queryInput = document.getElementById('query-input');
const updateTimeSpan = document.getElementById('update-time');
const languagesByName = {};
loadState();
await TreeSitter.init();
const parser = new TreeSitter();
const codeEditor = CodeMirror.fromTextArea(codeInput, {
lineNumbers: true,
showCursorWhenSelecting: true
});
const queryEditor = CodeMirror.fromTextArea(queryInput, {
lineNumbers: true,
showCursorWhenSelecting: true
});
const cluster = new Clusterize({
rows: [],
noDataText: null,
contentElem: outputContainer,
scrollElem: outputContainerScroll
});
const renderTreeOnCodeChange = debounce(renderTree, 50);
const saveStateOnChange = debounce(saveState, 2000);
const runTreeQueryOnChange = debounce(runTreeQuery, 50);
let languageName = languageSelect.value;
let treeRows = null;
let treeRowHighlightedIndex = -1;
let parseCount = 0;
let isRendering = 0;
let query;
codeEditor.on('changes', handleCodeChange);
codeEditor.on('viewportChange', runTreeQueryOnChange);
codeEditor.on('cursorActivity', debounce(handleCursorMovement, 150));
queryEditor.on('changes', debounce(handleQueryChange, 150));
loggingCheckbox.addEventListener('change', handleLoggingChange);
queryCheckbox.addEventListener('change', handleQueryEnableChange);
languageSelect.addEventListener('change', handleLanguageChange);
outputContainer.addEventListener('click', handleTreeClick);
handleQueryEnableChange();
await handleLanguageChange()
playgroundContainer.style.visibility = 'visible';
async function handleLanguageChange() {
const newLanguageName = languageSelect.value;
if (!languagesByName[newLanguageName]) {
const url = `${LANGUAGE_BASE_URL}/tree-sitter-${newLanguageName}.wasm`
languageSelect.disabled = true;
try {
languagesByName[newLanguageName] = await TreeSitter.Language.load(url);
} catch (e) {
console.error(e);
languageSelect.value = languageName;
return
} finally {
languageSelect.disabled = false;
}
}
tree = null;
languageName = newLanguageName;
parser.setLanguage(languagesByName[newLanguageName]);
handleCodeChange();
handleQueryChange();
}
async function handleCodeChange(editor, changes) {
const newText = codeEditor.getValue() + '\n';
const edits = tree && changes && changes.map(treeEditForEditorChange);
const start = performance.now();
if (edits) {
for (const edit of edits) {
tree.edit(edit);
}
}
const newTree = parser.parse(newText, tree);
const duration = (performance.now() - start).toFixed(1);
updateTimeSpan.innerText = `${duration} ms`;
if (tree) tree.delete();
tree = newTree;
parseCount++;
renderTreeOnCodeChange();
runTreeQueryOnChange();
saveStateOnChange();
}
async function renderTree() {
isRendering++;
const cursor = tree.walk();
let currentRenderCount = parseCount;
let row = '';
let rows = [];
let finishedRow = false;
let visitedChildren = false;
let indentLevel = 0;
for (let i = 0;; i++) {
if (i > 0 && i % 10000 === 0) {
await new Promise(r => setTimeout(r, 0));
if (parseCount !== currentRenderCount) {
cursor.delete();
isRendering--;
return;
}
}
let displayName;
if (cursor.nodeIsMissing) {
displayName = `MISSING ${cursor.nodeType}`
} else if (cursor.nodeIsNamed) {
displayName = cursor.nodeType;
}
if (visitedChildren) {
if (displayName) {
finishedRow = true;
}
if (cursor.gotoNextSibling()) {
visitedChildren = false;
} else if (cursor.gotoParent()) {
visitedChildren = true;
indentLevel--;
} else {
break;
}
} else {
if (displayName) {
if (finishedRow) {
row += '</div>';
rows.push(row);
finishedRow = false;
}
const start = cursor.startPosition;
const end = cursor.endPosition;
const id = cursor.nodeId;
let fieldName = cursor.currentFieldName();
if (fieldName) {
fieldName += ': ';
} else {
fieldName = '';
}
row = `<div>${' '.repeat(indentLevel)}${fieldName}<a class='plain' href="#" data-id=${id} data-range="${start.row},${start.column},${end.row},${end.column}">${displayName}</a> [${start.row}, ${start.column}] - [${end.row}, ${end.column}]`;
finishedRow = true;
}
if (cursor.gotoFirstChild()) {
visitedChildren = false;
indentLevel++;
} else {
visitedChildren = true;
}
}
}
if (finishedRow) {
row += '</div>';
rows.push(row);
}
cursor.delete();
cluster.update(rows);
treeRows = rows;
isRendering--;
handleCursorMovement();
}
function runTreeQuery(_, startRow, endRow) {
if (endRow == null) {
const viewport = codeEditor.getViewport();
startRow = viewport.from;
endRow = viewport.to;
}
codeEditor.operation(() => {
const marks = codeEditor.getAllMarks();
marks.forEach(m => m.clear());
if (tree && query) {
const captures = query.captures(
tree.rootNode,
{row: startRow, column: 0},
{row: endRow, column: 0},
);
let lastNodeId;
for (const {name, node} of captures) {
if (node.id === lastNodeId) continue;
lastNodeId = node.id;
const {startPosition, endPosition} = node;
codeEditor.markText(
{line: startPosition.row, ch: startPosition.column},
{line: endPosition.row, ch: endPosition.column},
{
inclusiveLeft: true,
inclusiveRight: true,
css: `color: ${colorForCaptureName(name)}`
}
);
}
}
});
}
function handleQueryChange() {
if (query) {
query.delete();
query.deleted = true;
query = null;
}
queryEditor.operation(() => {
queryEditor.getAllMarks().forEach(m => m.clear());
if (!queryCheckbox.checked) return;
const queryText = queryEditor.getValue();
try {
query = parser.getLanguage().query(queryText);
let match;
let row = 0;
queryEditor.eachLine((line) => {
while (match = CAPTURE_REGEX.exec(line.text)) {
queryEditor.markText(
{line: row, ch: match.index},
{line: row, ch: match.index + match[0].length},
{
inclusiveLeft: true,
inclusiveRight: true,
css: `color: ${colorForCaptureName(match[1])}`
}
);
}
row++;
});
} catch (error) {
const startPosition = queryEditor.posFromIndex(error.index);
const endPosition = {
line: startPosition.line,
ch: startPosition.ch + (error.length || Infinity)
};
if (error.index === queryText.length) {
if (startPosition.ch > 0) {
startPosition.ch--;
} else if (startPosition.row > 0) {
startPosition.row--;
startPosition.column = Infinity;
}
}
queryEditor.markText(
startPosition,
endPosition,
{
className: 'query-error',
inclusiveLeft: true,
inclusiveRight: true,
attributes: {title: error.message}
}
);
}
});
runTreeQuery();
saveQueryState();
}
function handleCursorMovement() {
if (isRendering) return;
const selection = codeEditor.getDoc().listSelections()[0];
let start = {row: selection.anchor.line, column: selection.anchor.ch};
let end = {row: selection.head.line, column: selection.head.ch};
if (
start.row > end.row ||
(
start.row === end.row &&
start.column > end.column
)
) {
let swap = end;
end = start;
start = swap;
}
const node = tree.rootNode.namedDescendantForPosition(start, end);
if (treeRows) {
if (treeRowHighlightedIndex !== -1) {
const row = treeRows[treeRowHighlightedIndex];
if (row) treeRows[treeRowHighlightedIndex] = row.replace('highlighted', 'plain');
}
treeRowHighlightedIndex = treeRows.findIndex(row => row.includes(`data-id=${node.id}`));
if (treeRowHighlightedIndex !== -1) {
const row = treeRows[treeRowHighlightedIndex];
if (row) treeRows[treeRowHighlightedIndex] = row.replace('plain', 'highlighted');
}
cluster.update(treeRows);
const lineHeight = cluster.options.item_height;
const scrollTop = outputContainerScroll.scrollTop;
const containerHeight = outputContainerScroll.clientHeight;
const offset = treeRowHighlightedIndex * lineHeight;
if (scrollTop > offset - 20) {
$(outputContainerScroll).animate({scrollTop: offset - 20}, 150);
} else if (scrollTop < offset + lineHeight + 40 - containerHeight) {
$(outputContainerScroll).animate({scrollTop: offset - containerHeight + 40}, 150);
}
}
}
function handleTreeClick(event) {
if (event.target.tagName === 'A') {
event.preventDefault();
const [startRow, startColumn, endRow, endColumn] = event
.target
.dataset
.range
.split(',')
.map(n => parseInt(n));
codeEditor.focus();
codeEditor.setSelection(
{line: startRow, ch: startColumn},
{line: endRow, ch: endColumn}
);
}
}
function handleLoggingChange() {
if (loggingCheckbox.checked) {
parser.setLogger((message, lexing) => {
if (lexing) {
console.log(" ", message)
} else {
console.log(message)
}
});
} else {
parser.setLogger(null);
}
}
function handleQueryEnableChange() {
if (queryCheckbox.checked) {
queryContainer.style.visibility = '';
queryContainer.style.position = '';
} else {
queryContainer.style.visibility = 'hidden';
queryContainer.style.position = 'absolute';
}
handleQueryChange();
}
function treeEditForEditorChange(change) {
const oldLineCount = change.removed.length;
const newLineCount = change.text.length;
const lastLineLength = change.text[newLineCount - 1].length;
const startPosition = {row: change.from.line, column: change.from.ch};
const oldEndPosition = {row: change.to.line, column: change.to.ch};
const newEndPosition = {
row: startPosition.row + newLineCount - 1,
column: newLineCount === 1
? startPosition.column + lastLineLength
: lastLineLength
};
const startIndex = codeEditor.indexFromPos(change.from);
let newEndIndex = startIndex + newLineCount - 1;
let oldEndIndex = startIndex + oldLineCount - 1;
for (let i = 0; i < newLineCount; i++) newEndIndex += change.text[i].length;
for (let i = 0; i < oldLineCount; i++) oldEndIndex += change.removed[i].length;
return {
startIndex, oldEndIndex, newEndIndex,
startPosition, oldEndPosition, newEndPosition
};
}
function colorForCaptureName(capture) {
const id = query.captureNames.indexOf(capture);
return COLORS_BY_INDEX[id % COLORS_BY_INDEX.length];
}
function loadState() {
const language = localStorage.getItem("language");
const sourceCode = localStorage.getItem("sourceCode");
const query = localStorage.getItem("query");
const queryEnabled = localStorage.getItem("queryEnabled");
if (language != null && sourceCode != null && query != null) {
queryInput.value = query;
codeInput.value = sourceCode;
languageSelect.value = language;
queryCheckbox.checked = (queryEnabled === 'true');
}
}
function saveState() {
localStorage.setItem("language", languageSelect.value);
localStorage.setItem("sourceCode", codeEditor.getValue());
saveQueryState();
}
function saveQueryState() {
localStorage.setItem("queryEnabled", queryCheckbox.checked);
localStorage.setItem("query", queryEditor.getValue());
}
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,46 +0,0 @@
{
"name": "@elm-tooling/tree-sitter-elm",
"version": "5.7.0",
"description": "Tree sitter definitions for elm",
"main": "bindings/node",
"publishConfig": {
"access": "public"
},
"keywords": [
"elm",
"elm-lang",
"tree-sitter",
"parser",
"lexer"
],
"author": "Razze",
"license": "MIT",
"dependencies": {
"nan": "^2.18.0"
},
"devDependencies": {
"tree-sitter-cli": "^0.20.8"
},
"scripts": {
"build": "tree-sitter generate",
"parse-basic": "tree-sitter parse ./examples/basic.elm",
"parse-test": "tree-sitter parse --debug ./examples/test.elm",
"test": "tree-sitter test && script/parse-examples",
"test-skip-download": "tree-sitter test && script/parse-examples -s",
"test-full": "tree-sitter test && script/parse-examples-full",
"test-full-skip-download": "tree-sitter test && script/parse-examples-full -s",
"test-only": "tree-sitter test",
"test-highlighting": "tree-sitter highlight test/highlight/basic.elm",
"test-tags": "tree-sitter tags test/highlight/basic.elm",
"generate-wasm": "tree-sitter build-wasm && mv ./tree-sitter-elm.wasm ./docs/js/tree-sitter-elm.wasm"
},
"repository": "https://github.com/elm-tooling/tree-sitter-elm",
"tree-sitter": [
{
"scope": "source.elm",
"file-types": [
"elm"
]
}
]
}

@ -1,76 +0,0 @@
; Keywords
[
"if"
"then"
"else"
"let"
"in"
] @keyword.control.elm
(case) @keyword.control.elm
(of) @keyword.control.elm
(colon) @keyword.other.elm
(backslash) @keyword.other.elm
(as) @keyword.other.elm
(port) @keyword.other.elm
(exposing) @keyword.other.elm
(alias) @keyword.other.elm
(infix) @keyword.other.elm
(arrow) @keyword.operator.arrow.elm
(port) @keyword.other.port.elm
(type_annotation(lower_case_identifier) @function.elm)
(port_annotation(lower_case_identifier) @function.elm)
(function_declaration_left(lower_case_identifier) @function.elm)
(function_call_expr target: (value_expr) @function.elm)
(field_access_expr(value_expr(value_qid)) @local.function.elm)
(lower_pattern) @local.function.elm
(record_base_identifier) @local.function.elm
(operator_identifier) @keyword.operator.elm
(eq) @keyword.operator.assignment.elm
"(" @punctuation.section.braces
")" @punctuation.section.braces
"|" @keyword.other.elm
"," @punctuation.separator.comma.elm
(import) @meta.import.elm
(module) @keyword.other.elm
(number_constant_expr) @constant.numeric.elm
(type) @keyword.type.elm
(type_declaration(upper_case_identifier) @storage.type.elm)
(type_ref) @storage.type.elm
(type_alias_declaration name: (upper_case_identifier) @storage.type.elm)
(union_variant(upper_case_identifier) @union.elm)
(union_pattern) @union.elm
(value_expr(upper_case_qid(upper_case_identifier)) @union.elm)
; comments
(line_comment) @comment.elm
(block_comment) @comment.elm
; strings
(string_escape) @character.escape.elm
(open_quote) @string.elm
(close_quote) @string.elm
(regular_string_part) @string.elm
(open_char) @char.elm
(close_char) @char.elm
; glsl
(glsl_content) @source.glsl

@ -1,4 +0,0 @@
; Parse glsl where defined
((glsl_content) @injection.content
(#set! injection.language "glsl"))

@ -1,15 +0,0 @@
(value_declaration) @local.scope
(type_alias_declaration) @local.scope
(type_declaration) @local.scope
(type_annotation) @local.scope
(port_annotation) @local.scope
(infix_declaration) @local.scope
(let_in_expr) @local.scope
(function_declaration_left (lower_pattern (lower_case_identifier)) @local.definition)
(function_declaration_left (lower_case_identifier) @local.definition)
(value_expr(value_qid(upper_case_identifier)) @local.reference)
(value_expr(value_qid(lower_case_identifier)) @local.reference)
(type_ref (upper_case_qid) @local.reference)

@ -1,19 +0,0 @@
(value_declaration (function_declaration_left (lower_case_identifier) @name)) @definition.function
(function_call_expr (value_expr (value_qid) @name)) @reference.function
(exposed_value (lower_case_identifier) @name) @reference.function
(type_annotation ((lower_case_identifier) @name) (colon)) @reference.function
(type_declaration ((upper_case_identifier) @name) ) @definition.type
(type_ref (upper_case_qid (upper_case_identifier) @name)) @reference.type
(exposed_type (upper_case_identifier) @name) @reference.type
(type_declaration (union_variant (upper_case_identifier) @name)) @definition.union
(value_expr (upper_case_qid (upper_case_identifier) @name)) @reference.union
(module_declaration
(upper_case_qid (upper_case_identifier)) @name
) @definition.module

@ -1,18 +0,0 @@
[
"rtfeldman/elm-spa-example",
"andys8/vim-emulation",
"DoctypeRosenthal/mindmap",
"RalfNorthman/adding-boxes",
"mosmos21/elm-todo",
"wolmir/conta-invaders",
"ryannhg/love-your-humans",
"smith-30/elm-login",
"jxxcarlson/elm-shared-state",
"doubledup/initiative_tracker",
"RaoKrishna/elm-poc",
"visotype/state-machine",
"Chadtech/elm-europe-2019-talk",
"mathiajusth/gravity",
"Vynlar/time-tracker",
"xbmc/elm-chorus"
]

@ -1,39 +0,0 @@
[
"1602/json-value",
"1602/json-schema",
"Chadtech/elm-imperative-porting",
"JonRowe/elm-jwt",
"NoRedInk/elm-formatted-text-19",
"NoRedInk/elm-plot-19",
"NoRedInk/style-elements",
"YuyaAizawa/peg",
"alex-tan/elm-dialog",
"alex-tan/elm-tree-diagram",
"alexanderkiel/list-selection",
"altayaydemir/style-elements",
"mdgriffith/style-elements",
"terezka/elm-charts-alpha",
"terezka/line-charts",
"the-sett/the-sett-laf",
"zwilias/json-decode-exploration",
"truqu/line-charts",
"tomjkidd/elm-multiway-tree-zipper",
"rtfeldman/elm-sorter-experiment",
"ianmackenzie/elm-geometry-prerelease",
"folkertdev/elm-state",
"folkertdev/one-true-path-experiment",
"elm-explorations/test",
"HAN-ASD-DT/priority-queue",
"HAN-ASD-DT/rsa",
"abradley2/form-controls",
"abradley2/form-fields",
"altjsus/elm-airtable",
"nik-garmash/elm-test",
"not1602/elm-feather",
"ozyinc/elm-sortable-table-with-row-id",
"peterszerzo/elm-natural-ui",
"m-mullins/elm-console",
"nathanjohnson320/elm-ui-components",
"proda-ai/elm-logger"
]

@ -1,2 +0,0 @@
// This is only for reference and not used automatically
examples-full/MacCASOutreach/graphicsvg/src/GraphicSVG/Widget.elm // Errors, but intelliJ does the same

@ -1 +0,0 @@
examples/elm-ui/tests-rendering/automation/templates/Run.elm

@ -1,79 +0,0 @@
#!/bin/bash
cd "$(dirname "$0")/.."
function checkout_at() {
repo=$1; url=$2; sha=$3
if [ ! -d "$repo" ]; then
git clone "https://github.com/$url" "$repo"
fi
pushd "$repo"
git fetch && git reset --hard "$sha"
popd
}
# Define list of arguments expected in the input
optstring="s"
while getopts ${optstring} arg; do
case ${arg} in
s)
SKIP_DOWNLOAD='true'
echo "Skip download"
;;
?)
echo "Invalid option: -${OPTARG}."
;;
esac
done
if [[ $SKIP_DOWNLOAD != 'true' ]]; then
checkout_at "examples/elm-spa-example" "rtfeldman/elm-spa-example" "c8c3201ec0488f17c1245e1fd2293ba5bc0748d5"
checkout_at "examples/elm-browser" "elm/browser" "1d28cd625b3ce07be6dfad51660bea6de2c905f2"
checkout_at "examples/elm-bytes" "elm/bytes" "2bce2aeda4ef18c3dcccd84084647d22a7af36a6"
checkout_at "examples/elm-core" "elm/core" "65cea00afa0de03d7dda0487d964a305fc3d58e3"
checkout_at "examples/elm-file" "elm/file" "e4ca3864c93a5e766e24ed6916174753567b2f59"
checkout_at "examples/elm-html" "elm/html" "94c079007f8a7ed282d5b53f4a49101dd0b6cf99"
checkout_at "examples/elm-http" "elm/http" "81b6fdc67d8e5fb25644fd79e6b0edbe2e14e474"
checkout_at "examples/elm-json" "elm/json" "0206c00884af953f2cba8823fee111ee71a0330e"
checkout_at "examples/elm-parser" "elm/parser" "7506b07eaa93a93d13b508b948c016105b0953c8"
checkout_at "examples/elm-project-metadata-utils" "elm/project-metadata-utils" "831733724fb2b59b38ba1639e6503d97607dbd9d"
checkout_at "examples/elm-random" "elm/random" "ecf97bb43f0d5cd75243428f69f45323957bda25"
checkout_at "examples/elm-regex" "elm/regex" "8810c41fb17ddf89165665489be213f44070bc4a"
checkout_at "examples/elm-svg" "elm/svg" "08bd432990862bab5b840654dd437fbb2e6176e7"
checkout_at "examples/elm-time" "elm/time" "dc3b75b7366e59b99962706f7bf064d3634a4bba"
checkout_at "examples/elm-url" "elm/url" "4e5ee032515581bf01428d54ee636dd601f4bc90"
checkout_at "examples/elm-virtual-dom" "elm/virtual-dom" "44cbe2bf3d598cab569045cefcc10de31907598d"
checkout_at "examples/elm-ui" "mdgriffith/elm-ui" "acae8857a02e600cc4b4737ca2f70607228b4489"
checkout_at "examples/elm-markup" "mdgriffith/elm-markup" "b073d85490f71c6491648bcd0b11bf9aca6e53a5"
checkout_at "examples/elm-visualization" "gampleman/elm-visualization" "6b9c7476507cedbbd8fc841fdecb59f4af2c3f96"
fi
skipped_files=()
examples_to_parse=()
all_examples=$(find examples -name '*.elm')
known_failures=$(cat script/known-failures.txt)
for example in $all_examples; do
if [[ ! $known_failures == *$example* ]]; then
examples_to_parse+=($example)
else
skipped_files+=($example)
fi
done
start=`date +%s.%N`
tree_sitter_report=$(echo ${examples_to_parse[@]} | xargs -n 100000 npx tree-sitter parse --quiet --stat)
end=`date +%s.%N`
ret_code=$?
echo -e "-----------------------------------------------------------------\n$tree_sitter_report \n -----------------------------------------------------------------\n"
skipped=$( echo ${#skipped_files[@]} )
# This doesn't work on macos due to how date is used and will default to empty
runtime=$( echo "$end - $start" | bc -l )
printf "Skipped: %d \nTook: %s\n" $skipped $runtime
exit $ret_code

@ -1,65 +0,0 @@
#!/bin/bash
cd "$(dirname "$0")/.."
function checkout() {
repo=$1; url=$2;
if [ ! -d "$repo" ]; then
git clone "https://github.com/$url" "$repo"
fi
pushd "$repo"
git fetch && git reset --hard HEAD
popd
}
# Define list of arguments expected in the input
optstring="s"
while getopts ${optstring} arg; do
case ${arg} in
s)
SKIP_DOWNLOAD='true'
echo "Skip download"
;;
?)
echo "Invalid option: -${OPTARG}."
;;
esac
done
echo "Finding libs"
libs_to_parse=$(grep -Po '"name":.*?[^\\]",' ./script/search.json | perl -pe 's/"name": "//; s/^"//; s/",$//')
libs_not_to_parse=$(grep -Po '".+"' ./script/error-packages.json | perl -pe 's/^"//; s/"$//')
for lib in $libs_to_parse; do
if [[ $libs_not_to_parse != *$lib* && $SKIP_DOWNLOAD != 'true' ]]; then
echo $lib
checkout "examples-full/$lib" "$lib"
fi
done
echo "Finding applications"
applications_to_parse=$(grep -Po '".+"' ./script/applications.json | perl -pe 's/^"//; s/"$//')
if [[ $SKIP_DOWNLOAD != 'true' ]]; then
for project in $applications_to_parse; do
echo $project
checkout "examples-full/$project" "$project"
done
fi
start=`date +%s.%N`
tree_sitter_report=$(npx tree-sitter parse examples-full/**/*.elm --quiet --stat)
end=`date +%s.%N`
ret_code=$?
echo -e "-----------------------------------------------------------------\n$tree_sitter_report \n -----------------------------------------------------------------\n"
runtime=$( echo "$end - $start" | bc -l )
printf "Took: %s\n" $runtime
exit $ret_code

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,496 +0,0 @@
#include "tree_sitter/parser.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define VEC_RESIZE(vec, _cap) \
void *tmp = realloc((vec).data, (_cap) * sizeof((vec).data[0])); \
assert(tmp != NULL); \
(vec).data = tmp; \
assert((vec).data != NULL); \
(vec).cap = (_cap);
#define VEC_GROW(vec, _cap) \
if ((vec).cap < (_cap)) { \
VEC_RESIZE((vec), (_cap)); \
}
#define VEC_PUSH(vec, el) \
if ((vec).cap == (vec).len) { \
VEC_RESIZE((vec), MAX(16, (vec).len * 2)); \
} \
(vec).data[(vec).len++] = (el);
#define VEC_POP(vec) (vec).len--;
#define VEC_BACK(vec) ((vec).data[(vec).len - 1])
#define VEC_FREE(vec) \
{ \
if ((vec).data != NULL) \
free((vec).data); \
}
#define VEC_CLEAR(vec) (vec).len = 0;
#define VEC_REVERSE(vec) \
do { \
if ((vec).len > 1) { \
for (size_t i = 0, j = (vec).len - 1; i < j; i++, j--) { \
uint8_t tmp = (vec).data[i]; \
(vec).data[i] = (vec).data[j]; \
(vec).data[j] = tmp; \
} \
} \
} while (0)
enum TokenType {
VIRTUAL_END_DECL,
VIRTUAL_OPEN_SECTION,
VIRTUAL_END_SECTION,
MINUS_WITHOUT_TRAILING_WHITESPACE,
GLSL_CONTENT,
BLOCK_COMMENT_CONTENT,
};
typedef struct {
uint32_t len;
uint32_t cap;
uint8_t *data;
} vec;
typedef struct {
uint32_t indent_length;
vec indents;
vec runback;
} Scanner;
static inline void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
static inline void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
// > You can detect error recovery in the external scanner by the fact that
// > _all_ tokens are considered valid at once.
// https://github.com/tree-sitter/tree-sitter/pull/1783#issuecomment-1181011411
static bool in_error_recovery(const bool *valid_symbols) {
return (valid_symbols[VIRTUAL_END_DECL] &&
valid_symbols[VIRTUAL_OPEN_SECTION] &&
valid_symbols[VIRTUAL_END_SECTION] &&
valid_symbols[MINUS_WITHOUT_TRAILING_WHITESPACE] &&
valid_symbols[GLSL_CONTENT] &&
valid_symbols[BLOCK_COMMENT_CONTENT]);
}
static bool is_elm_space(TSLexer *lexer) {
return lexer->lookahead == ' ' || lexer->lookahead == '\r' ||
lexer->lookahead == '\n';
}
static int checkForIn(TSLexer *lexer, const bool *valid_symbols) {
// Are we at the end of a let (in) declaration
if (valid_symbols[VIRTUAL_END_SECTION] && lexer->lookahead == 'i') {
skip(lexer);
if (lexer->lookahead == 'n') {
skip(lexer);
if (is_elm_space(lexer) || lexer->eof(lexer)) {
return 2; // Success
}
return 1; // Partial
}
return 1; // Partial
}
return 0;
}
static bool scan_block_comment(TSLexer *lexer) {
lexer->mark_end(lexer);
if (lexer->lookahead != '{') {
return false;
}
advance(lexer);
if (lexer->lookahead != '-') {
return false;
}
advance(lexer);
while (true) {
switch (lexer->lookahead) {
case '{':
scan_block_comment(lexer);
break;
case '-':
advance(lexer);
if (lexer->lookahead == '}') {
advance(lexer);
return true;
}
break;
case '\0':
return true;
default:
advance(lexer);
}
}
}
static void advance_to_line_end(TSLexer *lexer) {
while (true) {
if (lexer->lookahead == '\n' || lexer->eof(lexer)) {
break;
}
advance(lexer);
}
}
static bool scan(Scanner *scanner, TSLexer *lexer, const bool *valid_symbols) {
if (in_error_recovery(valid_symbols)) {
return false;
}
// First handle eventual runback tokens, we saved on a previous scan op
if (scanner->runback.len > 0 && VEC_BACK(scanner->runback) == 0 &&
valid_symbols[VIRTUAL_END_DECL]) {
VEC_POP(scanner->runback);
lexer->result_symbol = VIRTUAL_END_DECL;
return true;
}
if (scanner->runback.len > 0 && VEC_BACK(scanner->runback) == 1 &&
valid_symbols[VIRTUAL_END_SECTION]) {
VEC_POP(scanner->runback);
lexer->result_symbol = VIRTUAL_END_SECTION;
return true;
}
VEC_CLEAR(scanner->runback);
// Check if we have newlines and how much indentation
bool has_newline = false;
bool found_in = false;
bool can_call_mark_end = true;
lexer->mark_end(lexer);
while (true) {
if (lexer->lookahead == ' ' || lexer->lookahead == '\r') {
skip(lexer);
} else if (lexer->lookahead == '\n') {
skip(lexer);
has_newline = true;
while (true) {
if (lexer->lookahead == ' ') {
skip(lexer);
} else {
scanner->indent_length = lexer->get_column(lexer);
break;
}
}
} else if (!valid_symbols[BLOCK_COMMENT_CONTENT] &&
lexer->lookahead == '-') {
advance(lexer);
int32_t lookahead = lexer->lookahead;
// Handle minus without a whitespace for negate
if (valid_symbols[MINUS_WITHOUT_TRAILING_WHITESPACE] &&
((lookahead >= 'a' && lookahead <= 'z') ||
(lookahead >= 'A' && lookahead <= 'Z') || lookahead == '(')) {
if (can_call_mark_end) {
lexer->result_symbol = MINUS_WITHOUT_TRAILING_WHITESPACE;
lexer->mark_end(lexer);
return true;
}
return false;
}
// Scan past line comments. As far as the special token
// types we're scanning for here are concerned line comments
// are like whitespace. There is nothing useful to be
// learned from, say, their indentation. So we advance past
// them here.
//
// The one thing we need to keep in mind is that we should
// not call `lexer->mark_end(lexer)` after this point, or
// the comment will be lost.
if (lookahead == '-' && has_newline) {
can_call_mark_end = false;
advance(lexer);
advance_to_line_end(lexer);
} else if (valid_symbols[BLOCK_COMMENT_CONTENT] &&
lexer->lookahead == '}') {
lexer->result_symbol = BLOCK_COMMENT_CONTENT;
return true;
} else {
return false;
}
} else if (lexer->eof(lexer)) {
if (valid_symbols[VIRTUAL_END_SECTION]) {
lexer->result_symbol = VIRTUAL_END_SECTION;
return true;
}
if (valid_symbols[VIRTUAL_END_DECL]) {
lexer->result_symbol = VIRTUAL_END_DECL;
return true;
}
break;
} else {
break;
}
}
if (checkForIn(lexer, valid_symbols) == 2) {
if (has_newline) {
found_in = true;
} else {
lexer->result_symbol = VIRTUAL_END_SECTION;
VEC_POP(scanner->indents);
return true;
}
}
// Open section if the grammar lets us but only push to indent stack if
// we go further down in the stack
if (valid_symbols[VIRTUAL_OPEN_SECTION] && !lexer->eof(lexer)) {
VEC_PUSH(scanner->indents, lexer->get_column(lexer));
lexer->result_symbol = VIRTUAL_OPEN_SECTION;
return true;
}
if (valid_symbols[BLOCK_COMMENT_CONTENT]) {
if (!can_call_mark_end) {
return false;
}
lexer->mark_end(lexer);
while (true) {
if (lexer->lookahead == '\0') {
break;
}
if (lexer->lookahead != '{' && lexer->lookahead != '-') {
advance(lexer);
} else if (lexer->lookahead == '-') {
lexer->mark_end(lexer);
advance(lexer);
if (lexer->lookahead == '}') {
break;
}
} else if (scan_block_comment(lexer)) {
lexer->mark_end(lexer);
advance(lexer);
if (lexer->lookahead == '-') {
break;
}
}
}
lexer->result_symbol = BLOCK_COMMENT_CONTENT;
return true;
}
if (has_newline) {
// We had a newline now it's time to check if we need to add
// multiple tokens to get back up to the right level
VEC_CLEAR(scanner->runback);
while (scanner->indent_length <= VEC_BACK(scanner->indents)) {
if (scanner->indent_length == VEC_BACK(scanner->indents)) {
if (found_in) {
VEC_PUSH(scanner->runback, 1);
found_in = false;
break;
}
// Don't insert VIRTUAL_END_DECL when there is a line
// comment incoming
if (lexer->lookahead == '-') {
skip(lexer);
if (lexer->lookahead == '-') {
break;
}
}
// Don't insert VIRTUAL_END_DECL when there is a block
// comment incoming
if (lexer->lookahead == '{') {
skip(lexer);
if (lexer->lookahead == '-') {
break;
}
}
VEC_PUSH(scanner->runback, 0);
break;
}
if (scanner->indent_length < VEC_BACK(scanner->indents)) {
VEC_POP(scanner->indents);
VEC_PUSH(scanner->runback, 1);
found_in = false;
}
}
// Needed for some of the more weird cases where let is in the same
// line as everything before the in in the next line
if (found_in) {
VEC_PUSH(scanner->runback, 1);
found_in = false;
}
// Our list is the wrong way around, reverse it
VEC_REVERSE(scanner->runback);
// Handle the first runback token if we have them, if there are more
// they will be handled on the next scan operation
if (scanner->runback.len > 0 && VEC_BACK(scanner->runback) == 0 &&
valid_symbols[VIRTUAL_END_DECL]) {
VEC_POP(scanner->runback);
lexer->result_symbol = VIRTUAL_END_DECL;
return true;
}
if (scanner->runback.len > 0 && VEC_BACK(scanner->runback) == 1 &&
valid_symbols[VIRTUAL_END_SECTION]) {
VEC_POP(scanner->runback);
lexer->result_symbol = VIRTUAL_END_SECTION;
return true;
}
if (lexer->eof(lexer) && valid_symbols[VIRTUAL_END_SECTION]) {
lexer->result_symbol = VIRTUAL_END_SECTION;
return true;
}
}
if (valid_symbols[GLSL_CONTENT]) {
if (!can_call_mark_end) {
return false;
}
lexer->result_symbol = GLSL_CONTENT;
while (true) {
switch (lexer->lookahead) {
case '|':
lexer->mark_end(lexer);
advance(lexer);
if (lexer->lookahead == ']') {
advance(lexer);
return true;
}
break;
case '\0':
lexer->mark_end(lexer);
return true;
default:
advance(lexer);
}
}
}
return false;
}
// --------------------------------------------------------------------------------------------------------
// API
// --------------------------------------------------------------------------------------------------------
/**
* This function allocates the persistent state of the parser that is passed
* into the other API functions.
*/
void *tree_sitter_elm_external_scanner_create() {
Scanner *scanner = (Scanner *)calloc(1, sizeof(Scanner));
return scanner;
}
/**
* Main logic entry point.
* Since the state is a singular vector, it can just be cast and used directly.
*/
bool tree_sitter_elm_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
Scanner *scanner = (Scanner *)payload;
return scan(scanner, lexer, valid_symbols);
}
/**
* Copy the current state to another location for later reuse.
* This is normally more complex, but since this parser's state constists solely
* of a vector of integers, it can just be copied.
*/
unsigned tree_sitter_elm_external_scanner_serialize(void *payload,
char *buffer) {
Scanner *scanner = (Scanner *)payload;
size_t size = 0;
if (3 + scanner->indents.len + scanner->runback.len >=
TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
return 0;
}
size_t runback_count = scanner->runback.len;
if (runback_count > UINT8_MAX) {
runback_count = UINT8_MAX;
}
buffer[size++] = (char)runback_count;
if (runback_count > 0) {
memcpy(&buffer[size], scanner->runback.data, runback_count);
}
size += runback_count;
size_t indent_length_length = sizeof(scanner->indent_length);
buffer[size++] = (char)indent_length_length;
if (indent_length_length > 0) {
memcpy(&buffer[size], &scanner->indent_length, indent_length_length);
}
size += indent_length_length;
int iter = 1;
for (; iter != scanner->indents.len &&
size < TREE_SITTER_SERIALIZATION_BUFFER_SIZE;
++iter) {
buffer[size++] = (char)scanner->indents.data[iter];
}
return size;
}
/**
* Load another parser state into the currently active state.
* `payload` is the state of the previous parser execution, while `buffer` is
* the saved state of a different position (e.g. when doing incremental
* parsing).
*/
void tree_sitter_elm_external_scanner_deserialize(void *payload,
const char *buffer,
unsigned length) {
Scanner *scanner = (Scanner *)payload;
VEC_CLEAR(scanner->runback);
VEC_CLEAR(scanner->indents);
VEC_PUSH(scanner->indents, 0);
if (length == 0) {
return;
}
size_t size = 0;
size_t runback_count = (unsigned char)buffer[size++];
VEC_GROW(scanner->runback, runback_count)
if (runback_count > 0) {
memcpy(scanner->runback.data, &buffer[size], runback_count);
scanner->runback.len = runback_count;
size += runback_count;
}
size_t indent_length_length = (unsigned char)buffer[size++];
if (indent_length_length > 0) {
memcpy(&scanner->indent_length, &buffer[size], indent_length_length);
size += indent_length_length;
}
for (; size < length; size++) {
VEC_PUSH(scanner->indents, (unsigned char)buffer[size]);
}
assert(size == length);
}
/**
* Destroy the state.
*/
void tree_sitter_elm_external_scanner_destroy(void *payload) {
Scanner *scanner = (Scanner *)payload;
VEC_FREE(scanner->indents);
VEC_FREE(scanner->runback);
free(scanner);
}

@ -1,224 +0,0 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define ts_builtin_sym_error ((TSSymbol)-1)
#define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
typedef uint16_t TSStateId;
#ifndef TREE_SITTER_API_H_
typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage;
#endif
typedef struct {
TSFieldId field_id;
uint8_t child_index;
bool inherited;
} TSFieldMapEntry;
typedef struct {
uint16_t index;
uint16_t length;
} TSFieldMapSlice;
typedef struct {
bool visible;
bool named;
bool supertype;
} TSSymbolMetadata;
typedef struct TSLexer TSLexer;
struct TSLexer {
int32_t lookahead;
TSSymbol result_symbol;
void (*advance)(TSLexer *, bool);
void (*mark_end)(TSLexer *);
uint32_t (*get_column)(TSLexer *);
bool (*is_at_included_range_start)(const TSLexer *);
bool (*eof)(const TSLexer *);
};
typedef enum {
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
TSParseActionTypeRecover,
} TSParseActionType;
typedef union {
struct {
uint8_t type;
TSStateId state;
bool extra;
bool repetition;
} shift;
struct {
uint8_t type;
uint8_t child_count;
TSSymbol symbol;
int16_t dynamic_precedence;
uint16_t production_id;
} reduce;
uint8_t type;
} TSParseAction;
typedef struct {
uint16_t lex_state;
uint16_t external_lex_state;
} TSLexMode;
typedef union {
TSParseAction action;
struct {
uint8_t count;
bool reusable;
} entry;
} TSParseActionEntry;
struct TSLanguage {
uint32_t version;
uint32_t symbol_count;
uint32_t alias_count;
uint32_t token_count;
uint32_t external_token_count;
uint32_t state_count;
uint32_t large_state_count;
uint32_t production_id_count;
uint32_t field_count;
uint16_t max_alias_sequence_length;
const uint16_t *parse_table;
const uint16_t *small_parse_table;
const uint32_t *small_parse_table_map;
const TSParseActionEntry *parse_actions;
const char * const *symbol_names;
const char * const *field_names;
const TSFieldMapSlice *field_map_slices;
const TSFieldMapEntry *field_map_entries;
const TSSymbolMetadata *symbol_metadata;
const TSSymbol *public_symbol_map;
const uint16_t *alias_map;
const TSSymbol *alias_sequences;
const TSLexMode *lex_modes;
bool (*lex_fn)(TSLexer *, TSStateId);
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
TSSymbol keyword_capture_token;
struct {
const bool *states;
const TSSymbol *symbol_map;
void *(*create)(void);
void (*destroy)(void *);
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
unsigned (*serialize)(void *, char *);
void (*deserialize)(void *, const char *, unsigned);
} external_scanner;
const TSStateId *primary_state_ids;
};
/*
* Lexer Macros
*/
#define START_LEXER() \
bool result = false; \
bool skip = false; \
bool eof = false; \
int32_t lookahead; \
goto start; \
next_state: \
lexer->advance(lexer, skip); \
start: \
skip = false; \
lookahead = lexer->lookahead;
#define ADVANCE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define SKIP(state_value) \
{ \
skip = true; \
state = state_value; \
goto next_state; \
}
#define ACCEPT_TOKEN(symbol_value) \
result = true; \
lexer->result_symbol = symbol_value; \
lexer->mark_end(lexer);
#define END_STATE() return result;
/*
* Parse Table Macros
*/
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
#define STATE(id) id
#define ACTIONS(id) id
#define SHIFT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value \
} \
}}
#define SHIFT_REPEAT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value, \
.repetition = true \
} \
}}
#define SHIFT_EXTRA() \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.extra = true \
} \
}}
#define REDUCE(symbol_val, child_count_val, ...) \
{{ \
.reduce = { \
.type = TSParseActionTypeReduce, \
.symbol = symbol_val, \
.child_count = child_count_val, \
__VA_ARGS__ \
}, \
}}
#define RECOVER() \
{{ \
.type = TSParseActionTypeRecover \
}}
#define ACCEPT_INPUT() \
{{ \
.type = TSParseActionTypeAccept \
}}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_

@ -1,193 +0,0 @@
================================================================================
Annotation for func returning multiple
================================================================================
main : Program Value Model Msg
main =
Api.application Viewer.decoder
{ init = init
, onUrlChange = ChangedUrl
, onUrlRequest = ClickedLink
, subscriptions = subscriptions
, update = update
, view = view
}
--------------------------------------------------------------------------------
(file
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))
(type_ref
(upper_case_qid
(upper_case_identifier)))
(type_ref
(upper_case_qid
(upper_case_identifier)))
(type_ref
(upper_case_qid
(upper_case_identifier))))))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(function_call_expr
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(record_expr
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier))))
(field
(lower_case_identifier)
(eq)
(value_expr
(upper_case_qid
(upper_case_identifier))))
(field
(lower_case_identifier)
(eq)
(value_expr
(upper_case_qid
(upper_case_identifier))))
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier))))
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier))))
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier))))))))
================================================================================
Annotation for func with parameters returning tuple
================================================================================
init : Maybe Viewer -> Url -> Nav.Key -> ( Model, Cmd Msg )
init maybeViewer url navKey =
changeRouteTo (Route.fromUrl url)
(Redirect (Session.fromViewer navKey maybeViewer))
--------------------------------------------------------------------------------
(file
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))
(type_ref
(upper_case_qid
(upper_case_identifier))))
(arrow)
(type_ref
(upper_case_qid
(upper_case_identifier)))
(arrow)
(type_ref
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier)))
(arrow)
(tuple_type
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))))
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))
(type_ref
(upper_case_qid
(upper_case_identifier))))))))
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier))
(lower_pattern
(lower_case_identifier))
(lower_pattern
(lower_case_identifier)))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(parenthesized_expr
(function_call_expr
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(value_expr
(value_qid
(lower_case_identifier)))))
(parenthesized_expr
(function_call_expr
(value_expr
(upper_case_qid
(upper_case_identifier)))
(parenthesized_expr
(function_call_expr
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(value_expr
(value_qid
(lower_case_identifier)))
(value_expr
(value_qid
(lower_case_identifier))))))))))
================================================================================
Annotation with trailing whitespace
================================================================================
test : Int
test =
1
--------------------------------------------------------------------------------
(file
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(number_constant_expr
(number_literal))))

@ -1,102 +0,0 @@
================================================================================
Function containing an anonymous function
================================================================================
func =
(\_ -> get h w)
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(parenthesized_expr
(anonymous_function_expr
(backslash)
(pattern
(anything_pattern
(underscore)))
(arrow)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(value_expr
(value_qid
(lower_case_identifier)))
(value_expr
(value_qid
(lower_case_identifier))))))))
================================================================================
Function containing an anonymous function that's called
================================================================================
f6 = (\a -> a) 1
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(function_call_expr
(parenthesized_expr
(anonymous_function_expr
(backslash)
(pattern
(lower_pattern
(lower_case_identifier)))
(arrow)
(value_expr
(value_qid
(lower_case_identifier)))))
(number_constant_expr
(number_literal)))))
================================================================================
Function containing an anonymous function without braces
================================================================================
f6 = \a -> a
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(anonymous_function_expr
(backslash)
(pattern
(lower_pattern
(lower_case_identifier)))
(arrow)
(value_expr
(value_qid
(lower_case_identifier))))))
================================================================================
Function containing a pipe into an anonymous function without braces
================================================================================
f1 =
1 |> \a -> a
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(bin_op_expr
(number_constant_expr
(number_literal))
(operator
(operator_identifier))
(anonymous_function_expr
(backslash)
(pattern
(lower_pattern
(lower_case_identifier)))
(arrow)
(value_expr
(value_qid
(lower_case_identifier)))))))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,396 +0,0 @@
================================================================================
Case without branches followed by newline
================================================================================
-- Works in v4.5.0
update msg =
case msg of
--------------------------------------------------------------------------------
(file
(line_comment)
(ERROR
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)))
================================================================================
Case without branches directly on file end without comment before update - Hangs in v4.5.0
================================================================================
update msg =
case msg of
--------------------------------------------------------------------------------
(file
(ERROR
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)))
================================================================================
Case without branches directly on file end with comment before update
================================================================================
-- Works in v4.5.0
update msg =
case msg of
--------------------------------------------------------------------------------
(file
(line_comment)
(ERROR
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)))
================================================================================
Case without branches leading with one line comment at file end
================================================================================
-- Hangs in v4.5.0
update msg =
-- one line comment
case msg of
--------------------------------------------------------------------------------
(file
(line_comment)
(ERROR
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(line_comment)
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)))
================================================================================
Case without branches leading with one line comment + newline
================================================================================
-- Works in v4.5.0
update msg =
-- one line comment
case msg of
--------------------------------------------------------------------------------
(file
(line_comment)
(ERROR
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(line_comment)
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)))
================================================================================
Case without branches followed by new line + space + comment
================================================================================
-- Hangs in v4.5.0
update msg =
case msg of
-- Need to use a comment with leading space, because testsuite is removing trailing spaces
--------------------------------------------------------------------------------
(file
(line_comment)
(ERROR
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of))
(line_comment))
================================================================================
Case without branches followed by new line + without space + last line comment
================================================================================
-- Works in v4.5.0
update msg =
case msg of
-- With the comment in the last line, now you can have as much
-- spaces as you want!
-- Workaround: Add an one line comment without leading space at the end of file
--------------------------------------------------------------------------------
(file
(line_comment)
(ERROR
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of))
(line_comment)
(line_comment)
(line_comment))
================================================================================
Case followed by comment: not fully indented
================================================================================
update msg =
case msg of
Ok _ ->
"Ok!"
Err _ ->
"Error!"
-- This comment is not part of the case block
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case_of_expr
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))
(line_comment))
================================================================================
Case followed by comment: indented as sibling
================================================================================
update msg =
case msg of
Ok _ ->
"Ok!"
Err _ ->
"Error!"
-- This comment is parsed as a top-level comment.
-- elm-format too will format it to a toplevel comment.
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case_of_expr
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))
(line_comment)
(line_comment))
================================================================================
Case followed by comment: indented inside case
================================================================================
-- Correct in v4.5.0
update msg =
case msg of
Ok _ ->
"Ok!"
Err _ ->
"Error!"
-- This comment is parsed as a top-level comment.
-- elm-format too will format it to a toplevel comment.
--------------------------------------------------------------------------------
(file
(line_comment)
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case_of_expr
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))
(line_comment)
(line_comment))
================================================================================
Case followed by comment: indented inside case branch
================================================================================
update msg =
case msg of
Ok _ ->
"Ok!"
Err _ ->
"Error!"
-- This comment is parsed as a top-level comment.
-- elm-format too will format it to a toplevel comment.
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case_of_expr
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))
(anything_pattern
(underscore))))
(arrow)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))
(line_comment)
(line_comment))

@ -1,339 +0,0 @@
================================================================================
One line comment without linebreak
================================================================================
--
--------------------------------------------------------------------------------
(file
(line_comment))
================================================================================
One line comments
================================================================================
-- MODEL
-- update
-- more words
-- note: (isOkay x || any isOkay xs) would not get TCO
--------------------------------------------------------------------------------
(file
(line_comment)
(line_comment)
(line_comment)
(line_comment))
================================================================================
Block comments
================================================================================
{- one line -}
{- a multiline comment
how nice
-}
{-| Returns a dictionary mapping `ScreenId` to its problems, if any.
-}
{--}
-- add x y = x + y
--}
--------------------------------------------------------------------------------
(file
(block_comment)
(block_comment)
(block_comment)
(block_comment)
(line_comment)
(line_comment))
================================================================================
Complex Block comment
================================================================================
{-| Works just like [`Parser.Nestable`](Parser#nestable) to help distinguish
between unnestable `/*` `*/` comments like in JS and nestable `{-` `-}`
comments like in Elm.
-}
--------------------------------------------------------------------------------
(file
(block_comment))
================================================================================
Comment syntax within a string
================================================================================
module Main exposing ( ..)
one="\"{-"
two="""-}
notAThing = something
\"""
notAThing2 = something
"""
three = '"' {- "
notAThing3 = something
-}
four{--}=--{-
1
five = something
--}
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(double_dot)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(string_constant_expr
(open_quote)
(string_escape)
(regular_string_part)
(close_quote)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(string_constant_expr
(open_quote)
(regular_string_part)
(string_escape)
(regular_string_part)
(close_quote)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(char_constant_expr
(open_char)
(regular_string_part)
(close_char)))
(block_comment)
(value_declaration
(function_declaration_left
(lower_case_identifier))
(block_comment)
(eq)
(line_comment)
(number_constant_expr
(number_literal)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(value_expr
(value_qid
(lower_case_identifier))))
(line_comment))
================================================================================
Nested block comment are not nested for now
================================================================================
{- comment {- nested comment -} -}
--------------------------------------------------------------------------------
(file
(block_comment))
================================================================================
Empty comment
================================================================================
module A exposing (match)
{-
-}
match : String -> Maybe ( String, String )
match input =
Nothing
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_value
(lower_case_identifier))))
(block_comment)
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))
(arrow)
(type_ref
(upper_case_qid
(upper_case_identifier))
(tuple_type
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))))
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))))))))
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(value_expr
(upper_case_qid
(upper_case_identifier)))))
================================================================================
Empty comment inside function
================================================================================
match : String -> Maybe ( String, String )
match input =
{-
-}
Nothing
--------------------------------------------------------------------------------
(file
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))
(arrow)
(type_ref
(upper_case_qid
(upper_case_identifier))
(tuple_type
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))))
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))))))))
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(block_comment)
(value_expr
(upper_case_qid
(upper_case_identifier)))))
================================================================================
Type declaration with single variant with line comment
================================================================================
type Foo
= Bar -- This is a Bar
--------------------------------------------------------------------------------
(file
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(line_comment)))
)
================================================================================
Type declaration with line comment per union variant
================================================================================
type Foo
= Bar -- This is a Bar
| Biz -- This is a Biz
--------------------------------------------------------------------------------
(file
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(line_comment))
(union_variant
(upper_case_identifier)
(line_comment)))
)
================================================================================
Type declaration with union variant and associated data and line comment on new line
================================================================================
type Foo
= Bar
-- First associated data
Int
--------------------------------------------------------------------------------
(file
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(line_comment)
(type_ref
(upper_case_qid
(upper_case_identifier))))))
================================================================================
Type declaration with union variant and associated data with line comment on same line
================================================================================
type Foo
= Bar
Int -- First associated data
Float -- Second associated data
--------------------------------------------------------------------------------
(file
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier)))
(line_comment)
(type_ref
(upper_case_qid
(upper_case_identifier)))
(line_comment))))

@ -1,287 +0,0 @@
================================================================================
Complete function example
================================================================================
{-| An animation frame triggers about 60 times per second. Get the POSIX time
on each frame. (See [`elm/time`](/packages/elm/time/latest) for more info on
POSIX times.)
**Note:** Browsers have their own render loop, repainting things as fast as
possible. If you want smooth animations in your application, it is helpful to
sync up with the browsers natural refresh rate. This hooks into JavaScript's
`requestAnimationFrame` function.
-}
onAnimationFrame : (Time.Posix -> msg) -> Sub msg
onAnimationFrame =
AM.onAnimationFrame
--------------------------------------------------------------------------------
(file
(block_comment)
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier)))
(arrow)
(type_variable
(lower_case_identifier)))
(arrow)
(type_ref
(upper_case_qid
(upper_case_identifier))
(type_variable
(lower_case_identifier)))))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))))
================================================================================
Complete counter example
================================================================================
module Main exposing (Msg(..), main, update, view)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
main =
Browser.sandbox { init = 0, update = update, view = view }
type Msg
= Increment
| Decrement
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
{- Test comment -}
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
]
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier)
(exposed_union_constructors
(double_dot)))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_value
(lower_case_identifier))))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(function_call_expr
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(record_expr
(field
(lower_case_identifier)
(eq)
(number_constant_expr
(number_literal)))
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier))))
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier)))))))
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier))
(union_variant
(upper_case_identifier)))
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier))
(lower_pattern
(lower_case_identifier)))
(eq)
(case_of_expr
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))))
(arrow)
(bin_op_expr
(value_expr
(value_qid
(lower_case_identifier)))
(operator
(operator_identifier))
(number_constant_expr
(number_literal))))
(case_of_branch
(pattern
(union_pattern
(upper_case_qid
(upper_case_identifier))))
(arrow)
(bin_op_expr
(value_expr
(value_qid
(lower_case_identifier)))
(operator
(operator_identifier))
(number_constant_expr
(number_literal))))))
(block_comment)
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr)
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(value_expr
(upper_case_qid
(upper_case_identifier)))))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr)
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(parenthesized_expr
(function_call_expr
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(value_expr
(value_qid
(lower_case_identifier))))))))
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(value_expr
(upper_case_qid
(upper_case_identifier)))))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))))))

@ -1,154 +0,0 @@
================================================================================
Pattern match cons
================================================================================
test listList =
case listList of
[ a, b ] :: _ ->
let
product : Float
product =
a + b
in
product
_ ->
0
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case_of_expr
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)
(case_of_branch
(pattern
(cons_pattern
(list_pattern
(pattern
(lower_pattern
(lower_case_identifier)))
(pattern
(lower_pattern
(lower_case_identifier))))
(anything_pattern
(underscore))))
(arrow)
(let_in_expr
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(bin_op_expr
(value_expr
(value_qid
(lower_case_identifier)))
(operator
(operator_identifier))
(value_expr
(value_qid
(lower_case_identifier)))))
(value_expr
(value_qid
(lower_case_identifier)))))
(case_of_branch
(pattern
(anything_pattern
(underscore)))
(arrow)
(number_constant_expr
(number_literal))))))
================================================================================
Pattern match multiple cons
================================================================================
test listList =
case listList of
a :: b :: _ ->
let
product : Float
product =
a + b
in
product
_ ->
0
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(case_of_expr
(case)
(value_expr
(value_qid
(lower_case_identifier)))
(of)
(case_of_branch
(pattern
(cons_pattern
(lower_pattern
(lower_case_identifier))
(cons_pattern
(lower_pattern
(lower_case_identifier))
(anything_pattern
(underscore)))))
(arrow)
(let_in_expr
(type_annotation
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(bin_op_expr
(value_expr
(value_qid
(lower_case_identifier)))
(operator
(operator_identifier))
(value_expr
(value_qid
(lower_case_identifier)))))
(value_expr
(value_qid
(lower_case_identifier)))))
(case_of_branch
(pattern
(anything_pattern
(underscore)))
(arrow)
(number_constant_expr
(number_literal))))))

@ -1,28 +0,0 @@
================================================================================
Multiple field accessors
================================================================================
func model =
model.field.second.third
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(field_access_expr
(field_access_expr
(field_access_expr
(value_expr
(value_qid
(lower_case_identifier)))
(dot)
(lower_case_identifier))
(dot)
(lower_case_identifier))
(dot)
(lower_case_identifier))))

@ -1,63 +0,0 @@
================================================================================
Simple glsl function
================================================================================
textures_skies_tim_hell_fragment_1 =
[glsl|
precision mediump float;
varying vec2 vTextureCoord;
varying vec2 vLightmapCoord;
varying vec4 vColor;
uniform sampler2D texture;
uniform float time;
void main
(void) {
vec4 textureColor = texture2D(texture, vTextureCoord.st);
vec3 rgb = textureColor.rgb;
// alphaGen
float alpha = textureColor.a;
gl_FragColor = vec4(rgb, alpha);
}
|]
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(glsl_code_expr
(glsl_content))))
================================================================================
Simple glsl function no end
================================================================================
textures_skies_tim_hell_fragment_1 =
[glsl|
precision mediump float;
varying vec2 vTextureCoord;
varying vec2 vLightmapCoord;
varying vec4 vColor;
uniform sampler2D texture;
uniform float time;
void main
(void) {
vec4 textureColor = texture2D(texture, vTextureCoord.st);
vec3 rgb = textureColor.rgb;
// alphaGen
float alpha = textureColor.a;
gl_FragColor = vec4(rgb, alpha);
}
--------------------------------------------------------------------------------
(file
(ERROR
(function_declaration_left
(lower_case_identifier))
(eq)
(glsl_content)))

@ -1,263 +0,0 @@
================================================================================
Import statements
================================================================================
import Browser
import Html.Events
import Html.Events.Test
--------------------------------------------------------------------------------
(file
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier)))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier)
(dot)
(upper_case_identifier))))
================================================================================
Import statements with exposing
================================================================================
import Html.Events exposing (onClick)
import Html.Events exposing (..)
import Html.Events exposing (onClick, onDoubleClick)
import Html exposing (Html, button, div, text)
--------------------------------------------------------------------------------
(file
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_value
(lower_case_identifier))))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(exposing_list
(exposing)
(double_dot)))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))
================================================================================
Import statements prefixed with module and docs
================================================================================
module Asset exposing (Image, defaultAvatar, error, loading, src)
{-| Assets, such as images, videos, and audio. (We only have images for now.)
We should never expose asset URLs directly; this module should be in charge of
all of them. One source of truth!
-}
import Html exposing (Attribute, Html)
import Html.Attributes as Attr
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))))
(block_comment)
(import_clause
(import)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(exposed_type
(upper_case_identifier))))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(as_clause
(as)
(upper_case_identifier))))
================================================================================
Import statements with as clause
================================================================================
import Dict.Any as AnyDict exposing (AnyDict)
import Remedy.ScreenId as ScreenId exposing (ScreenId)
import Remedy.ScreenList as ScreenList
--------------------------------------------------------------------------------
(file
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(as_clause
(as)
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(as_clause
(as)
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(as_clause
(as)
(upper_case_identifier))))
================================================================================
Import statements with operator statement
================================================================================
import Url.Parser as Parser exposing ((</>), Parser, oneOf, s, string)
--------------------------------------------------------------------------------
(file
(import_clause
(import)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(as_clause
(as)
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_operator
(operator_identifier))
(exposed_type
(upper_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))
================================================================================
Import statements with type trying to expose all constructors
================================================================================
import Element exposing (DeviceClass(..))
--------------------------------------------------------------------------------
(file
(import_clause
(import)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier)
(exposed_union_constructors
(double_dot))))))
================================================================================
Import statements with type trying to expose single constructor - should fail
================================================================================
import Element exposing (DeviceClass(Phone))
--------------------------------------------------------------------------------
(file
(import_clause
(import)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(ERROR
(upper_case_identifier)))))

@ -1,124 +0,0 @@
================================================================================
Incomplete function call
================================================================================
view model =
div []
[ Html.
]
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr)
(list_expr
(value_expr
(upper_case_qid
(upper_case_identifier)))
(ERROR
(dot))))))
================================================================================
Incomplete model access
================================================================================
view model =
div []
[ model.
]
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr)
(list_expr
(field_access_expr
(value_expr
(value_qid
(lower_case_identifier)))
(dot)
(MISSING lower_case_identifier))))))
================================================================================
Incomplete model access
================================================================================
view model =
div []
[ model.
]
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr)
(list_expr
(field_access_expr
(value_expr
(value_qid
(lower_case_identifier)))
(dot)
(MISSING lower_case_identifier))))))
================================================================================
Incomplete import
================================================================================
import Foo as
import App exposing (Page(..))
defaultPage = Home
--------------------------------------------------------------------------------
(file
(ERROR
(import)
(upper_case_qid
(upper_case_identifier))
(as))
(import_clause
(import)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier)
(exposed_union_constructors
(double_dot)))))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(value_expr
(upper_case_qid
(upper_case_identifier)))))

File diff suppressed because it is too large Load Diff

@ -1,237 +0,0 @@
================================================================================
module statement exposing all
================================================================================
module Main exposing (..)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(double_dot))))
================================================================================
module statement sub dir exposing all
================================================================================
module Page.View exposing (..)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier))
(exposing_list
(exposing)
(double_dot))))
================================================================================
module statement exposing single function
================================================================================
module Main exposing (view)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_value
(lower_case_identifier)))))
================================================================================
module statement exposing multiple functions
================================================================================
module Main exposing (main, update, view)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))
================================================================================
module statement exposing type with all constructors and functions
================================================================================
module Main exposing (Msg(..), main, update, view)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier)
(exposed_union_constructors
(double_dot)))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))
================================================================================
module statement exposing type with no constructors and functions
================================================================================
module Main exposing (Msg, main, update, view)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))
================================================================================
module statement exposing type with all constructors and functions
================================================================================
module Main exposing (Msg(..), main, update, view)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier)
(exposed_union_constructors
(double_dot)))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))
================================================================================
module statement exposing type with one constructors and functions - not valid in elm 0.19 - should error
================================================================================
module Main exposing (Msg(One), main, update, view)
--------------------------------------------------------------------------------
(file
(module_declaration
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(ERROR
(upper_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))
================================================================================
effect module statement exposing
================================================================================
effect module Task where { command = MyCmd } exposing
( Task
, succeed, fail
, map, map2, map3, map4, map5
, sequence
, andThen
, onError, mapError
, perform, attempt
)
--------------------------------------------------------------------------------
(file
(module_declaration
(effect)
(module)
(upper_case_qid
(upper_case_identifier))
(where)
(record_expr
(field
(lower_case_identifier)
(eq)
(value_expr
(upper_case_qid
(upper_case_identifier)))))
(exposing_list
(exposing)
(exposed_type
(upper_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier))
(exposed_value
(lower_case_identifier)))))

@ -1,37 +0,0 @@
================================================================================
module statement exposing all
================================================================================
port module Ports exposing (foo)
port foo : String -> Cmd msg
--------------------------------------------------------------------------------
(file
(module_declaration
(port)
(module)
(upper_case_qid
(upper_case_identifier))
(exposing_list
(exposing)
(exposed_value
(lower_case_identifier))))
(port_annotation
(port)
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))
(arrow)
(type_ref
(upper_case_qid
(upper_case_identifier))
(type_variable
(lower_case_identifier))))))

@ -1,130 +0,0 @@
================================================================================
Function statement with function call and inline record
================================================================================
main =
Browser.sandbox
{ init = 0
, update = update
, view = view }
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(function_call_expr
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(record_expr
(field
(lower_case_identifier)
(eq)
(number_constant_expr
(number_literal)))
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier))))
(field
(lower_case_identifier)
(eq)
(value_expr
(value_qid
(lower_case_identifier))))))))
================================================================================
Function statement with list
================================================================================
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
]
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr)
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(value_expr
(upper_case_qid
(upper_case_identifier)))))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr)
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(parenthesized_expr
(function_call_expr
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier)))
(value_expr
(value_qid
(lower_case_identifier))))))))
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(value_expr
(upper_case_qid
(upper_case_identifier)))))
(list_expr
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))))))

@ -1,201 +0,0 @@
================================================================================
Multiline string used in func
================================================================================
toStringCase enumValue =
interpolate
""" {0} ->
"{1}"
"""
[ enumValue.name |> ClassCaseName.normalized
, enumValue.name |> ClassCaseName.raw
]
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier)
(lower_pattern
(lower_case_identifier)))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote))
(list_expr
(bin_op_expr
(field_access_expr
(value_expr
(value_qid
(lower_case_identifier)))
(dot)
(lower_case_identifier))
(operator
(operator_identifier))
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier))))
(bin_op_expr
(field_access_expr
(value_expr
(value_qid
(lower_case_identifier)))
(dot)
(lower_case_identifier))
(operator
(operator_identifier))
(value_expr
(value_qid
(upper_case_identifier)
(dot)
(lower_case_identifier))))))))
================================================================================
Strings multiline
================================================================================
string1 =
"""
multiline
"""
string2 =
""""""
string3 =
"""
"
"""
string4 =
"""
--comment
"""
string5 =
"""
{- block comment -}
"""
json =
"""
{ "description": null
, "slug": \"""" ++ str ++ """"
, "title": ""
, "tagList": []
, "createdAt": "2012-04-23T18:25:43.511Z"
, "updatedAt": "2012-04-23T18:25:43.511Z"
, "favorited": false
, "favoritesCount": 1
, "author":
{ "username": ""
, "bio": null
, "image": null
, "following": false
}
}
"""
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(string_constant_expr
(open_quote)
(close_quote)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(bin_op_expr
(string_constant_expr
(open_quote)
(regular_string_part)
(string_escape)
(close_quote))
(operator
(operator_identifier))
(value_expr
(value_qid
(lower_case_identifier)))
(operator
(operator_identifier))
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))
================================================================================
Multiline string as parameter
================================================================================
result =
interpolate """module {0} exposing (..)
placeholder : String
placeholder =
""
"""
--------------------------------------------------------------------------------
(file
(value_declaration
(function_declaration_left
(lower_case_identifier))
(eq)
(function_call_expr
(value_expr
(value_qid
(lower_case_identifier)))
(string_constant_expr
(open_quote)
(regular_string_part)
(close_quote)))))

@ -1,143 +0,0 @@
================================================================================
Type statement
================================================================================
type Msg
= Increment
type Msg
= Increment
| Decrement
type Msg
= Increment
| Decrement
| NoOp
--------------------------------------------------------------------------------
(file
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)))
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier))
(union_variant
(upper_case_identifier)))
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier))
(union_variant
(upper_case_identifier))
(union_variant
(upper_case_identifier))))
================================================================================
Type statement with payload
================================================================================
type Problem
= ContentProblem ValidationProblem
| GenericProblem String
| MetaProblem String
type ValidationProblem
= WithScreen ScreenId ScreenProblem
| RequiresAtLeastOneScreen
| ScreenListProblem ScreenList.ValidationProblem
type ScreenProblem
= WithElement Int ElementProblem
| ScreenIsEmpty
| ScreenIsUnreachable
type ElementProblem
= InvalidElement String
| InvalidScreenTarget
| InvalidScreenTargetCausesCycle
--------------------------------------------------------------------------------
(file
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier))))
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier))))
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier)))))
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier)))
(type_ref
(upper_case_qid
(upper_case_identifier))))
(union_variant
(upper_case_identifier))
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier)
(dot)
(upper_case_identifier)))))
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier)))
(type_ref
(upper_case_qid
(upper_case_identifier))))
(union_variant
(upper_case_identifier))
(union_variant
(upper_case_identifier)))
(type_declaration
(type)
(upper_case_identifier)
(eq)
(union_variant
(upper_case_identifier)
(type_ref
(upper_case_qid
(upper_case_identifier))))
(union_variant
(upper_case_identifier))
(union_variant
(upper_case_identifier))))

@ -1,63 +0,0 @@
================================================================================
Type alias number
================================================================================
type alias Number =
Int
--------------------------------------------------------------------------------
(file
(type_alias_declaration
(type)
(alias)
(upper_case_identifier)
(eq)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier))))))
================================================================================
Type alias
================================================================================
type alias ListItem =
{ name : String
, value : Int
, itemType : ListItemType
}
--------------------------------------------------------------------------------
(file
(type_alias_declaration
(type)
(alias)
(upper_case_identifier)
(eq)
(type_expression
(record_type
(field_type
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))))
(field_type
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))))
(field_type
(lower_case_identifier)
(colon)
(type_expression
(type_ref
(upper_case_qid
(upper_case_identifier)))))))))

@ -1,50 +0,0 @@
module Main exposing (Msg(..), main, update, view)
-- ^ keyword.other.elm
-- ^ keyword.other.elm
import Browser
-- ^ meta.import.elm
import Html exposing (Html, button, div, text)
-- ^ meta.import.elm
import Html.Events exposing (onClick)
-- ^ meta.import.elm
main =
Browser.sandbox { init = 0, update = update, view = view }
type Msg
-- <- @keyword.type.elm
-- ^ @storage.type.elm
= Increment
-- ^ union.elm
| Decrement
-- ^ union.elm
update : Msg -> Model
-- <- function.elm
-- ^ keyword.other.elm
-- ^ keyword.operator.arrow.elm
update msg model =
case msg of
-- ^ keyword.control.elm
Increment ->
-- ^ keyword.operator.arrow.elm
model + 1
-- ^ keyword.operator.elm
Decrement ->
model - 1
-- ^ constant.numeric.elm
view model =
-- ^ keyword.operator.assignment.elm
div []
[ button [ onClick Decrement ] [ text "-" ]
-- ^ string.elm
-- ^ string.elm
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
]

@ -1,9 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2016",
"jsx": "preserve",
"sourceMap": true
},
"exclude": ["node_modules", "**/node_modules/*"]
}