Add 'vendor/tree-sitter-scala/' from commit '0a3dd53a7fc4b352a538397d054380aaa28be54c'

git-subtree-dir: vendor/tree-sitter-scala
git-subtree-mainline: 2256c2f9f5
git-subtree-split: 0a3dd53a7f
pull/101/head
Hugo van Rijswijk 2022-01-18 11:37:22 +07:00
commit c2ec55f46a
30 changed files with 169194 additions and 0 deletions

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

@ -0,0 +1,20 @@
name: Build/test
on:
push:
pull_request:
branches:
- master
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 14
- run: npm install
- run: npm test

@ -0,0 +1,9 @@
node_modules
build
target
*.log
test.scala
package-lock.json
Cargo.lock
.scalafmt.conf
*worksheet.sc

@ -0,0 +1,3 @@
build
target
Cargo.lock

@ -0,0 +1,26 @@
[package]
name = "tree-sitter-scala"
description = "scala grammar for the tree-sitter parsing library"
version = "0.19.0"
keywords = ["incremental", "parsing", "scala"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/tree-sitter/tree-sitter-javascript"
edition = "2018"
license = "MIT"
build = "bindings/rust/build.rs"
include = [
"bindings/rust/*",
"grammar.js",
"queries/*",
"src/*",
]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "0.19"
[build-dependencies]
cc = "1.0"

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 Max Brunsfeld and GitHub
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,28 @@
tree-sitter-scala
=================
[![Test the grammar](https://github.com/tree-sitter/tree-sitter-scala/actions/workflows/ci.yml/badge.svg)](https://github.com/tree-sitter/tree-sitter-scala/actions/workflows/ci.yml)
Scala grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
References
* [The Scala Language Specification](https://www.scala-lang.org/files/archive/spec/2.13/)
* [Scala Syntax Summary](https://www.scala-lang.org/files/archive/spec/2.13/13-syntax-summary.html)
Development
-----------
First, install the project's dependencies:
```sh
npm install
```
Add a test case to `./corpus`, make the required changes to `grammar.js`,
regenerate and recompile the parser, and run the tests:
```sh
npm run build
npm test
```

@ -0,0 +1,19 @@
{
"targets": [
{
"target_name": "tree_sitter_scala_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"src/parser.c",
"bindings/node/binding.cc",
"src/scanner.c"
],
"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_scala();
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_scala());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("scala").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(tree_sitter_scala_binding, Init)
} // namespace

@ -0,0 +1,19 @@
try {
module.exports = require("../../build/Release/tree_sitter_scala_binding");
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_scala_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,16 @@
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");
let scanner_path = src_dir.join("scanner.c");
c_config.file(&parser_path);
c_config.file(&scanner_path);
c_config.compile("parser");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
}

@ -0,0 +1,52 @@
//! This crate provides scala 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_scala::language()).expect("Error loading scala 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_scala() -> 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_scala() }
}
/// 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 scala language");
}
}

@ -0,0 +1,87 @@
================================
Classes
================================
@deprecated("Use D", "1.0") class C {}
---
(compilation_unit
(class_definition
(annotation (type_identifier) (arguments (string) (string)))
(identifier)
(template_body)))
================================
Declarations and definitions
================================
class A(x: String) {
@transient @volatile var y: Int
@transient @volatile val z = x
@throws(Error)
@deprecated(message = "Don't use this", since = "1.0")
def foo() {}
}
---
(compilation_unit
(class_definition (identifier)
(class_parameters (class_parameter (identifier) (type_identifier)))
(template_body
(var_declaration
(annotation (type_identifier))
(annotation (type_identifier))
(identifier) (type_identifier))
(val_definition
(annotation (type_identifier))
(annotation (type_identifier))
(identifier) (identifier))
(function_definition
(annotation (type_identifier) (arguments (identifier)))
(annotation (type_identifier)
(arguments
(assignment_expression (identifier) (string))
(assignment_expression (identifier) (string))))
(identifier) (parameters) (block)))))
================================
Parameters
================================
class A(@one x: String) {
def foo(@another x: Int) {}
}
---
(compilation_unit
(class_definition (identifier)
(class_parameters
(class_parameter
(annotation (type_identifier)) (identifier) (type_identifier)))
(template_body
(function_definition
(identifier)
(parameters (parameter
(annotation (type_identifier))
(identifier) (type_identifier)))
(block)))))
================================
Types
================================
trait Function0[@specialized(Unit, Int, Double) T] {
def apply: T
}
---
(compilation_unit
(trait_definition (identifier)
(type_parameters
(annotation (type_identifier) (arguments (identifier) (identifier) (identifier))) (identifier))
(template_body (function_declaration (identifier) (type_identifier)))))

@ -0,0 +1,450 @@
================================
Package
================================
package a.b
package c {
object A
}
---
(compilation_unit
(package_clause (package_identifier (identifier) (identifier)))
(package_clause (package_identifier (identifier))
(template_body
(object_definition (identifier)))))
================================
Package object
================================
package object d extends A {
val hello: String = "there"
}
---
(compilation_unit
(package_object
(identifier)
(extends_clause (type_identifier))
(template_body
(val_definition (identifier) (type_identifier) (string)))))
================================
Imports
================================
import PartialFunction.condOpt
import a.b, c.e
import reflect.io.{Directory, File, Path}
---
(compilation_unit
(import_declaration
(stable_identifier (identifier) (identifier)))
(import_declaration
(stable_identifier (identifier) (identifier))
(stable_identifier (identifier) (identifier)))
(import_declaration
(stable_identifier (identifier) (identifier))
(import_selectors (identifier) (identifier) (identifier))))
================================
Imports: Wildcard
================================
import tools.nsc.classpath._
---
(compilation_unit
(import_declaration
(stable_identifier (stable_identifier (identifier) (identifier)) (identifier))
(wildcard)))
================================
Imports: Rename
================================
import lang.System.{lineSeparator => EOL}
---
(compilation_unit
(import_declaration
(stable_identifier (identifier) (identifier))
(import_selectors (renamed_identifier (identifier) (identifier)))))
=================================
Object definitions
=================================
// o1
object O1 {
}
case object O2 {
}
object O3 extends A {
}
---
(compilation_unit
(comment)
(object_definition (identifier) (template_body))
(object_definition (identifier) (template_body))
(object_definition (identifier) (extends_clause (type_identifier)) (template_body)))
=======================================
Class definitions
=======================================
class C[T, U] {
}
---
(compilation_unit
(class_definition
(identifier)
(type_parameters (identifier) (identifier))
(template_body)))
=======================================
Subclass definitions
=======================================
class A extends B.C[D, E] {
}
class A(b: B) extends C(b || ok) {
}
object C {
class A
extends B[T]
with C[T]
}
---
(compilation_unit
(class_definition
(identifier)
(extends_clause
(generic_type
(stable_type_identifier
(identifier)
(type_identifier))
(type_arguments (type_identifier) (type_identifier))))
(template_body))
(class_definition
(identifier)
(class_parameters
(class_parameter (identifier) (type_identifier)))
(extends_clause
(type_identifier)
(arguments
(infix_expression (identifier) (operator_identifier) (identifier))))
(template_body))
(object_definition
(identifier)
(template_body
(class_definition (identifier) (extends_clause
(compound_type
(generic_type (type_identifier) (type_arguments (type_identifier)))
(generic_type (type_identifier) (type_arguments (type_identifier)))))))))
=======================================
Class definitions with parameters
=======================================
class Point(val x: Int, val y: Int)(implicit coord: Coord)
---
(compilation_unit
(class_definition
(identifier)
(class_parameters
(class_parameter (identifier) (type_identifier))
(class_parameter (identifier) (type_identifier)))
(class_parameters
(class_parameter (identifier) (type_identifier)))))
=======================================
Modifiers
=======================================
implicit final sealed class Point {
private override def getX() = 1
}
private[a] class D[T] private (x: T) {
private[a] def b: Byte
}
---
(compilation_unit
(class_definition
(modifiers)
(identifier)
(template_body
(function_definition
(modifiers (access_modifier))
(identifier)
(parameters)
(integer_literal))))
(class_definition (modifiers (access_modifier (access_qualifier (identifier))))
(identifier) (type_parameters (identifier))
(access_modifier) (class_parameters (class_parameter (identifier) (type_identifier)))
(template_body (function_declaration
(modifiers (access_modifier (access_qualifier (identifier))))
(identifier) (type_identifier)))))
=======================================
Trait definitions
=======================================
trait A extends B
trait A extends B with C
trait T[U] {
}
trait T[U] extends V.W[U] {
}
---
(compilation_unit
(trait_definition
(identifier)
(extends_clause (type_identifier)))
(trait_definition
(identifier)
(extends_clause (compound_type (type_identifier) (type_identifier))))
(trait_definition
(identifier)
(type_parameters (identifier))
(template_body))
(trait_definition
(identifier)
(type_parameters (identifier))
(extends_clause (generic_type
(stable_type_identifier (identifier) (type_identifier))
(type_arguments (type_identifier))))
(template_body)))
=======================================
Value declarations
=======================================
class A {
val b, c : Int
val d : String
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(val_declaration
(identifier)
(identifier)
(type_identifier))
(val_declaration
(identifier)
(type_identifier)))))
=======================================
Value definitions
=======================================
class A {
val b = 1
val c : String = "d"
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(val_definition
(identifier)
(integer_literal))
(val_definition
(identifier)
(type_identifier)
(string)))))
=======================================
Variable declarations
=======================================
class A {
var b, c : Int
var d : String
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(var_declaration
(identifier)
(identifier)
(type_identifier))
(var_declaration
(identifier)
(type_identifier)))))
=======================================
Variable definitions
=======================================
class A {
var b : Int = 1
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(var_definition
(identifier)
(type_identifier)
(integer_literal)))))
=======================================
Type definitions
=======================================
class A {
type B = C
type D[E] = F
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(type_definition
(type_identifier)
(type_identifier))
(type_definition
(type_identifier)
(type_parameters (identifier))
(type_identifier)))))
=======================================
Function declarations
=======================================
class A {
def b(c: D) : E
def <*[B](that: IO[B]): IO[A]
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_declaration
(identifier)
(parameters (parameter (identifier) (type_identifier)))
(type_identifier))
(function_declaration
(operator_identifier)
(type_parameters (identifier))
(parameters (parameter (identifier) (generic_type (type_identifier) (type_arguments (type_identifier)))))
(generic_type (type_identifier) (type_arguments (type_identifier)))))))
=======================================
Function definitions
=======================================
class A {
def b(c: D, e: F) = 1
def g[H](i) {
j
}
def h(x: T)(implicit ev: Reads[T])
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters
(parameter (identifier) (type_identifier))
(parameter (identifier) (type_identifier)))
(integer_literal))
(function_definition
(identifier)
(type_parameters (identifier))
(parameters (parameter (identifier)))
(block (identifier)))
(function_declaration
(identifier)
(parameters (parameter (identifier) (type_identifier)))
(parameters (parameter (identifier) (generic_type (type_identifier) (type_arguments (type_identifier)))))))))
=======================================
Initialization expressions
=======================================
class A(val x: Int, val y: Int) {
assert(x != 0)
}
---
(compilation_unit
(class_definition
(identifier)
(class_parameters
(class_parameter (identifier) (type_identifier))
(class_parameter (identifier) (type_identifier)))
(template_body
(call_expression (identifier)
(arguments (infix_expression (identifier) (operator_identifier) (integer_literal)))))))
=======================================
Optional parameters
=======================================
def mkLines(header: String, indented: Boolean = false, repeated: Long = 0L): String = {}
---
(compilation_unit
(function_definition
(identifier)
(parameters
(parameter (identifier) (type_identifier))
(parameter (identifier) (type_identifier) (boolean_literal))
(parameter (identifier) (type_identifier) (integer_literal)))
(type_identifier) (block)))

