Skip to content

Latest commit

 

History

History
71 lines (45 loc) · 5.45 KB

CONTRIBUTING.md

File metadata and controls

71 lines (45 loc) · 5.45 KB

Contributing to GritQL

Welcome! We'd love to help you contribute to GritQL.

Welcome

We welcome contributions in the form of pull requests and issues.

Note that this codebase isn't yet extensively documented. If you get stuck, please ask for help on Discord.

Feature Flags

We use feature flags to control which parts of the codebase are compiled.

Note that some proprietary server-only integrations are hidden behind the "server" feature flag. This flag is disabled by default, and code should compile without any additions.

For major changes, we put new features should be put into the grit_alpha feature flag. Features that are ready for broad release should be put into the grit_beta feature flag. This is used for all public releases.

Features that should be tested in CI should be put into the grit_ci feature flag. This is used for all CI tests.

Language Grammars

If GritQL is failing to match a code snippet, this can typically be fixed simply by adjusting the metavariable grammar for the target language.

Metavariable grammars are found under ./resources/metavariable-grammars. Typical fixes include:

  • Adding a new named field for a relevant node you want to manipulate.
  • Adding a grit_metavariable node as a choice in the corresponding spot where you want to substitute the metavariable.
  • Check this guide to debug grammars generally.

After making your changes, run the ./resources/edit_grammars.mjs script to regenerate the matching grammar.

Snippet contexts

Snippet contexts help when a snippet is a valid AST subtree, but needs to be in a larger tree to parse. For example, matching on a table name like $schema.$table in SQL is not valid SQL by itself, only when surrounded by something like SELECT x from $schema.$table is the snippet valid.

Snippet contexts are defined by implementing the snippet_context_strings method in the Language trait. This method returns a list of strings that are used to match the snippet in the larger tree. For example, the SQL implementation returns ["SELECT 1 from ", ";"] to match a table name in a SQL query.

Adding a New Target Language

Note: Grit involves two languages:

  • GritQL is our query language for searching and transforming codebases.
  • The “target language” is the language we are transforming (ex. Python). This document describes the process of adding new target languages to Grit.

Most of these steps involve iteration over a set of sample programs to get closer to correctness. The initial work for a language can typically be done in a day or two.

Here are the steps for adding a new target language:

  1. Add the language as a supported language in the GritQL grammar, like this.
  2. Find a tree sitter grammar for the language and add it as a submodule under resources/language-submodules.
  3. Add a simple parse test in crates/core/src/test.rs to ensure that the grammar is working.
  4. Copy the grammar file into resources/metavariable-grammars. This alternative grammar is used for parsing snippets in GritQL.
  5. Patch the metavariable grammar to include $.grit_metavariable anywhere we want to substitute a metavariable. This is usually at least $identifier and $literal.
    • For a snippet to match, it also needs to be a field. Often you’ll want to wrap $thing like: field('thing', choice($.grit_metavariable, $thing))
  6. Add a new language implementation in crates/core/src/languages. This involves implementing the Language trait and adding a new Language enum variant.
  7. Add snippet_context_strings like this to provide context for snippets to match in.
  8. Add test cases for the language in crates/core/src/test.rs. This is a good time to add a few dozen test cases to ensure that the language is parsed correctly, and that the metavariable grammar is working.

Internal steps

These steps are done in our cloud environment and are not necessary for contributors to do.