Add 'vendor/tree-sitter-elm/' from commit '5128296ba8542853d59e6b7c8dfe3d1fb9a637ea'

git-subtree-dir: vendor/tree-sitter-elm
git-subtree-mainline: d6e9afd3d6
git-subtree-split: 5128296ba8
pull/223/head
Alex Perkins 2022-04-03 20:19:54 +07:00
commit 469f84b605
68 changed files with 68915 additions and 0 deletions

@ -0,0 +1,17 @@
# 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

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

@ -0,0 +1 @@
github: [razzeee]

@ -0,0 +1,50 @@
# 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@v2
- uses: actions/setup-node@v1
with:
node-version: 14
- run: npm i
- run: npm run build
- run: npm run test-only
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 14
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@v2
- uses: actions/setup-node@v1
with:
node-version: 14
registry-url: https://npm.pkg.github.com/
- run: npm i
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}

@ -0,0 +1,29 @@
name: Publish prebuilds
on:
release:
types: [created]
jobs:
prebuild:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [14]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Npm install
run: |
npm i
- run: npm run prebuild && npm run prebuild:upload -u ${PREBUILD_UPLOAD}
env:
PREBUILD_UPLOAD: ${{ secrets.GITHUB_TOKEN }}
shell: bash

@ -0,0 +1,18 @@
name: Publish crates.io
on:
release:
types: [created]
jobs:
cargo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- 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

@ -0,0 +1,36 @@
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: [14]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Npm install
run: |
npm i
- name: Unit tests
run: |
npx tree-sitter test
- name: Test examples
continue-on-error: true
run: |
script/parse-examples-full

@ -0,0 +1,60 @@
name: Test OSX, Windows and Linux
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
node:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
node-version: [12, 14]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Npm install
run: |
npm i
- name: Unit tests
run: |
npx tree-sitter test
- name: Test examples
run: |
if [ "$RUNNER_OS" != "Windows" ]; then
script/parse-examples
fi
shell: bash
rust:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- 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

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

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

@ -0,0 +1,42 @@
{
// 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": []
}
]
}

