diff --git a/.gitattributes b/.gitattributes index 7e2cae0c..79475a5e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,7 +6,7 @@ src/parser.c linguist-generated src/tree_sitter/* linguist-generated # C bindings -bindings/c/* linguist-generated +bindings/c/** linguist-generated CMakeLists.txt linguist-generated Makefile linguist-generated @@ -35,3 +35,7 @@ go.sum linguist-generated bindings/swift/** linguist-generated Package.swift linguist-generated Package.resolved linguist-generated + +# Zig bindings +build.zig linguist-generated +build.zig.zon linguist-generated diff --git a/.gitignore b/.gitignore index 9e684869..87a0c80c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,16 @@ # Rust artifacts target/ +Cargo.lock # Node artifacts build/ prebuilds/ node_modules/ +package-lock.json # Swift artifacts .build/ +Package.resolved # Go artifacts _obj/ @@ -25,6 +28,13 @@ dist/ *.dylib *.dll *.pc +*.exp +*.lib + +# Zig artifacts +.zig-cache/ +zig-cache/ +zig-out/ # Example dirs /examples/*/ @@ -38,4 +48,3 @@ dist/ *.tar.gz *.tgz *.zip - diff --git a/CMakeLists.txt b/CMakeLists.txt index 96efe9e4..d0c0c97c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,11 @@ add_library(tree-sitter-c-sharp src/parser.c) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) target_sources(tree-sitter-c-sharp PRIVATE src/scanner.c) endif() -target_include_directories(tree-sitter-c-sharp PRIVATE src) +target_include_directories(tree-sitter-c-sharp + PRIVATE src + INTERFACE $ + $) + target_compile_definitions(tree-sitter-c-sharp PRIVATE $<$:TREE_SITTER_REUSE_ALLOCATOR> @@ -46,8 +50,9 @@ configure_file(bindings/c/tree-sitter-c-sharp.pc.in include(GNUInstallDirs) -install(FILES bindings/c/tree-sitter-c-sharp.h - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tree_sitter") +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bindings/c/tree_sitter" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + FILES_MATCHING PATTERN "*.h") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-c-sharp.pc" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") install(TARGETS tree-sitter-c-sharp diff --git a/Makefile b/Makefile index 30604373..221e326d 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ $(PARSER): $(SRC_DIR)/grammar.json install: all install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' - install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h + install -m644 bindings/c/tree_sitter/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) diff --git a/Package.swift b/Package.swift index d4eac04b..af2f8ac6 100644 --- a/Package.swift +++ b/Package.swift @@ -7,7 +7,7 @@ let package = Package( .library(name: "TreeSitterCSharp", targets: ["TreeSitterCSharp"]), ], dependencies: [ - .package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"), + .package(name: "SwiftTreeSitter", url: "https://github.com/tree-sitter/swift-tree-sitter", from: "0.8.0"), ], targets: [ .target( diff --git a/bindings/c/tree-sitter-c-sharp.h b/bindings/c/tree_sitter/tree-sitter-c-sharp.h similarity index 82% rename from bindings/c/tree-sitter-c-sharp.h rename to bindings/c/tree_sitter/tree-sitter-c-sharp.h index 32644f89..03156424 100644 --- a/bindings/c/tree-sitter-c-sharp.h +++ b/bindings/c/tree_sitter/tree-sitter-c-sharp.h @@ -7,7 +7,7 @@ typedef struct TSLanguage TSLanguage; extern "C" { #endif -const TSLanguage *tree_sitter_c_sharp(void); +const TSLanguage *tree_sitter_c-sharp(void); #ifdef __cplusplus } diff --git a/bindings/go/binding.go b/bindings/go/binding.go index f8b38729..8f287fd7 100644 --- a/bindings/go/binding.go +++ b/bindings/go/binding.go @@ -2,7 +2,9 @@ package tree_sitter_c_sharp // #cgo CFLAGS: -std=c11 -fPIC // #include "../../src/parser.c" +// #if __has_include("../../src/scanner.c") // #include "../../src/scanner.c" +// #endif import "C" import "unsafe" diff --git a/bindings/go/binding_test.go b/bindings/go/binding_test.go index ccc190f8..153b2dcc 100644 --- a/bindings/go/binding_test.go +++ b/bindings/go/binding_test.go @@ -10,6 +10,6 @@ import ( func TestCanLoadGrammar(t *testing.T) { language := tree_sitter.NewLanguage(tree_sitter_c_sharp.Language()) if language == nil { - t.Errorf("Error loading C# grammar") + t.Errorf("Error loading CSharp grammar") } } diff --git a/bindings/node/binding.cc b/bindings/node/binding.cc index 442d0ba5..ec32d4d5 100644 --- a/bindings/node/binding.cc +++ b/bindings/node/binding.cc @@ -2,7 +2,7 @@ typedef struct TSLanguage TSLanguage; -extern "C" TSLanguage *tree_sitter_c_sharp(); +extern "C" TSLanguage *tree_sitter_c-sharp(); // "tree-sitter", "language" hashed with BLAKE2 const napi_type_tag LANGUAGE_TYPE_TAG = { @@ -10,11 +10,10 @@ const napi_type_tag LANGUAGE_TYPE_TAG = { }; Napi::Object Init(Napi::Env env, Napi::Object exports) { - exports["name"] = Napi::String::New(env, "c-sharp"); - auto language = Napi::External::New(env, tree_sitter_c_sharp()); + auto language = Napi::External::New(env, tree_sitter_c-sharp()); language.TypeTag(&LANGUAGE_TYPE_TAG); exports["language"] = language; return exports; } -NODE_API_MODULE(tree_sitter_c_sharp_binding, Init) +NODE_API_MODULE(tree_sitter_c-sharp_binding, Init) diff --git a/bindings/node/index.d.ts b/bindings/node/index.d.ts index efe259ee..528e060f 100644 --- a/bindings/node/index.d.ts +++ b/bindings/node/index.d.ts @@ -19,7 +19,6 @@ type NodeInfo = }); type Language = { - name: string; language: unknown; nodeTypeInfo: NodeInfo[]; }; diff --git a/bindings/python/tests/test_binding.py b/bindings/python/tests/test_binding.py index 790e4252..e9d52afc 100644 --- a/bindings/python/tests/test_binding.py +++ b/bindings/python/tests/test_binding.py @@ -1,6 +1,7 @@ from unittest import TestCase -import tree_sitter, tree_sitter_c_sharp +import tree_sitter +import tree_sitter_c_sharp class TestLanguage(TestCase): @@ -8,4 +9,4 @@ def test_can_load_grammar(self): try: tree_sitter.Language(tree_sitter_c_sharp.language()) except Exception: - self.fail("Error loading C# grammar") + self.fail("Error loading CSharp grammar") diff --git a/bindings/python/tree_sitter_c_sharp/binding.c b/bindings/python/tree_sitter_c_sharp/binding.c index 6c00cb2f..47703b6f 100644 --- a/bindings/python/tree_sitter_c_sharp/binding.c +++ b/bindings/python/tree_sitter_c_sharp/binding.c @@ -8,6 +8,13 @@ static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSE return PyCapsule_New(tree_sitter_c_sharp(), "tree_sitter.Language", NULL); } +static struct PyModuleDef_Slot slots[] = { +#ifdef Py_GIL_DISABLED + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, +#endif + {0, NULL} +}; + static PyMethodDef methods[] = { {"language", _binding_language, METH_NOARGS, "Get the tree-sitter language for this grammar."}, @@ -18,10 +25,11 @@ static struct PyModuleDef module = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "_binding", .m_doc = NULL, - .m_size = -1, - .m_methods = methods + .m_size = 0, + .m_methods = methods, + .m_slots = slots, }; PyMODINIT_FUNC PyInit__binding(void) { - return PyModule_Create(&module); + return PyModuleDef_Init(&module); } diff --git a/bindings/rust/build.rs b/bindings/rust/build.rs index 8a82bffe..1a4eb007 100644 --- a/bindings/rust/build.rs +++ b/bindings/rust/build.rs @@ -2,10 +2,7 @@ fn main() { let src_dir = std::path::Path::new("src"); let mut c_config = cc::Build::new(); - c_config - .std("c11") - .include(src_dir) - .flag_if_supported("-Wno-unused-value"); + c_config.std("c11").include(src_dir); #[cfg(target_env = "msvc")] c_config.flag("-utf-8"); @@ -15,8 +12,10 @@ fn main() { println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); let scanner_path = src_dir.join("scanner.c"); - c_config.file(&scanner_path); - println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); + if scanner_path.exists() { + c_config.file(&scanner_path); + println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); + } c_config.compile("tree-sitter-c-sharp"); } diff --git a/bindings/rust/lib.rs b/bindings/rust/lib.rs index e5c39219..66face54 100644 --- a/bindings/rust/lib.rs +++ b/bindings/rust/lib.rs @@ -1,42 +1,40 @@ -//! This crate provides CSharp language support for the [tree-sitter][] parsing library. +//! This crate provides CSharp language support for the [tree-sitter] parsing library. //! -//! Typically, you will use the [LANGUAGE][] constant to add this language to a -//! tree-sitter [Parser][], and then use the parser to parse some code: +//! Typically, you will use the [`LANGUAGE`] constant to add this language to a +//! tree-sitter [`Parser`], and then use the parser to parse some code: //! //! ``` //! let code = r#" //! "#; //! let mut parser = tree_sitter::Parser::new(); -//! let language = tree_sitter_c_sharp::LANGUAGE; +//! let language = tree_sitter_c-sharp::LANGUAGE; //! parser //! .set_language(&language.into()) -//! .expect("Error loading C# parser"); +//! .expect("Error loading CSharp parser"); //! let tree = parser.parse(code, None).unwrap(); //! assert!(!tree.root_node().has_error()); //! ``` //! -//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html +//! [`Parser`]: https://docs.rs/tree-sitter/0.25.7/tree_sitter/struct.Parser.html //! [tree-sitter]: https://tree-sitter.github.io/ use tree_sitter_language::LanguageFn; extern "C" { - fn tree_sitter_c_sharp() -> *const (); + fn tree_sitter_c-sharp() -> *const (); } -/// The tree-sitter [`LanguageFn`][LanguageFn] for this grammar. -/// -/// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html -pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_c_sharp) }; +/// The tree-sitter [`LanguageFn`] for this grammar. +pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_c-sharp) }; -/// The content of the [`node-types.json`][] file for this grammar. +/// 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 +/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); // NOTE: uncomment these to include any queries that this grammar contains: -pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); +// pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); @@ -48,6 +46,6 @@ mod tests { let mut parser = tree_sitter::Parser::new(); parser .set_language(&super::LANGUAGE.into()) - .expect("Error loading C# parser"); + .expect("Error loading CSharp parser"); } } diff --git a/bindings/swift/TreeSitterCSharp/c-sharp.h b/bindings/swift/TreeSitterCSharp/c-sharp.h index 32644f89..03156424 100644 --- a/bindings/swift/TreeSitterCSharp/c-sharp.h +++ b/bindings/swift/TreeSitterCSharp/c-sharp.h @@ -7,7 +7,7 @@ typedef struct TSLanguage TSLanguage; extern "C" { #endif -const TSLanguage *tree_sitter_c_sharp(void); +const TSLanguage *tree_sitter_c-sharp(void); #ifdef __cplusplus } diff --git a/bindings/swift/TreeSitterCSharpTests/TreeSitterCSharpTests.swift b/bindings/swift/TreeSitterCSharpTests/TreeSitterCSharpTests.swift index c66fe48a..c89cbeae 100644 --- a/bindings/swift/TreeSitterCSharpTests/TreeSitterCSharpTests.swift +++ b/bindings/swift/TreeSitterCSharpTests/TreeSitterCSharpTests.swift @@ -7,6 +7,6 @@ final class TreeSitterCSharpTests: XCTestCase { let parser = Parser() let language = Language(language: tree_sitter_c_sharp()) XCTAssertNoThrow(try parser.setLanguage(language), - "Error loading C# grammar") + "Error loading CSharp grammar") } } diff --git a/pyproject.toml b/pyproject.toml index f89c6080..e65d7a55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ authors = [ { name = "Max Brunsfeld", email = "maxbrunsfeld@gmail.com" }, { name = "Amaan Qureshi", email = "amaanq12@gmail.com" }, ] -requires-python = ">=3.9" +requires-python = ">=3.10" license.text = "MIT" readme = "README.md" @@ -26,8 +26,8 @@ readme = "README.md" Homepage = "https://github.com/tree-sitter/tree-sitter-c-sharp" [project.optional-dependencies] -core = ["tree-sitter~=0.22"] +core = ["tree-sitter~=0.24"] [tool.cibuildwheel] -build = "cp39-*" +build = "cp310-*" build-frontend = "build" diff --git a/setup.py b/setup.py index 93a23a1d..ee6923d5 100644 --- a/setup.py +++ b/setup.py @@ -1,15 +1,36 @@ -from os.path import isdir, join +from os import path from platform import system +from sysconfig import get_config_var from setuptools import Extension, find_packages, setup from setuptools.command.build import build +from setuptools.command.egg_info import egg_info from wheel.bdist_wheel import bdist_wheel +sources = [ + "bindings/python/tree_sitter_c_sharp/binding.c", + "src/parser.c", +] +if path.exists("src/scanner.c"): + sources.append("src/scanner.c") + +macros: list[tuple[str, str | None]] = [ + ("PY_SSIZE_T_CLEAN", None), + ("TREE_SITTER_HIDE_SYMBOLS", None), +] +if limited_api := not get_config_var("Py_GIL_DISABLED"): + macros.append(("Py_LIMITED_API", "0x030A0000")) + +if system() != "Windows": + cflags = ["-std=c11", "-fvisibility=hidden"] +else: + cflags = ["/std:c11", "/utf-8"] + class Build(build): def run(self): - if isdir("queries"): - dest = join(self.build_lib, "tree_sitter_c-sharp", "queries") + if path.isdir("queries"): + dest = path.join(self.build_lib, "tree_sitter_c-sharp", "queries") self.copy_tree("queries", dest) super().run() @@ -18,10 +39,17 @@ class BdistWheel(bdist_wheel): def get_tag(self): python, abi, platform = super().get_tag() if python.startswith("cp"): - python, abi = "cp39", "abi3" + python, abi = "cp310", "abi3" return python, abi, platform +class EggInfo(egg_info): + def find_sources(self): + super().find_sources() + self.filelist.recursive_include("queries", "*.scm") + self.filelist.include("src/tree_sitter/*.h") + + setup( packages=find_packages("bindings/python"), package_dir={"": "bindings/python"}, @@ -33,30 +61,17 @@ def get_tag(self): ext_modules=[ Extension( name="_binding", - sources=[ - "bindings/python/tree_sitter_c_sharp/binding.c", - "src/parser.c", - "src/scanner.c", - ], - extra_compile_args=[ - "-std=c11", - "-fvisibility=hidden", - ] if system() != "Windows" else [ - "/std:c11", - "/utf-8", - ], - define_macros=[ - ("Py_LIMITED_API", "0x03090000"), - ("PY_SSIZE_T_CLEAN", None), - ("TREE_SITTER_HIDE_SYMBOLS", None), - ], + sources=sources, + extra_compile_args=cflags, + define_macros=macros, include_dirs=["src"], - py_limited_api=True, + py_limited_api=limited_api, ) ], cmdclass={ "build": Build, - "bdist_wheel": BdistWheel + "bdist_wheel": BdistWheel, + "egg_info": EggInfo, }, zip_safe=False )