@ -0,0 +1,625 @@
===============================
Call expressions
===============================
class C {
def main() {
a()
a(123)
a(b, c)
a.map(x => x + 1)
a { 123 }
a { b }
a.map{ x => x + 1 }
a.exists { case ((i, _)) => i }
}
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(call_expression (identifier) (arguments))
(call_expression (identifier) (arguments (integer_literal)))
(call_expression (identifier) (arguments (identifier) (identifier)))
(call_expression (field_expression (identifier) (identifier)) (arguments
(lambda_expression (identifier)
(infix_expression (identifier) (operator_identifier) (integer_literal)))))
(call_expression (identifier) (block (integer_literal)))
(call_expression (identifier) (block (identifier)))
(call_expression (field_expression (identifier) (identifier)) (block
(lambda_expression (identifier)
(infix_expression (identifier) (operator_identifier) (integer_literal)))))
(call_expression (field_expression (identifier) (identifier)) (case_block (case_clause
(tuple_pattern (tuple_pattern (identifier) (wildcard))) (identifier)))))))))
===============================
Generic functions
===============================
class C {
def main() {
a[T]()
List[Traversable[ClassPath]]()
}
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(call_expression
(generic_function
(identifier)
(type_arguments (type_identifier)))
(arguments))
(call_expression
(generic_function
(identifier)
(type_arguments
(generic_type (type_identifier) (type_arguments (type_identifier)))))
(arguments)))))))
===============================
Assignments
===============================
class C {
def main() {
a = b
a(1) = c
}
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(assignment_expression (identifier) (identifier))
(assignment_expression (call_expression (identifier) (arguments (integer_literal))) (identifier))
)
)
)
)
)
===============================
If expressions
===============================
class C {
def main() {
if (a) b()
if (c) {
d()
e()
} else if (f) {
g()
} else {
h()
}
}
}
def other() {
if (a) {
b
}
else c()
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(if_expression
(parenthesized_expression (identifier))
(call_expression (identifier) (arguments)))
(if_expression
(parenthesized_expression (identifier))
(block (call_expression (identifier) (arguments)) (call_expression (identifier) (arguments)))
(if_expression
(parenthesized_expression (identifier))
(block (call_expression (identifier) (arguments)))
(block (call_expression (identifier) (arguments)))))))))
(function_definition
(identifier)
(parameters)
(block
(if_expression
(parenthesized_expression (identifier))
(block (identifier))
(call_expression (identifier) (arguments))))))
===============================
Try expressions
===============================
def main() {
try a() finally depth -= 1
try {
doThing()
} catch {
case e: SomeException => prinlnt(e.message)
case NonFatal(ex) => throw new SomeException(ex)
} finally {
tryAnotherThing()
}
try b()
catch { case e => println(e) }
finally doFinalThing()
try a()
finally b()
}
---
(compilation_unit
(function_definition
(identifier)
(parameters)
(block
(try_expression
(call_expression (identifier) (arguments))
(finally_clause (infix_expression (identifier) (operator_identifier) (integer_literal))))
(try_expression
(block (call_expression (identifier) (arguments)))
(catch_clause
(case_block
(case_clause
(typed_pattern
(identifier)
(type_identifier))
(call_expression
(identifier)
(arguments (field_expression
(identifier)
(identifier)))))
(case_clause
(case_class_pattern
(type_identifier)
(identifier))
(throw_expression (instance_expression (call_expression (identifier) (arguments (identifier))))
)
)
)
)
(finally_clause (block (call_expression (identifier) (arguments))))
)
(try_expression (call_expression (identifier) (arguments))
(catch_clause (case_block (case_clause
(identifier)
(call_expression
(identifier)
(arguments (identifier))))))
(finally_clause (call_expression (identifier) (arguments))))
(try_expression (call_expression (identifier) (arguments))
(finally_clause (call_expression (identifier) (arguments)))))))
===============================
Match expressions
===============================
def matchTest(x: Int): String = x match {
case 0 =>
case 1 => "one"; "uno"
case 2 => "two"
case 3 => {
"3"
}
case ((i, _)) => i
case _ =>
val x = "many"
"more"
}
---
(compilation_unit
(function_definition
(identifier)
(parameters (parameter (identifier) (type_identifier)))
(type_identifier)
(match_expression (identifier) (case_block
(case_clause (integer_literal))
(case_clause (integer_literal) (string) (string))
(case_clause (integer_literal) (string))
(case_clause (integer_literal) (block (string)))
(case_clause (tuple_pattern (tuple_pattern (identifier) (wildcard))) (identifier))
(case_clause (wildcard) (val_definition (identifier) (string)) (string))))))
===============================
Field expressions
===============================
class C {
def main() {
a.b = c
a.b.d
}
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(assignment_expression
(field_expression (identifier) (identifier))
(identifier))
(field_expression
(field_expression (identifier) (identifier))
(identifier)))))))
===============================
Instance expressions
===============================
class C {
def main() {
a = new B
c = new D(e, f)
}
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(assignment_expression (identifier) (instance_expression (identifier)))
(assignment_expression (identifier) (instance_expression (call_expression (identifier) (arguments (identifier) (identifier))))))))))
===============================
Infix expressions
===============================
class C {
def main() {
a = b max c
d + e + f
}
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(assignment_expression
(identifier)
(infix_expression (identifier) (identifier) (identifier)))
(infix_expression
(infix_expression (identifier) (operator_identifier) (identifier))
(operator_identifier)
(identifier)))))))
===============================
Prefix expressions
===============================
class C {
def main() {
!a
!!a
+a + b
}
}
---
(compilation_unit
(class_definition
(identifier)
(template_body
(function_definition
(identifier)
(parameters)
(block
(prefix_expression (identifier))
(prefix_expression (prefix_expression (identifier)))
(infix_expression
(prefix_expression (identifier))
(operator_identifier)
(identifier)))))))
===============================
Postfix expressions
===============================
object O {
val v = "value" toUpperCase
val c = 1 + 2 toString
}
---
(compilation_unit
(object_definition
(identifier)
(template_body
(val_definition
(identifier)
(postfix_expression (string) (identifier)))
(val_definition
(identifier)
(postfix_expression
(infix_expression (integer_literal) (operator_identifier) (integer_literal))
(identifier)
)
)
)
)
)
===============================
Ascription Expression
===============================
object O {
val l = a: List
val x = 2: Byte
Nil: List[String]
3: _*
}
---
(compilation_unit
(object_definition
(identifier)
(template_body
(val_definition (identifier)
(ascription_expression (identifier)
(type_identifier)))
(val_definition (identifier)
(ascription_expression (integer_literal)
(type_identifier)))
(ascription_expression (identifier)
(generic_type (type_identifier)
(type_arguments (type_identifier))))
(ascription_expression (integer_literal)
(repeated_parameter_type (type_identifier))))))
================================================================================
Lambda Expression
================================================================================
object O {
val l = a => a + 1
val b = (x: Int, y: Int) => { x * y }
val f = _ => 2
(a, b, _) => a - b
}
--------------------------------------------------------------------------------
(compilation_unit
(object_definition (identifier)
(template_body (val_definition
(identifier) (lambda_expression
(identifier) (infix_expression
(identifier) (operator_identifier) (integer_literal))))
(val_definition (identifier)
(lambda_expression (bindings
(binding (identifier) (type_identifier))
(binding (identifier) (type_identifier)))
(block (infix_expression
(identifier) (operator_identifier) (identifier)))))
(val_definition (identifier)
(lambda_expression (identifier) (integer_literal)))
(lambda_expression
(bindings
(binding (identifier))
(binding (identifier))
(binding (identifier)))
(infix_expression (identifier)
(operator_identifier)
(identifier))))))
===============================
Unit expressions
===============================
val x = ()
def f(): Unit = { (
); }
---
(compilation_unit
(val_definition (identifier) (unit))
(function_definition (identifier) (parameters) (type_identifier) (block (unit)))
)
===============================
Return expressions
===============================
def f: Unit = return
def g(a: A): B = { f(); return null.asInstanceOf[B] }
---
(compilation_unit
(function_definition (identifier) (type_identifier) (return_expression))
(function_definition
(identifier)
(parameters (parameter (identifier) (type_identifier)))
(type_identifier)
(block
(call_expression
(identifier)
(arguments))
(return_expression
(generic_function (field_expression (null_literal) (identifier))
(type_arguments (type_identifier))))
)
)
)
===============================
While loops
===============================
def f = {
while(a) g()
while(b < c) {
d
}
}
---
(compilation_unit
(function_definition
(identifier)
(block
(while_expression
(parenthesized_expression (identifier))
(call_expression (identifier) (arguments)))
(while_expression
(parenthesized_expression (infix_expression (identifier) (operator_identifier) (identifier)))
(block (identifier))))))
===============================
Do-while loops
===============================
def f() = {
do g(a, b) while(c && d)
do {
g(a, b)
h(a, b)
} while (c < d)
}
---
(compilation_unit
(function_definition
(identifier)
(parameters)
(block
(do_while_expression
(call_expression (identifier) (arguments (identifier) (identifier)))
(parenthesized_expression (infix_expression (identifier) (operator_identifier) (identifier))))
(do_while_expression
(block
(call_expression (identifier) (arguments (identifier) (identifier)))
(call_expression (identifier) (arguments (identifier) (identifier))))
(parenthesized_expression (infix_expression (identifier) (operator_identifier) (identifier)))))))
===============================
For comprehensions
===============================
def f() = {
for (n <- nums) yield n + 1
for (x <- xs; y <- ys) g(x, y)
for {
x <- xs
a = b + c
y <- g() if d
(t, u) = y
} yield {
h(x, y)
}
}
---
(compilation_unit
(function_definition
(identifier)
(parameters)
(block
(for_expression
(enumerators (enumerator (identifier) (identifier)))
(infix_expression (identifier) (operator_identifier) (integer_literal)))
(for_expression
(enumerators
(enumerator (identifier) (identifier))
(enumerator (identifier) (identifier)))
(call_expression (identifier) (arguments (identifier) (identifier))))
(for_expression
(enumerators
(enumerator (identifier) (identifier))
(enumerator (identifier) (infix_expression (identifier) (operator_identifier) (identifier)))
(enumerator (identifier) (call_expression (identifier) (arguments)) (guard (identifier)))
(enumerator (tuple_pattern (identifier) (identifier)) (identifier)))
(block (call_expression (identifier) (arguments (identifier) (identifier))))))))
===============================
Chained expressions
===============================
def main() {
val myList = List(1, 2, 3)
myList.map(_ * 2)
myList
.map(_ * 2)
myList
.length
}
---
(compilation_unit
(function_definition
(identifier)
(parameters)
(block
(val_definition (identifier) (call_expression
(identifier)
(arguments (integer_literal) (integer_literal) (integer_literal))))
(call_expression
(field_expression (identifier) (identifier))
(arguments (infix_expression
(identifier) (operator_identifier) (integer_literal))))
(call_expression
(field_expression (identifier) (identifier))
(arguments (infix_expression
(identifier) (operator_identifier) (integer_literal))))
(field_expression (identifier) (identifier)))))

