Skip to content

Commit

Permalink
feature (Language): Type annotations for the Language class
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas committed Mar 7, 2022
1 parent f52566a commit 1c44e9e
Show file tree
Hide file tree
Showing 18 changed files with 170 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"makefile.extensionOutputFolder": "./.vscode"
}
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
run:
python3 ./

test:
python3 -m unittest discover -v src

install:
python3 -m pip install --user canary-env
python3 -m pip install --user canary-env

inspect-js:
nm -D nm -D ./canary-env/lib/python3.9/site-packages/tree_sitter/binding.cpython-39-x86_64-linux-gnu.so
6 changes: 0 additions & 6 deletions __main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@

print(tree.root_node.sexp())

class Node:
_obj

def __init__(self, obj):
self._obj = obj

reached_root = False
while not reached_root:
curr = cursor.node
Expand Down
1 change: 0 additions & 1 deletion src/tree-sitter/__init__.py

This file was deleted.

File renamed without changes.
1 change: 1 addition & 0 deletions src/tree_sitter_py/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .language import *
File renamed without changes.
67 changes: 67 additions & 0 deletions src/tree_sitter_py/language.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from tree_sitter import Language as _Language

from src.tree_sitter_py.query import Query

class Language:
def __init__(self, language: _Language) -> None:
self._language = language

@property
def id(self) -> int:
return self._language.language_id

@property
def name(self):
return self._language.name

def field_id_for_name(self, name: str) -> int:
"""Returns the id of a field found in 'grammer.js' as a 'field' function call
Args:
name (str): The name of the field, also the first parameter in the function call
Returns:
int: The int id of the field
"""
return self._language.field_id_for_name(name)

def query(self, source: str) -> Query:
"""Creates a query from the soruce for a given language
Args:
source (str): The query source
Returns:
Query: A query for the given language
"""
return Query(self._language.query(source))

class LanguageLibrary:
@staticmethod
def vendor_path() -> str:
return './vendor'

@staticmethod
def build_path() -> str:
return './build'

@staticmethod
def build_file() -> str:
return 'my-languages.so'

@staticmethod
def full_build_path() -> str:
return f'{LanguageLibrary.build_path()}/{LanguageLibrary.build_file()}'

@staticmethod
def build() -> str:
_Language.build_library(
LanguageLibrary.full_build_path(),
[ f'{LanguageLibrary.vendor_path()}/tree-sitter-javascript' ]
)

@staticmethod
def js() -> Language:
return Language(
_Language(LanguageLibrary.full_build_path(), 'javascript')
)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 5 additions & 0 deletions src/tree_sitter_py/query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from tree_sitter.binding import Query as _Query

class Query:
def __init__(self, query: _Query) -> None:
self._query = query
70 changes: 70 additions & 0 deletions src/tree_sitter_py/test_language.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import string
from . import *

from importlib.resources import path
from tree_sitter.binding import Query as _Query
from tree_sitter import Language as _Language
import unittest
from os import path

class TestLanguageLibrary(unittest.TestCase):
def test_vendor_path(self):
self.assertEqual(LanguageLibrary.vendor_path(), './vendor')
self.assertIsInstance(LanguageLibrary.vendor_path(), str)

def test_build_path(self):
self.assertEqual(LanguageLibrary.build_path(), './build')
self.assertIsInstance(LanguageLibrary.build_path(), str)

def test_build_file(self):
self.assertEqual(LanguageLibrary.build_file(), 'my-languages.so')
self.assertIsInstance(LanguageLibrary.build_file(), str)

def test_full_build_path(self):
self.assertEqual(LanguageLibrary.full_build_path(), './build/my-languages.so')
self.assertIsInstance(LanguageLibrary.full_build_path(), str)

def test_build(self):
LanguageLibrary.build()
self.assertTrue(path.exists(LanguageLibrary.full_build_path()))
js = LanguageLibrary.js()
self.assertIsNotNone(js)
self.assertIsInstance(js, Language)
self.assertIsInstance(js._language, _Language)

class TestLanguage(unittest.TestCase):
_js_language: Language = None

def setUp(self) -> None:
LanguageLibrary.build()
self._js_language = LanguageLibrary.js()
return super().setUp()

def test_id(self):
self.assertIsNotNone(self._js_language.id)
self.assertIsInstance(self._js_language.id, int)

def test_name(self):
self.assertIsNotNone(self._js_language.name)
self.assertEqual(self._js_language.name, 'javascript')
self.assertIsInstance(self._js_language.name, str)

def test_field_id_for_name(self):
self.assertIsInstance(self._js_language.field_id_for_name('kind'), int)
self.assertEqual(self._js_language.field_id_for_name('kind'), 21)
self.assertIsInstance(self._js_language.field_id_for_name('name'), int)
self.assertEqual(self._js_language.field_id_for_name('name'), 25)
self.assertIsInstance(self._js_language.field_id_for_name('source'), int)
self.assertEqual(self._js_language.field_id_for_name('source'), 34)
self.assertIsInstance(self._js_language.field_id_for_name('condition'), int)
self.assertEqual(self._js_language.field_id_for_name('condition'), 8)
self.assertIsInstance(self._js_language.field_id_for_name('consequence'), int)
self.assertEqual(self._js_language.field_id_for_name('consequence'), 9)
self.assertIsInstance(self._js_language.field_id_for_name('alternative'), int)
self.assertEqual(self._js_language.field_id_for_name('alternative'), 2)

def test_query(self):
query = self._js_language.query('(binary_expression (number) (number))')
self.assertIsInstance(query, Query)
self.assertIsInstance(query._query, _Query)
pass
File renamed without changes.
17 changes: 17 additions & 0 deletions tests/test_string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import unittest

class TestStringMethods(unittest.TestCase):

def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')

def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())

def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
Empty file.

0 comments on commit 1c44e9e

Please sign in to comment.