mirror of https://github.com/Wilfred/difftastic/
Add 'vendor/tree-sitter-elm/' from commit '5128296ba8542853d59e6b7c8dfe3d1fb9a637ea'
git-subtree-dir: vendor/tree-sitter-elm git-subtree-mainline:pull/223/headd6e9afd3d6git-subtree-split:5128296ba8
commit
469f84b605
@ -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 @@
|
||||
[](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);
|
||||
};
|
||||
}
|
||||
})();
|
||||
Binary file not shown.
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/*"]
|
||||
}
|
||||
Loading…
Reference in New Issue