@ -0,0 +1,175 @@
==========================
Simple strings
==========================
val oneLineString = "I'm just on one line"
val multiLineString = """
a
$thisIsntInterpolated
${thisEither}
"""
---
(compilation_unit
(val_definition (identifier) (string))
(val_definition (identifier) (string)))
==========================
Interpolated strings
==========================
val string1 = s"a $b ${c}"
val string2 = f"hi $name%s"
val string3 = raw"Not a new line \n${ha}"
val string4 = s"""
works even in multiline strings, ${name}
"""
---
(compilation_unit
(val_definition
(identifier)
(interpolated_string_expression
(identifier) (interpolated_string
(interpolation (identifier))
(interpolation (block (identifier))))))
(val_definition
(identifier)
(interpolated_string_expression
(identifier) (interpolated_string
(interpolation (identifier)))))
(val_definition
(identifier)
(interpolated_string_expression
(identifier) (interpolated_string
(interpolation (block (identifier))))))
(val_definition
(identifier)
(interpolated_string_expression
(identifier) (interpolated_string
(interpolation (block (identifier)))))))
==========================
Integer literals
==========================
val i1 = 0
val i2 = 1234
val i3 = -0xF2
val i4 = 0XA0
val l1 = -0l
val l2 = 1234L
val l3 = 0xF23l
val l4 = 0XA03L
---
(compilation_unit
(val_definition (identifier) (integer_literal))
(val_definition (identifier) (integer_literal))
(val_definition (identifier) (integer_literal))
(val_definition (identifier) (integer_literal))
(val_definition (identifier) (integer_literal))
(val_definition (identifier) (integer_literal))
(val_definition (identifier) (integer_literal))
(val_definition (identifier) (integer_literal))
)
==========================
Floating point literals
==========================
val f1 = 3.14
val f2 = -3f
val f2 = 3E-1
val d1 = .314D
---
(compilation_unit
(val_definition (identifier) (floating_point_literal))
(val_definition (identifier) (floating_point_literal))
(val_definition (identifier) (floating_point_literal))
(val_definition (identifier) (floating_point_literal))
)
==========================
Boolean literals
==========================
val myBool = true
def foo(a: Boolean = false) = a && true
---
(compilation_unit
(val_definition (identifier) (boolean_literal))
(function_definition
(identifier)
(parameters (parameter
(identifier)
(type_identifier)
(boolean_literal)))
(infix_expression
(identifier)
(operator_identifier)
(boolean_literal))))
==========================
Character literals
==========================
val myChar = 'c'
val otherChar = '\u0041'
val anotherChar = '\n'
def foo(a: Char = 'c') = a + 'd'
---
(compilation_unit
(val_definition (identifier) (character_literal))
(val_definition (identifier) (character_literal))
(val_definition (identifier) (character_literal))
(function_definition
(identifier)
(parameters (parameter
(identifier)
(type_identifier)
(character_literal)))
(infix_expression
(identifier)
(operator_identifier)
(character_literal))))
==========================
Symbol literals
==========================
val mySymbol = 'c
val myOtherSymbol = 'thing
---
(compilation_unit
(val_definition (identifier) (symbol_literal))
(val_definition (identifier) (symbol_literal)))
==========================
Null
==========================
lazy val nullObject: String = null
---
(compilation_unit (val_definition (modifiers) (identifier) (type_identifier) (null_literal)))

@ -0,0 +1,171 @@
=========================
Alternative patterns
=========================
val x = y match {
case 1 | a => b
case "c" | "d" | "e" => f
}
---
(compilation_unit
(val_definition
(identifier)
(match_expression (identifier) (case_block
(case_clause
(alternative_pattern (integer_literal) (identifier))
(identifier))
(case_clause
(alternative_pattern
(alternative_pattern (string) (string))
(string))
(identifier))))))
=========================
Typed patterns
=========================
val x = y match {
case 1 : Int => 2
case a : B with C => d
case _: B | _: C => 3
case Object.Constant => 3
}
---
(compilation_unit
(val_definition
(identifier)
(match_expression (identifier) (case_block
(case_clause
(typed_pattern (integer_literal) (type_identifier)) (integer_literal))
(case_clause
(typed_pattern (identifier) (compound_type (type_identifier) (type_identifier)))
(identifier))
(case_clause
(alternative_pattern
(typed_pattern (wildcard) (type_identifier))
(typed_pattern (wildcard) (type_identifier)))
(integer_literal))
(case_clause
(stable_identifier (identifier) (identifier))
(integer_literal))))))
============================
Tuple patterns
============================
val (a, b) = if (c) (d, e) else (f, g)
val x = y match {
case (A, B) => X
}
---
(compilation_unit
(val_definition
(tuple_pattern (identifier) (identifier))
(if_expression
(parenthesized_expression (identifier))
(tuple_expression (identifier) (identifier))
(tuple_expression (identifier) (identifier))))
(val_definition (identifier)
(match_expression (identifier)
(case_block
(case_clause
(tuple_pattern (identifier) (identifier)) (identifier))))))
============================
Case class patterns
============================
def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
s"You got an email from $email with title: $title"
case SMS(number, message) =>
s"You got an SMS from $number! Message: $message"
case VoiceRecording(name, link) =>
s"you received a Voice Recording from $name! Click the link to hear it: $link"
}
}
---
(compilation_unit
(function_definition
(identifier)
(parameters (parameter (identifier) (type_identifier)))
(type_identifier)
(block
(match_expression (identifier) (case_block
(case_clause
(case_class_pattern (type_identifier) (identifier) (identifier) (wildcard))
(interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier)))))
(case_clause
(case_class_pattern (type_identifier) (identifier) (identifier))
(interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier)))))
(case_clause
(case_class_pattern (type_identifier) (identifier) (identifier))
(interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier))))))))))
============================
Infix patterns
============================
def first(x: Seq[Int]) = x match {
case e :+ _ => Some(e)
case _ => None
}
---
(compilation_unit
(function_definition (identifier)
(parameters (parameter (identifier) (generic_type (type_identifier) (type_arguments (type_identifier)))))
(match_expression (identifier)
(case_block
(case_clause (infix_pattern (identifier) (operator_identifier) (wildcard))
(call_expression (identifier) (arguments (identifier))))
(case_clause (wildcard)
(identifier))))))
============================
Capture patterns
============================
val x = y match {
case a @ B(1) => a
case b @ C(d @ (e @ X, _: Y)) => e
case req @ (POST | GET) -> Root / "test" => 5
}
---
(compilation_unit
(val_definition
(identifier)
(match_expression
(identifier)
(case_block
(case_clause
(capture_pattern (identifier) (case_class_pattern (type_identifier) (integer_literal)))
(identifier))
(case_clause
(capture_pattern (identifier)
(case_class_pattern (type_identifier)
(capture_pattern (identifier)
(tuple_pattern
(capture_pattern (identifier) (identifier))
(typed_pattern (wildcard) (type_identifier))))))
(identifier))
(case_clause
(infix_pattern
(infix_pattern
(capture_pattern (identifier)
(tuple_pattern (alternative_pattern (identifier) (identifier))))
(operator_identifier) (identifier)) (operator_identifier) (string))
(integer_literal))))))