@ -0,0 +1,34 @@
[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.5.1"
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "~0.20"
[build-dependencies]
cc = "1.0"

@ -0,0 +1,6 @@
1. Increase the version number in the package.json and the Cargo.toml
2. Run `npm run generate-types && 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.

@ -0,0 +1,21 @@
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.

@ -0,0 +1,31 @@
[![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.

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

@ -0,0 +1,28 @@
#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

@ -0,0 +1,19 @@
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 (_) {}

@ -0,0 +1,38 @@
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);
// If your language uses an external scanner written in C,
// then include this block of code:
/*
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());
// If your language uses an external scanner written in C++,
// then include this block of code:
let mut cpp_config = cc::Build::new();
cpp_config.cpp(true);
cpp_config.include(&src_dir);
cpp_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable");
let scanner_path = src_dir.join("scanner.cc");
cpp_config.file(&scanner_path);
cpp_config.compile("scanner");
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
}

@ -0,0 +1,52 @@
//! 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");
}
}

@ -0,0 +1,250 @@
<!--
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>

@ -0,0 +1,461 @@
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

Binary file not shown.

@ -0,0 +1,31 @@
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
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
]

@ -0,0 +1,92 @@
module Main exposing (..)
func ab =
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
case ab of
True ->
Just
{ s = 5
}
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing
_ ->
Nothing

File diff suppressed because one or more lines are too long

@ -0,0 +1,882 @@
export interface Parser {
parse(input: string | Input, previousTree?: Tree, options?: {bufferSize?: number, includedRanges?: Range[]}): Tree;
getLanguage(): any;
setLanguage(language: any): void;
getLogger(): Logger;
setLogger(logFunc: Logger): void;
}
export type Point = {
row: number;
column: number;
};
export type Range = {
startIndex: number,
endIndex: number,
startPosition: Point,
endPosition: Point
};
export type Edit = {
startIndex: number;
oldEndIndex: number;
newEndIndex: number;
startPosition: Point;
oldEndPosition: Point;
newEndPosition: Point;
};
export type Logger = (
message: string,
params: {[param: string]: string},
type: "parse" | "lex"
) => void;
export interface Input {
seek(index: number): void;
read(): any;
}
interface SyntaxNodeBase {
tree: Tree;
type: string;
isNamed: boolean;
text: string;
startPosition: Point;
endPosition: Point;
startIndex: number;
endIndex: number;
parent: SyntaxNode | null;
children: Array<SyntaxNode>;
namedChildren: Array<SyntaxNode>;
childCount: number;
namedChildCount: number;
firstChild: SyntaxNode | null;
firstNamedChild: SyntaxNode | null;
lastChild: SyntaxNode | null;
lastNamedChild: SyntaxNode | null;
nextSibling: SyntaxNode | null;
nextNamedSibling: SyntaxNode | null;
previousSibling: SyntaxNode | null;
previousNamedSibling: SyntaxNode | null;
hasChanges(): boolean;
hasError(): boolean;
isMissing(): boolean;
toString(): string;
child(index: number): SyntaxNode | null;
namedChild(index: number): SyntaxNode | null;
firstChildForIndex(index: number): SyntaxNode | null;
firstNamedChildForIndex(index: number): SyntaxNode | null;
descendantForIndex(index: number): SyntaxNode;
descendantForIndex(startIndex: number, endIndex: number): SyntaxNode;
namedDescendantForIndex(index: number): SyntaxNode;
namedDescendantForIndex(startIndex: number, endIndex: number): SyntaxNode;
descendantForPosition(position: Point): SyntaxNode;
descendantForPosition(startPosition: Point, endPosition: Point): SyntaxNode;
namedDescendantForPosition(position: Point): SyntaxNode;
namedDescendantForPosition(startPosition: Point, endPosition: Point): SyntaxNode;
descendantsOfType<T extends TypeString>(types: T | readonly T[], startPosition?: Point, endPosition?: Point): NodeOfType<T>[];
closest<T extends SyntaxType>(types: T | readonly T[]): NamedNode<T> | null;
walk(): TreeCursor;
}
export interface TreeCursor {
nodeType: string;
nodeText: string;
nodeIsNamed: boolean;
startPosition: Point;
endPosition: Point;
startIndex: number;
endIndex: number;
readonly currentNode: SyntaxNode
reset(node: SyntaxNode): void
gotoParent(): boolean;
gotoFirstChild(): boolean;
gotoFirstChildForIndex(index: number): boolean;
gotoNextSibling(): boolean;
}
export interface Tree {
readonly rootNode: SyntaxNode;
edit(delta: Edit): Tree;
walk(): TreeCursor;
getChangedRanges(other: Tree): Range[];
getEditedRange(other: Tree): Range;
}
interface NamedNodeBase extends SyntaxNodeBase {
isNamed: true;
}
/** An unnamed node with the given type string. */
export interface UnnamedNode<T extends string = string> extends SyntaxNodeBase {
type: T;
isNamed: false;
}
type PickNamedType<Node, T extends string> = Node extends { type: T; isNamed: true } ? Node : never;
type PickType<Node, T extends string> = Node extends { type: T } ? Node : never;
/** A named node with the given `type` string. */
export type NamedNode<T extends SyntaxType = SyntaxType> = PickNamedType<SyntaxNode, T>;
/**
* A node with the given `type` string.
*
* Note that this matches both named and unnamed nodes. Use `NamedNode<T>` to pick only named nodes.
*/
export type NodeOfType<T extends string> = PickType<SyntaxNode, T>;
interface TreeCursorOfType<S extends string, T extends SyntaxNodeBase> {
nodeType: S;
currentNode: T;
}
type TreeCursorRecord = { [K in TypeString]: TreeCursorOfType<K, NodeOfType<K>> };
/**
* A tree cursor whose `nodeType` correlates with `currentNode`.
*
* The typing becomes invalid once the underlying cursor is mutated.
*
* The intention is to cast a `TreeCursor` to `TypedTreeCursor` before
* switching on `nodeType`.
*
* For example:
* ```ts
* let cursor = root.walk();
* while (cursor.gotoNextSibling()) {
* const c = cursor as TypedTreeCursor;
* switch (c.nodeType) {
* case SyntaxType.Foo: {
* let node = c.currentNode; // Typed as FooNode.
* break;
* }
* }
* }
* ```
*/
export type TypedTreeCursor = TreeCursorRecord[keyof TreeCursorRecord];
export interface ErrorNode extends NamedNodeBase {
type: SyntaxType.ERROR;
hasError(): true;
}
export const enum SyntaxType {
ERROR = "ERROR",
AnonymousFunctionExpr = "anonymous_function_expr",
AnythingPattern = "anything_pattern",
AsClause = "as_clause",
BinOpExpr = "bin_op_expr",
BlockComment = "block_comment",
CaseOfBranch = "case_of_branch",
CaseOfExpr = "case_of_expr",
CharConstantExpr = "char_constant_expr",
ConsPattern = "cons_pattern",
ExposedOperator = "exposed_operator",
ExposedType = "exposed_type",
ExposedUnionConstructors = "exposed_union_constructors",
ExposedValue = "exposed_value",
ExposingList = "exposing_list",
Field = "field",
FieldAccessExpr = "field_access_expr",
FieldAccessorFunctionExpr = "field_accessor_function_expr",
FieldType = "field_type",
File = "file",
FunctionCallExpr = "function_call_expr",
FunctionDeclarationLeft = "function_declaration_left",
GlslCodeExpr = "glsl_code_expr",
IfElseExpr = "if_else_expr",
ImportClause = "import_clause",
InfixDeclaration = "infix_declaration",
LetInExpr = "let_in_expr",
ListExpr = "list_expr",
ListPattern = "list_pattern",
LowerPattern = "lower_pattern",
LowerTypeName = "lower_type_name",
ModuleDeclaration = "module_declaration",
NegateExpr = "negate_expr",
NullaryConstructorArgumentPattern = "nullary_constructor_argument_pattern",
NumberConstantExpr = "number_constant_expr",
Operator = "operator",
OperatorAsFunctionExpr = "operator_as_function_expr",
OperatorIdentifier = "operator_identifier",
ParenthesizedExpr = "parenthesized_expr",
Pattern = "pattern",
PortAnnotation = "port_annotation",
RecordBaseIdentifier = "record_base_identifier",
RecordExpr = "record_expr",
RecordPattern = "record_pattern",
RecordType = "record_type",
StringConstantExpr = "string_constant_expr",
TupleExpr = "tuple_expr",
TuplePattern = "tuple_pattern",
TupleType = "tuple_type",
TypeAliasDeclaration = "type_alias_declaration",
TypeAnnotation = "type_annotation",
TypeDeclaration = "type_declaration",
TypeExpression = "type_expression",
TypeRef = "type_ref",
TypeVariable = "type_variable",
UnionPattern = "union_pattern",
UnionVariant = "union_variant",
UnitExpr = "unit_expr",
UpperCaseQid = "upper_case_qid",
ValueDeclaration = "value_declaration",
ValueExpr = "value_expr",
ValueQid = "value_qid",
Alias = "alias",
Arrow = "arrow",
As = "as",
Backslash = "backslash",
Case = "case",
CloseChar = "close_char",
CloseQuote = "close_quote",
Colon = "colon",
Dot = "dot",
DoubleDot = "double_dot",
Effect = "effect",
Eq = "eq",
Exposing = "exposing",
GlslContent = "glsl_content",
Import = "import",
Infix = "infix",
InvalidStringEscape = "invalid_string_escape",
LineComment = "line_comment",
LowerCaseIdentifier = "lower_case_identifier",
Module = "module",
NumberLiteral = "number_literal",
Of = "of",
OpenChar = "open_char",
OpenQuote = "open_quote",
Port = "port",
RegularStringPart = "regular_string_part",
StringEscape = "string_escape",
Type = "type",
Underscore = "underscore",
UpperCaseIdentifier = "upper_case_identifier",
Where = "where",
}
export type UnnamedType =
| "&&"
| "("
| ")"
| "*"
| "+"
| "++"
| ","
| "-"
| "-}"
| "/"
| "//"
| "/="
| "::"
| "<"
| "</>"
| "<<"
| "<="
| "<?>"
| "<|"
| "=="
| ">"
| ">="
| ">>"
| "["
| "]"
| "^"
| "else"
| "if"
| "in"
| "let"
| "then"
| "{"
| "{-"
| "|"
| "|."
| "|="
| "|>"
| "||"
| "}"
;
export type TypeString = SyntaxType | UnnamedType;
export type SyntaxNode =
| AnonymousFunctionExprNode
| AnythingPatternNode
| AsClauseNode
| BinOpExprNode
| BlockCommentNode
| CaseOfBranchNode
| CaseOfExprNode
| CharConstantExprNode
| ConsPatternNode
| ExposedOperatorNode
| ExposedTypeNode
| ExposedUnionConstructorsNode
| ExposedValueNode
| ExposingListNode
| FieldNode
| FieldAccessExprNode
| FieldAccessorFunctionExprNode
| FieldTypeNode
| FileNode
| FunctionCallExprNode
| FunctionDeclarationLeftNode
| GlslCodeExprNode
| IfElseExprNode
| ImportClauseNode
| InfixDeclarationNode
| LetInExprNode
| ListExprNode
| ListPatternNode
| LowerPatternNode
| LowerTypeNameNode
| ModuleDeclarationNode
| NegateExprNode
| NullaryConstructorArgumentPatternNode
| NumberConstantExprNode
| OperatorNode
| OperatorAsFunctionExprNode
| OperatorIdentifierNode
| ParenthesizedExprNode
| PatternNode
| PortAnnotationNode
| RecordBaseIdentifierNode
| RecordExprNode
| RecordPatternNode
| RecordTypeNode
| StringConstantExprNode
| TupleExprNode
| TuplePatternNode
| TupleTypeNode
| TypeAliasDeclarationNode
| TypeAnnotationNode
| TypeDeclarationNode
| TypeExpressionNode
| TypeRefNode
| TypeVariableNode
| UnionPatternNode
| UnionVariantNode
| UnitExprNode
| UpperCaseQidNode
| ValueDeclarationNode
| ValueExprNode
| ValueQidNode
| UnnamedNode<"&&">
| UnnamedNode<"(">
| UnnamedNode<")">
| UnnamedNode<"*">
| UnnamedNode<"+">
| UnnamedNode<"++">
| UnnamedNode<",">
| UnnamedNode<"-">
| UnnamedNode<"-}">
| UnnamedNode<"/">
| UnnamedNode<"//">
| UnnamedNode<"/=">
| UnnamedNode<"::">
| UnnamedNode<"<">
| UnnamedNode<"</>">
| UnnamedNode<"<<">
| UnnamedNode<"<=">
| UnnamedNode<"<?>">
| UnnamedNode<"<|">
| UnnamedNode<"==">
| UnnamedNode<">">
| UnnamedNode<">=">
| UnnamedNode<">>">
| UnnamedNode<"[">
| UnnamedNode<"]">
| UnnamedNode<"^">
| AliasNode
| ArrowNode
| AsNode
| BackslashNode
| CaseNode
| CloseCharNode
| CloseQuoteNode
| ColonNode
| DotNode
| DoubleDotNode
| EffectNode
| UnnamedNode<"else">
| EqNode
| ExposingNode
| GlslContentNode
| UnnamedNode<"if">
| ImportNode
| UnnamedNode<"in">
| InfixNode
| InvalidStringEscapeNode
| UnnamedNode<"let">
| LineCommentNode
| LowerCaseIdentifierNode
| ModuleNode
| NumberLiteralNode
| OfNode
| OpenCharNode
| OpenQuoteNode
| PortNode
| RegularStringPartNode
| StringEscapeNode
| UnnamedNode<"then">
| TypeNode
| UnderscoreNode
| UpperCaseIdentifierNode
| WhereNode
| UnnamedNode<"{">
| UnnamedNode<"{-">
| UnnamedNode<"|">
| UnnamedNode<"|.">
| UnnamedNode<"|=">
| UnnamedNode<"|>">
| UnnamedNode<"||">
| UnnamedNode<"}">
| ErrorNode
;
export interface AnonymousFunctionExprNode extends NamedNodeBase {
type: SyntaxType.AnonymousFunctionExpr;
exprNode: AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode;
paramNodes: PatternNode[];
}
export interface AnythingPatternNode extends NamedNodeBase {
type: SyntaxType.AnythingPattern;
}
export interface AsClauseNode extends NamedNodeBase {
type: SyntaxType.AsClause;
nameNode: UpperCaseIdentifierNode;
}
export interface BinOpExprNode extends NamedNodeBase {
type: SyntaxType.BinOpExpr;
partNodes: (AnonymousFunctionExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode)[];
}
export interface BlockCommentNode extends NamedNodeBase {
type: SyntaxType.BlockComment;
}
export interface CaseOfBranchNode extends NamedNodeBase {
type: SyntaxType.CaseOfBranch;
exprNode: AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode;
patternNode: PatternNode;
}
export interface CaseOfExprNode extends NamedNodeBase {
type: SyntaxType.CaseOfExpr;
branchNodes: CaseOfBranchNode[];
exprNode: AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode;
}
export interface CharConstantExprNode extends NamedNodeBase {
type: SyntaxType.CharConstantExpr;
}
export interface ConsPatternNode extends NamedNodeBase {
type: SyntaxType.ConsPattern;
partNodes: (UnnamedNode<"("> | UnnamedNode<")"> | AnythingPatternNode | CharConstantExprNode | ConsPatternNode | ListPatternNode | LowerPatternNode | NumberConstantExprNode | PatternNode | RecordPatternNode | StringConstantExprNode | TuplePatternNode | UnionPatternNode | UnitExprNode)[];
}
export interface ExposedOperatorNode extends NamedNodeBase {
type: SyntaxType.ExposedOperator;
operatorNode: OperatorIdentifierNode;
}
export interface ExposedTypeNode extends NamedNodeBase {
type: SyntaxType.ExposedType;
}
export interface ExposedUnionConstructorsNode extends NamedNodeBase {
type: SyntaxType.ExposedUnionConstructors;
}
export interface ExposedValueNode extends NamedNodeBase {
type: SyntaxType.ExposedValue;
}
export interface ExposingListNode extends NamedNodeBase {
type: SyntaxType.ExposingList;
doubleDotNode?: DoubleDotNode;
}
export interface FieldNode extends NamedNodeBase {
type: SyntaxType.Field;
expressionNode: AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode;
nameNode: LowerCaseIdentifierNode;
}
export interface FieldAccessExprNode extends NamedNodeBase {
type: SyntaxType.FieldAccessExpr;
targetNode: FieldAccessExprNode | ParenthesizedExprNode | RecordExprNode | ValueExprNode;
}
export interface FieldAccessorFunctionExprNode extends NamedNodeBase {
type: SyntaxType.FieldAccessorFunctionExpr;
}
export interface FieldTypeNode extends NamedNodeBase {
type: SyntaxType.FieldType;
nameNode: LowerCaseIdentifierNode;
typeExpressionNode: TypeExpressionNode;
}
export interface FileNode extends NamedNodeBase {
type: SyntaxType.File;
moduleDeclarationNode?: ModuleDeclarationNode;
}
export interface FunctionCallExprNode extends NamedNodeBase {
type: SyntaxType.FunctionCallExpr;
argNodes: (AnonymousFunctionExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode)[];
targetNode: FieldAccessExprNode | FieldAccessorFunctionExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | ValueExprNode;
}
export interface FunctionDeclarationLeftNode extends NamedNodeBase {
type: SyntaxType.FunctionDeclarationLeft;
patternNodes: (UnnamedNode<"("> | UnnamedNode<")"> | AnythingPatternNode | CharConstantExprNode | ListPatternNode | LowerPatternNode | NumberConstantExprNode | PatternNode | RecordPatternNode | StringConstantExprNode | TuplePatternNode | UnitExprNode)[];
}
export interface GlslCodeExprNode extends NamedNodeBase {
type: SyntaxType.GlslCodeExpr;
contentNode: GlslContentNode;
}
export interface IfElseExprNode extends NamedNodeBase {
type: SyntaxType.IfElseExpr;
exprListNodes: (AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode)[];
}
export interface ImportClauseNode extends NamedNodeBase {
type: SyntaxType.ImportClause;
asClauseNode?: AsClauseNode;
exposingNode?: ExposingListNode;
moduleNameNode: UpperCaseQidNode;
}
export interface InfixDeclarationNode extends NamedNodeBase {
type: SyntaxType.InfixDeclaration;
associativityNode: LowerCaseIdentifierNode;
operatorNode: OperatorIdentifierNode;
precedenceNode: NumberLiteralNode;
}
export interface LetInExprNode extends NamedNodeBase {
type: SyntaxType.LetInExpr;
bodyNode: AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode;
valueDeclarationNodes: ValueDeclarationNode[];
}
export interface ListExprNode extends NamedNodeBase {
type: SyntaxType.ListExpr;
exprListNodes: (AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode)[];
}
export interface ListPatternNode extends NamedNodeBase {
type: SyntaxType.ListPattern;
partNodes: PatternNode[];
}
export interface LowerPatternNode extends NamedNodeBase {
type: SyntaxType.LowerPattern;
}
export interface LowerTypeNameNode extends NamedNodeBase {
type: SyntaxType.LowerTypeName;
}
export interface ModuleDeclarationNode extends NamedNodeBase {
type: SyntaxType.ModuleDeclaration;
exposingNode: ExposingListNode;
nameNode: UpperCaseQidNode;
}
export interface NegateExprNode extends NamedNodeBase {
type: SyntaxType.NegateExpr;
}
export interface NullaryConstructorArgumentPatternNode extends NamedNodeBase {
type: SyntaxType.NullaryConstructorArgumentPattern;
}
export interface NumberConstantExprNode extends NamedNodeBase {
type: SyntaxType.NumberConstantExpr;
}
export interface OperatorNode extends NamedNodeBase {
type: SyntaxType.Operator;
}
export interface OperatorAsFunctionExprNode extends NamedNodeBase {
type: SyntaxType.OperatorAsFunctionExpr;
operatorNode: OperatorIdentifierNode;
}
export interface OperatorIdentifierNode extends NamedNodeBase {
type: SyntaxType.OperatorIdentifier;
}
export interface ParenthesizedExprNode extends NamedNodeBase {
type: SyntaxType.ParenthesizedExpr;
expressionNode: AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode;
}
export interface PatternNode extends NamedNodeBase {
type: SyntaxType.Pattern;
childNode: AnythingPatternNode | CharConstantExprNode | ConsPatternNode | ListPatternNode | LowerPatternNode | NumberConstantExprNode | PatternNode | RecordPatternNode | StringConstantExprNode | TuplePatternNode | UnionPatternNode | UnitExprNode;
patternAsNode?: LowerPatternNode;
}
export interface PortAnnotationNode extends NamedNodeBase {
type: SyntaxType.PortAnnotation;
nameNode: LowerCaseIdentifierNode;
typeExpressionNode: TypeExpressionNode;
}
export interface RecordBaseIdentifierNode extends NamedNodeBase {
type: SyntaxType.RecordBaseIdentifier;
}
export interface RecordExprNode extends NamedNodeBase {
type: SyntaxType.RecordExpr;
baseRecordNode?: RecordBaseIdentifierNode;
fieldNodes: FieldNode[];
}
export interface RecordPatternNode extends NamedNodeBase {
type: SyntaxType.RecordPattern;
patternListNodes: LowerPatternNode[];
}
export interface RecordTypeNode extends NamedNodeBase {
type: SyntaxType.RecordType;
baseRecordNode?: RecordBaseIdentifierNode;
fieldTypeNodes: FieldTypeNode[];
}
export interface StringConstantExprNode extends NamedNodeBase {
type: SyntaxType.StringConstantExpr;
}
export interface TupleExprNode extends NamedNodeBase {
type: SyntaxType.TupleExpr;
exprNodes: (AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode)[];
}
export interface TuplePatternNode extends NamedNodeBase {
type: SyntaxType.TuplePattern;
patternNodes: PatternNode[];
}
export interface TupleTypeNode extends NamedNodeBase {
type: SyntaxType.TupleType;
typeExpressionNodes: TypeExpressionNode[];
unitExprNode?: UnitExprNode;
}
export interface TypeAliasDeclarationNode extends NamedNodeBase {
type: SyntaxType.TypeAliasDeclaration;
nameNode: UpperCaseIdentifierNode;
typeExpressionNode: TypeExpressionNode;
typeVariableNodes: LowerTypeNameNode[];
}
export interface TypeAnnotationNode extends NamedNodeBase {
type: SyntaxType.TypeAnnotation;
nameNode: LowerCaseIdentifierNode;
typeExpressionNode: TypeExpressionNode;
}
export interface TypeDeclarationNode extends NamedNodeBase {
type: SyntaxType.TypeDeclaration;
nameNode: UpperCaseIdentifierNode;
typeNameNodes: LowerTypeNameNode[];
unionVariantNodes: UnionVariantNode[];
}
export interface TypeExpressionNode extends NamedNodeBase {
type: SyntaxType.TypeExpression;
partNodes: (RecordTypeNode | TupleTypeNode | TypeExpressionNode | TypeRefNode | TypeVariableNode)[];
}
export interface TypeRefNode extends NamedNodeBase {
type: SyntaxType.TypeRef;
partNodes: (RecordTypeNode | TupleTypeNode | TypeExpressionNode | TypeRefNode | TypeVariableNode)[];
}
export interface TypeVariableNode extends NamedNodeBase {
type: SyntaxType.TypeVariable;
}
export interface UnionPatternNode extends NamedNodeBase {
type: SyntaxType.UnionPattern;
argPatternNodes: (UnnamedNode<"("> | UnnamedNode<")"> | AnythingPatternNode | CharConstantExprNode | ListPatternNode | LowerPatternNode | NullaryConstructorArgumentPatternNode | NumberConstantExprNode | PatternNode | RecordPatternNode | StringConstantExprNode | TuplePatternNode | UnitExprNode)[];
constructorNode: UpperCaseQidNode;
}
export interface UnionVariantNode extends NamedNodeBase {
type: SyntaxType.UnionVariant;
nameNode: UpperCaseIdentifierNode;
partNodes: (RecordTypeNode | TupleTypeNode | TypeExpressionNode | TypeRefNode | TypeVariableNode)[];
}
export interface UnitExprNode extends NamedNodeBase {
type: SyntaxType.UnitExpr;
}
export interface UpperCaseQidNode extends NamedNodeBase {
type: SyntaxType.UpperCaseQid;
}
export interface ValueDeclarationNode extends NamedNodeBase {
type: SyntaxType.ValueDeclaration;
bodyNode: AnonymousFunctionExprNode | BinOpExprNode | CaseOfExprNode | CharConstantExprNode | FieldAccessExprNode | FieldAccessorFunctionExprNode | FunctionCallExprNode | GlslCodeExprNode | IfElseExprNode | LetInExprNode | ListExprNode | NegateExprNode | NumberConstantExprNode | OperatorAsFunctionExprNode | ParenthesizedExprNode | RecordExprNode | StringConstantExprNode | TupleExprNode | UnitExprNode | ValueExprNode;
functionDeclarationLeftNode?: FunctionDeclarationLeftNode;
patternNode?: PatternNode;
}
export interface ValueExprNode extends NamedNodeBase {
type: SyntaxType.ValueExpr;
nameNode: UpperCaseQidNode | ValueQidNode;
}
export interface ValueQidNode extends NamedNodeBase {
type: SyntaxType.ValueQid;
}
export interface AliasNode extends NamedNodeBase {
type: SyntaxType.Alias;
}
export interface ArrowNode extends NamedNodeBase {
type: SyntaxType.Arrow;
}
export interface AsNode extends NamedNodeBase {
type: SyntaxType.As;
}
export interface BackslashNode extends NamedNodeBase {
type: SyntaxType.Backslash;
}
export interface CaseNode extends NamedNodeBase {
type: SyntaxType.Case;
}
export interface CloseCharNode extends NamedNodeBase {
type: SyntaxType.CloseChar;
}
export interface CloseQuoteNode extends NamedNodeBase {
type: SyntaxType.CloseQuote;
}
export interface ColonNode extends NamedNodeBase {
type: SyntaxType.Colon;
}
export interface DotNode extends NamedNodeBase {
type: SyntaxType.Dot;
}
export interface DoubleDotNode extends NamedNodeBase {
type: SyntaxType.DoubleDot;
}
export interface EffectNode extends NamedNodeBase {
type: SyntaxType.Effect;
}
export interface EqNode extends NamedNodeBase {
type: SyntaxType.Eq;
}
export interface ExposingNode extends NamedNodeBase {
type: SyntaxType.Exposing;
}
export interface GlslContentNode extends NamedNodeBase {
type: SyntaxType.GlslContent;
}
export interface ImportNode extends NamedNodeBase {
type: SyntaxType.Import;
}
export interface InfixNode extends NamedNodeBase {
type: SyntaxType.Infix;
}
export interface InvalidStringEscapeNode extends NamedNodeBase {
type: SyntaxType.InvalidStringEscape;
}
export interface LineCommentNode extends NamedNodeBase {
type: SyntaxType.LineComment;
}
export interface LowerCaseIdentifierNode extends NamedNodeBase {
type: SyntaxType.LowerCaseIdentifier;
}
export interface ModuleNode extends NamedNodeBase {
type: SyntaxType.Module;
}
export interface NumberLiteralNode extends NamedNodeBase {
type: SyntaxType.NumberLiteral;
}
export interface OfNode extends NamedNodeBase {
type: SyntaxType.Of;
}
export interface OpenCharNode extends NamedNodeBase {
type: SyntaxType.OpenChar;
}
export interface OpenQuoteNode extends NamedNodeBase {
type: SyntaxType.OpenQuote;
}
export interface PortNode extends NamedNodeBase {
type: SyntaxType.Port;
}
export interface RegularStringPartNode extends NamedNodeBase {
type: SyntaxType.RegularStringPart;
}
export interface StringEscapeNode extends NamedNodeBase {
type: SyntaxType.StringEscape;
}
export interface TypeNode extends NamedNodeBase {
type: SyntaxType.Type;
}
export interface UnderscoreNode extends NamedNodeBase {
type: SyntaxType.Underscore;
}
export interface UpperCaseIdentifierNode extends NamedNodeBase {
type: SyntaxType.UpperCaseIdentifier;
}
export interface WhereNode extends NamedNodeBase {
type: SyntaxType.Where;
}

@ -0,0 +1,53 @@
{
"name": "@elm-tooling/tree-sitter-elm",
"version": "5.5.1",
"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.15.0",
"prebuild-install": "^6.1.4"
},
"devDependencies": {
"@asgerf/dts-tree-sitter": "^0.1.0",
"prebuild": "^10.0.1",
"tree-sitter-cli": "^0.20.4"
},
"scripts": {
"build": "tree-sitter generate && node-gyp build --debug",
"install": "prebuild-install || node-gyp rebuild",
"prebuild": "prebuild -r electron --all --strip --verbose",
"prebuild:upload": "prebuild --upload-all",
"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-types": "node ./node_modules/@asgerf/dts-tree-sitter/build/src/index.js src > index.d.ts",
"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"
]
}
]
}

@ -0,0 +1,76 @@
; 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

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

@ -0,0 +1,15 @@
(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)

@ -0,0 +1,19 @@
(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

@ -0,0 +1,18 @@
[
"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"
]

@ -0,0 +1,39 @@
[
"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"
]

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

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

@ -0,0 +1,79 @@
#!/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" "5a5bcf48720bc7d53461b3cd42a9f19f119c5503"
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" "edbf5e268ecc1572402c7747ae26abb2f92192ec"
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

@ -0,0 +1,65 @@
#!/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

@ -0,0 +1,507 @@
#include <tree_sitter/parser.h>
#include <algorithm>
#include <vector>
#include <string>
#include <cwctype>
#include <cstring>
namespace
{
using std::string;
using std::vector;
enum TokenType
{
VIRTUAL_END_DECL,
VIRTUAL_OPEN_SECTION,
VIRTUAL_END_SECTION,
MINUS_WITHOUT_TRAILING_WHITESPACE,
GLSL_CONTENT,
BLOCK_COMMENT_CONTENT
};
struct Scanner
{
Scanner() {}
unsigned serialize(char *buffer)
{
size_t i = 0;
size_t runback_count = runback.size();
if (runback_count > UINT8_MAX)
runback_count = UINT8_MAX;
buffer[i++] = runback_count;
if (runback_count > 0)
{
memcpy(&buffer[i], runback.data(), runback_count);
}
i += runback_count;
size_t indent_length_length = sizeof(indent_length);
buffer[i++] = indent_length_length;
if (indent_length_length > 0)
{
memcpy(&buffer[i], &indent_length, indent_length_length);
}
i += indent_length_length;
vector<uint32_t>::iterator
iter = indent_length_stack.begin() + 1,
end = indent_length_stack.end();
for (; iter != end && i < TREE_SITTER_SERIALIZATION_BUFFER_SIZE; ++iter)
{
buffer[i++] = *iter;
}
return i;
}
void deserialize(const char *buffer, unsigned length)
{
runback.clear();
indent_length_stack.clear();
indent_length_stack.push_back(0);
if (length > 0)
{
size_t i = 0;
size_t runback_count = (uint8_t)buffer[i++];
runback.resize(runback_count);
if (runback_count > 0)
{
memcpy(runback.data(), &buffer[i], runback_count);
}
i += runback_count;
size_t indent_length_length = buffer[i++];
if (indent_length_length > 0)
{
memcpy(&indent_length, &buffer[i], indent_length_length);
}
i += indent_length_length;
for (; i < length; i++)
{
indent_length_stack.push_back(buffer[i]);
}
}
}
void advance(TSLexer *lexer)
{
lexer->advance(lexer, false);
}
void skip(TSLexer *lexer)
{
lexer->advance(lexer, true);
}
bool isElmSpace(TSLexer *lexer)
{
return lexer->lookahead == ' ' || lexer->lookahead == '\r' || lexer->lookahead == '\n';
}
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 (isElmSpace(lexer) || lexer->eof(lexer))
{
return 2; // Success
}
return 1; // Partial
}
return 1; // Partial
}
return 0;
}
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);
}
}
}
void advance_to_line_end(TSLexer *lexer)
{
while(true)
{
if (lexer->lookahead == '\n') {
break;
}
else if (lexer->eof(lexer)) {
break;
} else {
advance(lexer);
}
}
}
bool scan(TSLexer *lexer, const bool *valid_symbols)
{
// First handle eventual runback tokens, we saved on a previous scan op
if (!runback.empty() && runback.back() == 0 && valid_symbols[VIRTUAL_END_DECL])
{
runback.pop_back();
lexer->result_symbol = VIRTUAL_END_DECL;
return true;
}
if (!runback.empty() && runback.back() == 1 && valid_symbols[VIRTUAL_END_SECTION])
{
runback.pop_back();
lexer->result_symbol = VIRTUAL_END_SECTION;
return true;
}
runback.clear();
// 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 == ' ')
{
skip(lexer);
}
else if (lexer->lookahead == '\n')
{
skip(lexer);
has_newline = true;
while (true)
{
if (lexer->lookahead == ' ')
{
skip(lexer);
}
else
{
indent_length = lexer->get_column(lexer);
break;
}
}
}
else if (!valid_symbols[BLOCK_COMMENT_CONTENT] && lexer->lookahead == '-')
{
advance(lexer);
auto 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;
}
else {
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.
else 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->lookahead == '\r')
{
skip(lexer);
}
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;
indent_length_stack.pop_back();
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))
{
indent_length_stack.push_back(lexer->get_column(lexer));
lexer->result_symbol = VIRTUAL_OPEN_SECTION;
return true;
}
else 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;
}
else 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
runback.clear();
while (indent_length <= indent_length_stack.back())
{
if (indent_length == indent_length_stack.back())
{
if (found_in)
{
runback.push_back(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;
}
}
runback.push_back(0);
break;
}
else if (indent_length < indent_length_stack.back())
{
indent_length_stack.pop_back();
runback.push_back(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)
{
runback.push_back(1);
found_in = false;
}
// Our list is the wrong way around, reverse it
std::reverse(runback.begin(), runback.end());
// Handle the first runback token if we have them, if there are more they will be handled on the next scan operation
if (!runback.empty() && runback.back() == 0 && valid_symbols[VIRTUAL_END_DECL])
{
runback.pop_back();
lexer->result_symbol = VIRTUAL_END_DECL;
return true;
}
else if (!runback.empty() && runback.back() == 1 && valid_symbols[VIRTUAL_END_SECTION])
{
runback.pop_back();
lexer->result_symbol = VIRTUAL_END_SECTION;
return true;
}
else 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;
}
// The indention of the current line
uint32_t indent_length;
// Our indentation stack
vector<uint32_t> indent_length_stack;
// Stack of 0 - for possible VIRTUAL_END_DECL or 1 - for possible VIRTUAL_END_SECTION
vector<uint8_t> runback;
};
} // namespace
extern "C"
{
void *tree_sitter_elm_external_scanner_create()
{
return new Scanner();
}
bool tree_sitter_elm_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols)
{
Scanner *scanner = static_cast<Scanner *>(payload);
return scanner->scan(lexer, valid_symbols);
}
unsigned tree_sitter_elm_external_scanner_serialize(void *payload, char *buffer)
{
Scanner *scanner = static_cast<Scanner *>(payload);
return scanner->serialize(buffer);
}
void tree_sitter_elm_external_scanner_deserialize(void *payload, const char *buffer, unsigned length)
{
Scanner *scanner = static_cast<Scanner *>(payload);
scanner->deserialize(buffer, length);
}
void tree_sitter_elm_external_scanner_destroy(void *payload)
{
Scanner *scanner = static_cast<Scanner *>(payload);
delete scanner;
}
}

@ -0,0 +1,223 @@
#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;
};
/*
* 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_

@ -0,0 +1,193 @@
================================================================================
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))))

@ -0,0 +1,102 @@
================================================================================
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

@ -0,0 +1,396 @@
================================================================================
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))

@ -0,0 +1,247 @@
================================================================================
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)))))

@ -0,0 +1,287 @@
================================================================================
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)))))))))

@ -0,0 +1,154 @@
================================================================================
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))))))

@ -0,0 +1,28 @@
================================================================================
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))))

@ -0,0 +1,63 @@
================================================================================
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)))

@ -0,0 +1,263 @@
================================================================================
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)))))

@ -0,0 +1,124 @@
================================================================================
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

@ -0,0 +1,237 @@
================================================================================
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)))))

@ -0,0 +1,37 @@
================================================================================
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))))))

@ -0,0 +1,130 @@
================================================================================
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)))))))))

@ -0,0 +1,201 @@
================================================================================
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)))))

@ -0,0 +1,143 @@
================================================================================
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))))

@ -0,0 +1,63 @@
================================================================================
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)))))))))

@ -0,0 +1,50 @@
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 "+" ]
]

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