@ -0,0 +1,252 @@
===================================
Stable type identifiers
===================================
object Main {
type A = B.C
type D = E.F.G
}
---
(compilation_unit
(object_definition (identifier) (template_body
(type_definition
(type_identifier)
(stable_type_identifier (identifier) (type_identifier)))
(type_definition
(type_identifier)
(stable_type_identifier (stable_identifier (identifier) (identifier)) (type_identifier))))))
===================================
Generic types
===================================
object Main {
type A = B[C, D]
type E = F.G[H]
}
---
(compilation_unit
(object_definition (identifier) (template_body
(type_definition
(type_identifier)
(generic_type
(type_identifier)
(type_arguments (type_identifier) (type_identifier))))
(type_definition
(type_identifier)
(generic_type
(stable_type_identifier (identifier) (type_identifier))
(type_arguments (type_identifier)))))))
===================================
Tuple types
===================================
object Main {
type A = (B, C)
}
---
(compilation_unit
(object_definition (identifier) (template_body
(type_definition
(type_identifier)
(tuple_type
(type_identifier)
(type_identifier))))))
===================================
Function types
===================================
object Main {
type A = (B, C) => D
type A = (B, C) => (D, E)
type A = B => (D, E)
}
---
(compilation_unit
(object_definition (identifier) (template_body
(type_definition
(type_identifier)
(function_type
(parameter_types (type_identifier) (type_identifier))
(type_identifier)))
(type_definition
(type_identifier)
(function_type
(parameter_types (type_identifier) (type_identifier))
(tuple_type (type_identifier) (type_identifier))))
(type_definition
(type_identifier)
(function_type
(parameter_types (type_identifier))
(tuple_type (type_identifier) (type_identifier)))))))
==================================
Compound types
==================================
def cloneAndReset(obj: Cloneable with Resetable): Cloneable = {
}
class F extends Cloneable with Resetable with Serializable {}
---
(compilation_unit
(function_definition
(identifier)
(parameters (parameter (identifier) (compound_type (type_identifier) (type_identifier))))
(type_identifier) (block))
(class_definition (identifier)
(extends_clause
(compound_type (type_identifier) (type_identifier) (type_identifier)))
(template_body)))
==================================
Infix types
==================================
type A = B Foo C
type A = B ! C or D
type A = (B, C) ~ D
---
(compilation_unit
(type_definition
(type_identifier)
(infix_type (type_identifier) (identifier) (type_identifier)))
(type_definition
(type_identifier)
(infix_type
(infix_type (type_identifier) (operator_identifier) (type_identifier))
(identifier)
(type_identifier)))
(type_definition
(type_identifier)
(infix_type
(tuple_type (type_identifier) (type_identifier))
(operator_identifier)
(type_identifier))))
==================================
Variant Types
==================================
class Function1[-T1, +R]
---
(compilation_unit
(class_definition
(identifier)
(type_parameters
(contravariant_type_parameter (identifier))
(covariant_type_parameter (identifier)))))
==================================
Upper bound
==================================
class A[B <: C]
---
(compilation_unit
(class_definition
(identifier)
(type_parameters
(identifier)
(upper_bound (type_identifier)))))
==================================
Lower bound
==================================
class A[B >: C]
---
(compilation_unit
(class_definition
(identifier)
(type_parameters
(identifier)
(lower_bound (type_identifier)))))
==================================
View bound
==================================
class A[B <% C <% D]
---
(compilation_unit
(class_definition
(identifier)
(type_parameters
(identifier)
(view_bound (type_identifier))
(view_bound (type_identifier)))))
==================================
Context bound
==================================
class A[B : C : D]
---
(compilation_unit
(class_definition
(identifier)
(type_parameters
(identifier)
(context_bound (type_identifier))
(context_bound (type_identifier)))))
==================================
Projections
==================================
type A = B[C]#D
---
(compilation_unit
(type_definition (type_identifier)
(projected_type
(generic_type (type_identifier) (type_arguments (type_identifier)))
(type_identifier))))
==================================
Complex types
==================================
type A = B with B1 with B2 ! C with C1
---
(compilation_unit
(type_definition (type_identifier)
(infix_type
(compound_type (type_identifier) (type_identifier) (type_identifier))
(operator_identifier)
(compound_type (type_identifier) (type_identifier)))))

@ -0,0 +1,9 @@
package a.b
package c {
object A
}
package c {
package object d {
val hello: String = "there"
}
}

@ -0,0 +1,289 @@
/* NSC -- new Scala compiler
* Copyright 2006-2013 LAMP/EPFL
* @author Paul Phillips
*/
package scala
package tools
package util
import java.net.URL
import scala.tools.reflect.WrappedProperties.AccessControl
import scala.tools.nsc.Settings
import scala.tools.nsc.util.ClassPath
import scala.reflect.io.{Directory, File, Path}
import PartialFunction.condOpt
import scala.tools.nsc.classpath._
// Loosely based on the draft specification at:
// https://wiki.scala-lang.org/display/SIW/Classpath
object PathResolver {
// Imports property/environment functions which suppress security exceptions.
import AccessControl._
import java.lang.System.{lineSeparator => EOL}
implicit class MkLines(val t: TraversableOnce[_]) extends AnyVal {
def mkLines: String = t.mkString("", EOL, EOL)
def mkLines(header: String, indented: Boolean = false, embraced: Boolean = false): String = {
val space = "\u0020"
val sep = if (indented) EOL + space * 2 else EOL
val (lbrace, rbrace) = if (embraced) (space + "{", EOL + "}") else ("", "")
t.mkString(header + lbrace + sep, sep, rbrace + EOL)
}
}
implicit class AsLines(val s: String) extends AnyVal {
// sm"""...""" could do this in one pass
def asLines = s.trim.stripMargin.lines.mkLines
}
/** pretty print class path */
def ppcp(s: String) = ClassPath.split(s) match {
case Nil => ""
case Seq(x) => x
case xs => xs.mkString(EOL, EOL, "")
}
/** Values found solely by inspecting environment or property variables.
*/
object Environment {
import scala.collection.JavaConverters._
private def searchForBootClasspath =
System.getProperties.asScala collectFirst { case (k, v) if k endsWith ".boot.class.path" => v } getOrElse ""
/** Environment variables which java pays attention to so it
* seems we do as well.
*/
def sourcePathEnv = envOrElse("SOURCEPATH", "")
def javaBootClassPath = propOrElse("sun.boot.class.path", searchForBootClasspath)
def javaExtDirs = propOrEmpty("java.ext.dirs")
def scalaHome = propOrEmpty("scala.home")
def scalaExtDirs = propOrEmpty("scala.ext.dirs")
/** The java classpath and whether to use it. */
def javaUserClassPath = propOrElse("java.class.path", "")
def useJavaClassPath = propOrFalse("scala.usejavacp")
override def toString = s"""
|object Environment {
| scalaHome = $scalaHome (useJavaClassPath = $useJavaClassPath)
| javaBootClassPath = <${javaBootClassPath.length} chars>
| javaExtDirs = ${ppcp(javaExtDirs)}
| javaUserClassPath = ${ppcp(javaUserClassPath)}
| scalaExtDirs = ${ppcp(scalaExtDirs)}
|}""".asLines
}
/** Default values based on those in Environment as interpreted according
* to the path resolution specification.
*/
object Defaults {
def scalaSourcePath = Environment.sourcePathEnv
def javaBootClassPath = Environment.javaBootClassPath
def javaUserClassPath = Environment.javaUserClassPath
def javaExtDirs = Environment.javaExtDirs
def useJavaClassPath = Environment.useJavaClassPath
def scalaHome = Environment.scalaHome
def scalaHomeDir = Directory(scalaHome)
def scalaLibDir = Directory(scalaHomeDir / "lib")
def scalaClassesDir = Directory(scalaHomeDir / "classes")
def scalaLibAsJar = File(scalaLibDir / "scala-library.jar")
def scalaLibAsDir = Directory(scalaClassesDir / "library")
def scalaLibDirFound: Option[Directory] =
if (scalaLibAsJar.isFile) Some(scalaLibDir)
else if (scalaLibAsDir.isDirectory) Some(scalaClassesDir)
else None
def scalaLibFound =
if (scalaLibAsJar.isFile) scalaLibAsJar.path
else if (scalaLibAsDir.isDirectory) scalaLibAsDir.path
else ""
// TODO It must be time for someone to figure out what all these things
// are intended to do. This is disabled here because it was causing all
// the scala jars to end up on the classpath twice: one on the boot
// classpath as set up by the runner (or regular classpath under -nobootcp)
// and then again here.
def scalaBootClassPath = ""
def scalaExtDirs = Environment.scalaExtDirs
def scalaPluginPath = (scalaHomeDir / "misc" / "scala-devel" / "plugins").path
override def toString = s"""
|object Defaults {
| scalaHome = $scalaHome
| javaBootClassPath = ${ppcp(javaBootClassPath)}
| scalaLibDirFound = $scalaLibDirFound
| scalaLibFound = $scalaLibFound
| scalaBootClassPath = ${ppcp(scalaBootClassPath)}
| scalaPluginPath = ${ppcp(scalaPluginPath)}
|}""".asLines
}
/** Locations discovered by supplemental heuristics.
*/
object SupplementalLocations {
/** The platform-specific support jar.
*
* Usually this is `tools.jar` in the jdk/lib directory of the platform distribution.
*
* The file location is determined by probing the lib directory under JDK_HOME or JAVA_HOME,
* if one of those environment variables is set, then the lib directory under java.home,
* and finally the lib directory under the parent of java.home. Or, as a last resort,
* search deeply under those locations (except for the parent of java.home, on the notion
* that if this is not a canonical installation, then that search would have little
* chance of succeeding).
*/
def platformTools: Option[File] = {
val jarName = "tools.jar"
def jarPath(path: Path) = (path / "lib" / jarName).toFile
def jarAt(path: Path) = {
val f = jarPath(path)
if (f.isFile) Some(f) else None
}
val jdkDir = {
val d = Directory(jdkHome)
if (d.isDirectory) Some(d) else None
}
def deeply(dir: Directory) = dir.deepFiles find (_.name == jarName)
val home = envOrSome("JDK_HOME", envOrNone("JAVA_HOME")) map (p => Path(p))
val install = Some(Path(javaHome))
(home flatMap jarAt) orElse (install flatMap jarAt) orElse (install map (_.parent) flatMap jarAt) orElse
(jdkDir flatMap deeply)
}
override def toString = s"""
|object SupplementalLocations {
| platformTools = $platformTools
|}""".asLines
}
/** With no arguments, show the interesting values in Environment and Defaults.
* If there are arguments, show those in Calculated as if those options had been
* given to a scala runner.
*/
def main(args: Array[String]): Unit =
if (args.isEmpty) {
println(Environment)
println(Defaults)
} else {
val settings = new Settings()
val rest = settings.processArguments(args.toList, processAll = false)._2
val pr = new PathResolver(settings)
println("COMMAND: 'scala %s'".format(args.mkString(" ")))
println("RESIDUAL: 'scala %s'\n".format(rest.mkString(" ")))
pr.result match {
case cp: AggregateClassPath =>
println(s"ClassPath has ${cp.aggregates.size} entries and results in:\n${cp.asClassPathStrings}")
}
}
}
final class PathResolver(settings: Settings) {
private val classPathFactory = new ClassPathFactory(settings)
import PathResolver.{ AsLines, Defaults, ppcp }
private def cmdLineOrElse(name: String, alt: String) = {
(commandLineFor(name) match {
case Some("") => None
case x => x
}) getOrElse alt
}
private def commandLineFor(s: String): Option[String] = condOpt(s) {
case "javabootclasspath" => settings.javabootclasspath.value
case "javaextdirs" => settings.javaextdirs.value
case "bootclasspath" => settings.bootclasspath.value
case "extdirs" => settings.extdirs.value
case "classpath" | "cp" => settings.classpath.value
case "sourcepath" => settings.sourcepath.value
}
/** Calculated values based on any given command line options, falling back on
* those in Defaults.
*/
object Calculated {
def scalaHome = Defaults.scalaHome
def useJavaClassPath = settings.usejavacp.value || Defaults.useJavaClassPath
def useManifestClassPath= settings.usemanifestcp.value
def javaBootClassPath = cmdLineOrElse("javabootclasspath", Defaults.javaBootClassPath)
def javaExtDirs = cmdLineOrElse("javaextdirs", Defaults.javaExtDirs)
def javaUserClassPath = if (useJavaClassPath) Defaults.javaUserClassPath else ""
def scalaBootClassPath = cmdLineOrElse("bootclasspath", Defaults.scalaBootClassPath)
def scalaExtDirs = cmdLineOrElse("extdirs", Defaults.scalaExtDirs)
/** Scaladoc doesn't need any bootstrapping, otherwise will create errors such as:
* [scaladoc] ../scala-trunk/src/reflect/scala/reflect/macros/Reifiers.scala:89: error: object api is not a member of package reflect
* [scaladoc] case class ReificationException(val pos: reflect.api.PositionApi, val msg: String) extends Throwable(msg)
* [scaladoc] ^
* because the bootstrapping will look at the sourcepath and create package "reflect" in "<root>"
* and then when typing relative names, instead of picking <root>.scala.relect, typedIdentifier will pick up the
* <root>.reflect package created by the bootstrapping. Thus, no bootstrapping for scaladoc!
* TODO: we should refactor this as a separate -bootstrap option to have a clean implementation, no? */
def sourcePath = if (!settings.isScaladoc) cmdLineOrElse("sourcepath", Defaults.scalaSourcePath) else ""
def userClassPath = settings.classpath.value // default is specified by settings and can be overridden there
import classPathFactory._
// Assemble the elements!
def basis = List[Traversable[ClassPath]](
JrtClassPath.apply(), // 0. The Java 9 classpath (backed by the jrt:/ virtual system, if available)
classesInPath(javaBootClassPath), // 1. The Java bootstrap class path.
contentsOfDirsInPath(javaExtDirs), // 2. The Java extension class path.
classesInExpandedPath(javaUserClassPath), // 3. The Java application class path.
classesInPath(scalaBootClassPath), // 4. The Scala boot class path.
contentsOfDirsInPath(scalaExtDirs), // 5. The Scala extension class path.
classesInExpandedPath(userClassPath), // 6. The Scala application class path.
classesInManifest(useManifestClassPath), // 8. The Manifest class path.
sourcesInPath(sourcePath) // 7. The Scala source path.
)
lazy val containers = basis.flatten.distinct
override def toString = s"""
|object Calculated {
| scalaHome = $scalaHome
| javaBootClassPath = ${ppcp(javaBootClassPath)}
| javaExtDirs = ${ppcp(javaExtDirs)}
| javaUserClassPath = ${ppcp(javaUserClassPath)}
| useJavaClassPath = $useJavaClassPath
| scalaBootClassPath = ${ppcp(scalaBootClassPath)}
| scalaExtDirs = ${ppcp(scalaExtDirs)}
| userClassPath = ${ppcp(userClassPath)}
| sourcePath = ${ppcp(sourcePath)}
|}""".asLines
}
def containers = Calculated.containers
import PathResolver.MkLines
def result: ClassPath = {
val cp = computeResult()
if (settings.Ylogcp) {
Console print f"Classpath built from ${settings.toConciseString} %n"
Console print s"Defaults: ${PathResolver.Defaults}"
Console print s"Calculated: $Calculated"
val xs = (Calculated.basis drop 2).flatten.distinct
Console print (xs mkLines (s"After java boot/extdirs classpath has ${xs.size} entries:", indented = true))
}
cp
}
def resultAsURLs: Seq[URL] = result.asURLs
@deprecated("Use resultAsURLs instead of this one", "2.11.5")
def asURLs: List[URL] = resultAsURLs.toList
private def computeResult(): ClassPath = AggregateClassPath(containers.toIndexedSeq)
}

@ -0,0 +1,108 @@
/* NSC -- new Scala compiler
* Copyright 2005-2013 LAMP/EPFL
* @author Martin Odersky
*/
package scala.tools.nsc
package ast.parser
import javac._
/** An nsc sub-component.
*/
abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParsers with Scanners with JavaParsers with JavaScanners {
import global._
val phaseName = "parser"
def newPhase(prev: Phase): StdPhase = new ParserPhase(prev)
abstract class MemberDefTraverser extends Traverser {
def onMember(defn: MemberDef): Unit
private var depth: Int = 0
private def lower[T](body: => T): T = {
depth += 1
try body finally depth -= 1
}
def currentDepth = depth
/** Prune this tree and all trees beneath it. Can be overridden. */
def prune(md: MemberDef): Boolean = (
md.mods.isSynthetic
|| md.mods.isParamAccessor
|| nme.isConstructorName(md.name)
|| (md.name containsName nme.ANON_CLASS_NAME)
)
override def traverse(t: Tree): Unit = t match {
case md: MemberDef if prune(md) =>
case md @ PackageDef(_, stats) => traverseTrees(stats)
case md: ImplDef => onMember(md) ; lower(traverseTrees(md.impl.body))
case md: ValOrDefDef => onMember(md) ; lower(traverse(md.rhs))
case _ => super.traverse(t)
}
}
class MemberPosReporter(unit: CompilationUnit) extends MemberDefTraverser {
private var outputFn: MemberDef => String = outputForScreen
val path = unit.source.file.path
// If a single line, outputs the line; if it spans multiple lines
// outputs NN,NN with start and end lines, e.g. 15,25.
def outputPos(md: MemberDef): String = {
val pos = md.pos
val start = pos.focusStart.line
val end = pos.focusEnd.line
if (start == end) "" + start else s"$start,$end"
}
def outputForSed(md: MemberDef): String = {
val pos_s = "%-12s" format outputPos(md) + "p"
s"$pos_s $path # ${md.keyword} ${md.name}"
}
def outputForScreen(md: MemberDef): String = {
val pos_s = "%-20s" format " " * currentDepth + outputPos(md)
s"$pos_s ${md.keyword} ${md.name}"
}
def onMember(md: MemberDef) = println(outputFn(md))
// It recognizes "sed" and "anything else".
def show(style: String) {
if (style == "sed") {
outputFn = outputForSed
traverse(unit.body)
}
else {
outputFn = outputForScreen
println(path)
traverse(unit.body)
}
println("")
}
}
private def initialUnitBody(unit: CompilationUnit): Tree = {
if (unit.isJava) newJavaUnitParser(unit).parse()
else if (currentRun.parsing.incompleteHandled) newUnitParser(unit).parse()
else newUnitParser(unit).smartParse()
}
class ParserPhase(prev: Phase) extends StdPhase(prev) {
override val checkable = false
override val keepsTypeParams = false
def apply(unit: CompilationUnit) {
informProgress("parsing " + unit)
// if the body is already filled in, don't overwrite it
// otherwise compileLate is going to overwrite bodies of synthetic source files
if (unit.body == EmptyTree)
unit.body = initialUnitBody(unit)
if (settings.Yrangepos && !reporter.hasErrors)
validatePositions(unit.body)
if (settings.Ymemberpos.isSetByUser)
new MemberPosReporter(unit) show (style = settings.Ymemberpos.value)
}
}
}

@ -0,0 +1 @@
class Function1[-T1, +R]

@ -0,0 +1,888 @@
const PREC = {
stable_type_id: 1,
binding: 1,
lambda: 1,
stable_id: 2,
assign: 2,
unit: 2,
ascription: 2,
postfix: 3,
infix: 4,
new: 5,
prefix: 5,
compound: 5,
call: 6,
field: 6,
}
module.exports = grammar({
name: 'scala',
extras: $ => [
/\s/,
$.comment
],
supertypes: $ => [
$.expression,
$._definition,
$._pattern,
],
externals: $ => [
$._automatic_semicolon,
$._simple_string,
$._simple_multiline_string,
$._interpolated_string_middle,
$._interpolated_string_end,
$._interpolated_multiline_string_middle,
$._interpolated_multiline_string_end,
'else',
'catch',
'finally',
'extends',
'with',
],
inline: $ => [
$._pattern,
$._semicolon,
$._definition,
$._type_identifier,
$._param_type,
$.literal,
],
conflicts: $ => [
[$.tuple_type, $.parameter_types],
[$.binding, $.expression],
],
word: $ => $.identifier,
rules: {
compilation_unit: $ => repeat($._definition),
_definition: $ => choice(
$.package_clause,
$.package_object,
$.class_definition,
$.import_declaration,
$.object_definition,
$.trait_definition,
$.val_definition,
$.val_declaration,
$.var_definition,
$.var_declaration,
$.type_definition,
$.function_definition,
$.function_declaration
),
package_clause: $ => seq(
'package',
field('name', $.package_identifier),
// This is slightly more permissive than the EBNF in that it allows any
// kind of delcaration inside of the package blocks. As we're more
// concerned with the structure rather than the validity of the program
// we'll allow it.
field('body', optional($.template_body))
),
package_identifier: $ => sep1(
'.', $.identifier
),
package_object: $ => seq(
'package',
'object',
$._object_definition
),
import_declaration: $ => seq(
'import',
sep1(',', $._import_expression)
),
_import_expression: $ => seq(
field('path', choice($.stable_identifier, $.identifier)),
optional(seq(
'.',
choice(
$.wildcard,
$.import_selectors
)
))
),
import_selectors: $ => seq(
'{',
commaSep1(choice(
$.identifier,
$.renamed_identifier
)),
'}'
),
renamed_identifier: $ => seq(
field('name', $.identifier),
'=>',
field('alias', choice($.identifier, $.wildcard))
),
object_definition: $ => seq(
repeat($.annotation),
optional($.modifiers),
optional('case'),
'object',
$._object_definition
),
_object_definition: $ => seq(
field('name', $.identifier),
field('extend', optional($.extends_clause)),
field('body', optional($.template_body)),
),
class_definition: $ => prec.right(seq(
repeat($.annotation),
optional($.modifiers),
optional('case'),
'class',
field('name', $.identifier),
field('type_parameters', optional($.type_parameters)),
optional($.access_modifier),
field('class_parameters', repeat($.class_parameters)),
field('extend', optional($.extends_clause)),
field('body', optional($.template_body))
)),
trait_definition: $ => seq(
repeat($.annotation),
optional($.modifiers),
'trait',
field('name', $.identifier),
field('type_parameters', optional($.type_parameters)),
field('extend', optional($.extends_clause)),
field('body', optional($.template_body))
),
// The EBNF makes a distinction between function type parameters and other
// type parameters as you can't specify variance on function type
// parameters. This isn't important to the structure of the AST so we don't
// make that distinction.
type_parameters: $ => seq(
'[',
commaSep1($._variant_type_parameter),
']'
),
_variant_type_parameter: $ => seq(
repeat($.annotation),
choice(
$.covariant_type_parameter,
$.contravariant_type_parameter,
$._type_parameter // invariant type parameter
)
),
covariant_type_parameter: $ => seq(
'+',
$._type_parameter
),
contravariant_type_parameter: $ => seq(
'-',
$._type_parameter,
),
_type_parameter: $ => seq(
field('name', choice($.wildcard, $.identifier)),
field('type_parameters', optional($.type_parameters)),
field('bound', optional($.upper_bound)),
field('bound', optional($.lower_bound)),
field('bound', optional(repeat($.view_bound))),
field('bound', optional(repeat($.context_bound))),
),
upper_bound: $ => seq('<:', field('type', $._type)),
lower_bound: $ => seq('>:', field('type', $._type)),
view_bound: $ => seq('<%', field('type', $._type)),
context_bound: $ => seq(':', field('type', $._type)),
template_body: $ => seq(
'{',
// TODO: self type
optional($._block),
'}'
),
annotation: $ => prec.right(seq(
'@',
field('name', $._simple_type),
field('arguments', repeat($.arguments)),
)),
val_definition: $ => seq(
repeat($.annotation),
optional($.modifiers),
'val',
field('pattern', $._pattern),
optional(seq(':', field('type', $._type))),
'=',
field('value', $.expression)
),
val_declaration: $ => seq(
repeat($.annotation),
optional($.modifiers),
'val',
commaSep1(field('name', $.identifier)),
':',
field('type', $._type)
),
var_declaration: $ => seq(
repeat($.annotation),
optional($.modifiers),
'var',
commaSep1(field('name', $.identifier)),
':',
field('type', $._type)
),
var_definition: $ => seq(
repeat($.annotation),
optional($.modifiers),
'var',
field('pattern', $._pattern),
optional(seq(':', field('type', $._type))),
'=',
field('value', $.expression)
),
type_definition: $ => seq(
repeat($.annotation),
optional($.modifiers),
'type',
field('name', $._type_identifier),
field('type_parameters', optional($.type_parameters)),
'=',
field('type', $._type)
),
function_definition: $ => seq(
repeat($.annotation),
optional($.modifiers),
'def',
field('name', choice($.identifier, $.operator_identifier)),
field('type_parameters', optional($.type_parameters)),
field('parameters', repeat($.parameters)),
optional(seq(':', field('return_type', $._type))),
choice(
seq('=', field('body', $.expression)),
field('body', $.block)
)
),
function_declaration: $ => seq(
repeat($.annotation),
optional($.modifiers),
'def',
field('name', choice($.identifier, $.operator_identifier)),
field('type_parameters', optional($.type_parameters)),
field('parameters', repeat($.parameters)),
optional(seq(':', field('return_type', $._type)))
),
modifiers: $ => repeat1(choice(
'abstract',
'final',
'sealed',
'implicit',
'lazy',
'override',
$.access_modifier,
)),
access_modifier: $ => seq(
choice('private', 'protected'),
optional($.access_qualifier),
),
access_qualifier: $ => seq(
'[',
$.identifier,
']',
),
extends_clause: $ => seq(
'extends',
field('type', $._type),
optional($.arguments)
),
// TODO: Allow only the last parameter list to be implicit.
class_parameters: $ => prec(1, seq(
'(',
optional('implicit'),
commaSep($.class_parameter),
')'
)),
// TODO: Allow only the last parameter list to be implicit.
parameters: $ => seq(
'(',
optional('implicit'),
commaSep($.parameter),
')'
),
class_parameter: $ => seq(
repeat($.annotation),
optional($.modifiers),
optional(choice('val', 'var')),
field('name', $.identifier),
optional(seq(':', field('type', $._type))),
optional(seq('=', field('default_value', $.expression)))
),
parameter: $ => seq(
repeat($.annotation),
field('name', $.identifier),
optional(seq(':', field('type', $._param_type))),
optional(seq('=', field('default_value', $.expression)))
),
_block: $ => prec.left(seq(
sep1($._semicolon, choice(
$.expression,
$._definition
)),
optional($._semicolon),
)),
block: $ => seq(
'{',
optional($._block),
'}'
),
// ---------------------------------------------------------------
// Types
_type: $ => choice(
$.function_type,
$.compound_type,
$.infix_type,
$._annotated_type,
),
// TODO: Make this a visible type, so that _type can be a supertype.
_annotated_type: $ => prec.right(seq(
$._simple_type,
repeat($.annotation),
)),
_simple_type: $ => choice(
$.generic_type,
$.projected_type,
$.tuple_type,
$.stable_type_identifier,
$._type_identifier,
),
compound_type: $ => prec(PREC.compound, seq(
field('base', $._annotated_type),
repeat1(seq('with', field('extra', $._annotated_type))),
// TODO: Refinement.
)),
infix_type: $ => prec.left(PREC.infix, seq(
field('left', choice($.compound_type, $.infix_type, $._annotated_type)),
field('operator', choice($.identifier, $.operator_identifier)),
field('right', choice($.compound_type, $.infix_type, $._annotated_type))
)),
tuple_type: $ => seq(
'(',
commaSep1($._type),
')',
),
stable_type_identifier: $ => prec.left(PREC.stable_type_id, seq(
choice($.identifier, $.stable_identifier),
'.',
$._type_identifier
)),
stable_identifier: $ => prec.left(PREC.stable_id, seq(
choice($.identifier, $.stable_identifier),
'.',
$.identifier
)),
generic_type: $ => seq(
field('type', $._simple_type),
field('type_arguments', $.type_arguments)
),
projected_type: $ => seq(
field('type', $._simple_type),
'#',
field('selector', $._type_identifier),
),
function_type: $ => prec.right(seq(
field('parameter_types', $.parameter_types),
'=>',
field('return_type', $._type)
)),
// Deprioritize against typed_pattern._type.
parameter_types: $ => prec(-1, choice(
$._annotated_type,
// Prioritize a parenthesized param list over a single tuple_type.
prec.dynamic(1, seq('(', commaSep($._param_type), ')' )),
$.compound_type,
$.infix_type,
)),
_param_type: $ => choice(
$._type,
$.lazy_parameter_type,
$.repeated_parameter_type,
),
lazy_parameter_type: $ => seq(
'=>',
field('type', $._type)
),
repeated_parameter_type: $ => seq(
field('type', $._type),
'*',
),
_type_identifier: $ => alias($.identifier, $.type_identifier),
// ---------------------------------------------------------------
// Patterns
_pattern: $ => choice(
$.identifier,
$.stable_identifier,
$.capture_pattern,
$.tuple_pattern,
$.case_class_pattern,
$.infix_pattern,
$.alternative_pattern,
$.typed_pattern,
$.literal,
$.wildcard
),
case_class_pattern: $ => seq(
field('type', choice($._type_identifier, $.stable_type_identifier)),
'(',
field('pattern', commaSep($._pattern)),
')'
),
infix_pattern: $ => prec.left(PREC.infix, seq(
field('left', $._pattern),
field('operator', choice($.identifier, $.operator_identifier)),
field('right', $._pattern),
)),
capture_pattern: $ => prec(PREC.field, seq(
field('name', $.identifier),
'@',
field('pattern', $._pattern)
)),
typed_pattern: $ => prec.right(seq(
field('pattern', $._pattern),
':',
field('type', $._type)
)),
// TODO: Flatten this.
alternative_pattern: $ => prec.left(-1, seq(
$._pattern,
'|',
$._pattern
)),
tuple_pattern: $ => seq(
'(',
$._pattern,
repeat(seq(',', $._pattern)),
')'
),
// ---------------------------------------------------------------
// Expressions
expression: $ => choice(
$.if_expression,
$.match_expression,
$.try_expression,
$.call_expression,
$.generic_function,
$.assignment_expression,
$.parenthesized_expression,
$.interpolated_string_expression,
$.lambda_expression,
$.field_expression,
$.instance_expression,
$.postfix_expression,
$.ascription_expression,
$.infix_expression,
$.prefix_expression,
$.tuple_expression,
$.case_block,
$.block,
$.identifier,
$.literal,
$.unit,
$.return_expression,
$.throw_expression,
$.while_expression,
$.do_while_expression,
$.for_expression,
),
if_expression: $ => prec.right(seq(
'if',
field('condition', $.parenthesized_expression),
field('consequence', $.expression),
optional(seq(
'else',
field('alternative', $.expression)
))
)),
match_expression: $ => seq(
field('value', $.expression),
'match',
field('body', $.case_block)
),
try_expression: $ => prec.right(seq(
'try',
field('body', $.expression),
optional($.catch_clause),
optional($.finally_clause)
)),
catch_clause: $ => prec.right(seq('catch', $.case_block)),
finally_clause: $ => prec.right(seq('finally', $.expression)),
binding: $ => prec.dynamic(PREC.binding, seq(
field('name', $.identifier),
optional(seq(':', field('type', $._param_type))),
)),
bindings: $ => seq(
'(',
commaSep($.binding),
')',
),
lambda_expression: $ => prec.right(PREC.lambda, seq(
choice(
$.bindings,
$.identifier,
),
'=>',
$.expression,
)),
case_block: $ => choice(
prec(-1, seq('{', '}')),
seq('{', repeat1($.case_clause), '}'),
),
case_clause: $ => prec.left(seq(
'case',
field('pattern', $._pattern),
optional($.guard),
'=>',
field('body', optional($._block)),
)),
guard: $ => seq(
'if',
field('condition', $.expression)
),
assignment_expression: $ => prec.right(PREC.assign, seq(
field('left', $.expression),
'=',
field('right', $.expression)
)),
generic_function: $ => prec(PREC.call, seq(
field('function', $.expression),
field('type_arguments', $.type_arguments)
)),
call_expression: $ => prec(PREC.call, seq(
field('function', $.expression),
field('arguments', choice($.arguments, $.case_block, $.block)),
)),
field_expression: $ => prec(PREC.field, seq(
field('value', $.expression),
'.',
field('field', $.identifier)
)),
instance_expression: $ => prec(PREC.new, seq(
'new',
$.expression
)),
ascription_expression: $ => prec.right(PREC.ascription, seq(
$.expression,
':',
$._param_type,
)),
infix_expression: $ => prec.left(PREC.infix, seq(
field('left', $.expression),
field('operator', choice($.identifier, $.operator_identifier)),
field('right', $.expression)
)),
postfix_expression: $ => prec.left(PREC.postfix, seq(
$.expression,
choice($.identifier, $.operator_identifier),
)),
prefix_expression: $ => prec(PREC.prefix, seq(
choice('+', '-', '!', '~'),
$.expression
)),
tuple_expression: $ => seq(
'(',
$.expression,
repeat1(seq(',', $.expression)),
')'
),
parenthesized_expression: $ => seq(
'(',
$.expression,
')'
),
type_arguments: $ => seq(
'[',
commaSep1($._type),
']'
),
arguments: $ => seq(
'(',
commaSep($.expression),
')'
),
// TODO: Include operators.
identifier: $ => /[a-zA-Z_]\w*/,
wildcard: $ => '_',
operator_identifier: $ => /[^\s\w\(\)\[\]\{\}'"`\.;,]+/,
literal: $ => choice(
$.integer_literal,
$.floating_point_literal,
$.boolean_literal,
$.character_literal,
$.symbol_literal,
$.string,
$.null_literal
),
integer_literal: $ => token(
seq(
optional(/[-]/),
choice(
/[\d]+/,
/0[xX][\da-fA-F]+/
),
optional(/[lL]/)
)
),
floating_point_literal: $ => token(
seq(
optional(/[-]/),
choice(
// digit {digit} . digit {digit} [exponentPart] [floatType]
seq(
/[\d]+\.[\d]+/,
optional(/[eE][+-]?[\d]+/),
optional(/[dfDF]/)
),
// . digit {digit} [exponentPart] [floatType]
seq(
/\.[\d]+/,
optional(/[eE][+-]?[\d]+/),
optional(/[dfDF]/)
),
// digit {digit} exponentPart [floatType]
seq(
/[\d]+/,
/[eE][+-]?[\d]+/,
optional(/[dfDF]/)
),
// digit {digit} [exponentPart] floatType
seq(
/[\d]+/,
optional(/[eE][+-]?[\d]+/),
/[dfDF]/
)
)
)
),
boolean_literal: $ => choice('true', 'false'),
character_literal: $ => token(seq(
'\'',
optional(choice(
seq('\\', choice(
/[^xu]/,
/u[0-9a-fA-F]{4}/,
/u{[0-9a-fA-F]+}/,
/x[0-9a-fA-F]{2}/
)),
/[^\\'\n]/
)),
'\''
)),
symbol_literal: $ => token(seq(
"'",
repeat1(/[^\\'\n]/)
)),
interpolated_string_expression: $ => seq(
$.identifier,
$.interpolated_string
),
_interpolated_string_start: $ => '"',
_interpolated_multiline_string_start: $ => '"""',
interpolation: $ => seq('$', choice($.identifier, $.block)),
interpolated_string: $ => choice(
seq(
$._interpolated_string_start,
repeat(seq(
$._interpolated_string_middle,
$.interpolation
)),
$._interpolated_string_end
),
seq(
$._interpolated_multiline_string_start,
repeat(seq(
$._interpolated_multiline_string_middle,
$.interpolation
)),
$._interpolated_multiline_string_end
)
),
string :$ =>
choice(
$._simple_string,
$._simple_multiline_string
),
_semicolon: $ => choice(
';',
$._automatic_semicolon
),
null_literal: $ => 'null',
unit: $ => prec(PREC.unit, seq('(', ')')),
return_expression: $ => prec.left(seq('return', optional($.expression))),
throw_expression: $ => prec.left(seq('throw', $.expression)),
while_expression: $ => prec.right(seq(
'while',
field('condition', $.parenthesized_expression),
field('body', $.expression)
)),
do_while_expression: $ => prec.right(seq(
'do',
field('body', $.expression),
'while',
field('condition', $.parenthesized_expression)
)),
for_expression: $ => prec.right(seq(
'for',
field('enumerators', choice(
seq("(", $.enumerators, ")"),
seq("{", $.enumerators, "}")
)),
optional('yield'),
field('body', $.expression)
)),
enumerators: $ => seq(
sep1($._semicolon, $.enumerator),
optional($._automatic_semicolon)
),
enumerator: $ => seq(
$._pattern,
choice('<-', '='),
$.expression,
optional($.guard)
),
comment: $ => token(choice(
seq('//', /.*/),
seq(
'/*',
/[^*]*\*+([^/*][^*]*\*+)*/,
'/'
)
))
}
})
function commaSep(rule) {
return optional(commaSep1(rule))
}
function commaSep1(rule) {
return sep1(',', rule)
}
function sep(delimiter, rule) {
return optional(sep1(delimiter, rule))
}
function sep1(delimiter, rule) {
return seq(rule, repeat(seq(delimiter, rule)))
}

@ -0,0 +1,30 @@
{
"name": "tree-sitter-scala",
"version": "0.19.0",
"description": "Scala grammar for tree-sitter",
"main": "bindings/node",
"keywords": [
"parser",
"scala"
],
"author": "Max Brunsfeld",
"license": "MIT",
"dependencies": {
"nan": "^2.14.1"
},
"devDependencies": {
"tree-sitter-cli": "^0.19.5"
},
"scripts": {
"build": "tree-sitter generate && node-gyp build",
"test": "tree-sitter test && tree-sitter parse examples/*.scala --quiet --time"
},
"tree-sitter": [
{
"scope": "source.scala",
"file-types": [
"scala"
]
}
]
}

@ -0,0 +1,4 @@
#!/bin/bash
# scalac -Yshow-trees -Xprint:parser $@
scalac -Yshow-trees -Xprint:typer $@

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,219 @@
#include <tree_sitter/parser.h>
#include <wctype.h>
enum TokenType {
AUTOMATIC_SEMICOLON,
SIMPLE_STRING,
SIMPLE_MULTILINE_STRING,
INTERPOLATED_STRING_MIDDLE,
INTERPOLATED_STRING_END,
INTERPOLATED_MULTILINE_STRING_MIDDLE,
INTERPOLATED_MULTILINE_STRING_END,
ELSE,
CATCH,
FINALLY,
EXTENDS,
WITH,
};
void *tree_sitter_scala_external_scanner_create() { return NULL; }
void tree_sitter_scala_external_scanner_destroy(void *p) {}
void tree_sitter_scala_external_scanner_reset(void *p) {}
unsigned tree_sitter_scala_external_scanner_serialize(void *p, char *buffer) { return 0; }
void tree_sitter_scala_external_scanner_deserialize(void *p, const char *b, unsigned n) {}
static void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
static bool scan_string_content(TSLexer *lexer, bool is_multiline, bool has_interpolation) {
unsigned closing_quote_count = 0;
for (;;) {
if (lexer->lookahead == '"') {
advance(lexer);
closing_quote_count++;
if (!is_multiline) {
lexer->result_symbol = has_interpolation ? INTERPOLATED_STRING_END : SIMPLE_STRING;
return true;
}
if (closing_quote_count == 3) {
lexer->result_symbol = has_interpolation ? INTERPOLATED_MULTILINE_STRING_END : SIMPLE_MULTILINE_STRING;
return true;
}
} else if (lexer->lookahead == '$') {
if (is_multiline && has_interpolation) {
lexer->result_symbol = INTERPOLATED_MULTILINE_STRING_MIDDLE;
return true;
} else if (has_interpolation){
lexer->result_symbol = INTERPOLATED_STRING_MIDDLE;
return true;
} else {
advance(lexer);
}
} else {
closing_quote_count = 0;
if (lexer->lookahead == '\\') {
advance(lexer);
if (lexer->lookahead != 0) advance(lexer);
} else if (lexer->lookahead == '\n') {
if (is_multiline) {
advance(lexer);
} else {
return false;
}
} else if (lexer->lookahead == 0) {
return false;
} else {
advance(lexer);
}
}
}
}
bool tree_sitter_scala_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
unsigned newline_count = 0;
while (iswspace(lexer->lookahead)) {
if (lexer->lookahead == '\n') newline_count++;
lexer->advance(lexer, true);
}
if (valid_symbols[AUTOMATIC_SEMICOLON] && newline_count > 0) {
// NOTE: When there's a dot after a new line it could be a multi-line field
// expression, in which case we don't recognize it as an automatic semicolon.
if (lexer->lookahead == '.') return false;
lexer->mark_end(lexer);
lexer->result_symbol = AUTOMATIC_SEMICOLON;
if (newline_count > 1) return true;
if (valid_symbols[ELSE]) {
if (lexer->lookahead != 'e') return true;
advance(lexer);
if (lexer->lookahead != 'l') return true;
advance(lexer);
if (lexer->lookahead != 's') return true;
advance(lexer);
if (lexer->lookahead != 'e') return true;
advance(lexer);
if (iswalpha(lexer->lookahead)) return true;
return false;
}
if (valid_symbols[CATCH]) {
if (lexer->lookahead != 'c' && lexer->lookahead != 'f') return true;
advance(lexer);
if (lexer->lookahead == 'a') {
advance(lexer);
if (lexer->lookahead != 't') return true;
advance(lexer);
if (lexer->lookahead != 'c') return true;
advance(lexer);
if (lexer->lookahead != 'h') return true;
advance(lexer);
if (iswalpha(lexer->lookahead)) return true;
return false;
} else if (lexer->lookahead == 'i') {
advance(lexer);
if (lexer->lookahead != 'n') return true;
advance(lexer);
if (lexer->lookahead != 'a') return true;
advance(lexer);
if (lexer->lookahead != 'l') return true;
advance(lexer);
if (lexer->lookahead != 'l') return true;
advance(lexer);
if (lexer->lookahead != 'y') return true;
advance(lexer);
if (iswalpha(lexer->lookahead)) return true;
return false;
} else {
return true;
}
}
if (valid_symbols[FINALLY]) {
if (lexer->lookahead != 'f') return true;
advance(lexer);
if (lexer->lookahead != 'i') return true;
advance(lexer);
if (lexer->lookahead != 'n') return true;
advance(lexer);
if (lexer->lookahead != 'a') return true;
advance(lexer);
if (lexer->lookahead != 'l') return true;
advance(lexer);
if (lexer->lookahead != 'l') return true;
advance(lexer);
if (lexer->lookahead != 'y') return true;
advance(lexer);
if (iswalpha(lexer->lookahead)) return true;
return false;
}
if (valid_symbols[EXTENDS]) {
if (lexer->lookahead != 'e') return true;
advance(lexer);
if (lexer->lookahead != 'x') return true;
advance(lexer);
if (lexer->lookahead != 't') return true;
advance(lexer);
if (lexer->lookahead != 'e') return true;
advance(lexer);
if (lexer->lookahead != 'n') return true;
advance(lexer);
if (lexer->lookahead != 'd') return true;
advance(lexer);
if (lexer->lookahead != 's') return true;
advance(lexer);
if (iswalpha(lexer->lookahead)) return true;
return false;
}
if (valid_symbols[WITH]) {
if (lexer->lookahead != 'w') return true;
advance(lexer);
if (lexer->lookahead != 'i') return true;
advance(lexer);
if (lexer->lookahead != 't') return true;
advance(lexer);
if (lexer->lookahead != 'h') return true;
advance(lexer);
if (iswalpha(lexer->lookahead)) return true;
return false;
}
return true;
}
while (iswspace(lexer->lookahead)) {
if (lexer->lookahead == '\n') newline_count++;
lexer->advance(lexer, true);
}
if (valid_symbols[SIMPLE_STRING] && lexer->lookahead == '"') {
advance(lexer);
bool is_multiline = false;
if (lexer->lookahead == '"') {
advance(lexer);
if (lexer->lookahead == '"') {
advance(lexer);
is_multiline = true;
} else {
lexer->result_symbol = SIMPLE_STRING;
return true;
}
}
return scan_string_content(lexer, is_multiline, false);
}
if (valid_symbols[INTERPOLATED_STRING_MIDDLE]) {
return scan_string_content(lexer, false, true);
}
if (valid_symbols[INTERPOLATED_MULTILINE_STRING_MIDDLE]) {
return scan_string_content(lexer, true, true);
}
return false;
}

@ -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_