Skip to content

Commit

Permalink
Merge pull request #124 from seart-group/language/state
Browse files Browse the repository at this point in the history
  • Loading branch information
dabico authored Feb 6, 2024
2 parents e64a463 + 2794af1 commit 50cd00f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 0 deletions.
10 changes: 10 additions & 0 deletions lib/ch_usi_si_seart_treesitter_Language.cc
Original file line number Diff line number Diff line change
Expand Up @@ -565,3 +565,13 @@ JNIEXPORT jobject JNICALL Java_ch_usi_si_seart_treesitter_Language_iterator(
thisObject
);
}

JNIEXPORT jint JNICALL Java_ch_usi_si_seart_treesitter_Language_nextState(
JNIEnv* env, jclass self, jlong id, jint state, jint symbol) {
if (id == (jlong)ch_usi_si_seart_treesitter_Language_INVALID) return (jint)(-1);
return (jint)ts_language_next_state(
(const TSLanguage*)id,
(TSStateId)state,
(TSSymbol)symbol
);
}
8 changes: 8 additions & 0 deletions lib/ch_usi_si_seart_treesitter_Language.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions src/main/java/ch/usi/si/seart/treesitter/Language.java
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,32 @@ public static void validate(@NotNull Language language) {
*/
public native LookaheadIterator iterator(int state);

/**
* Obtain the next language parse state for a given {@link Node}.
* <p>
* Combine this with lookahead iterators to generate completion
* suggestions or valid symbols in {@code ERROR} nodes.
*
* @param node the node
* @return the next parse state
* @throws NullPointerException if {@code node} is null
* @throws IllegalArgumentException if this language
* was not used to parse the node and its syntax tree
* @since 1.12.0
*/
public int nextState(@NotNull Node node) {
Objects.requireNonNull(node, "Node must not be null!");
Language language = node.getLanguage();
if (!this.equals(language)) throw new IllegalArgumentException(
"Node language does not match the language of this instance!"
);
int state = node.getParseState();
Symbol symbol = node.getGrammarSymbol();
return nextState(id, state, symbol.getId());
}

private static native int nextState(long id, int state, int symbol);

@Generated
@SuppressWarnings("unused")
public int getTotalSymbols() {
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/ch/usi/si/seart/treesitter/LanguageTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ch.usi.si.seart.treesitter;

import lombok.Cleanup;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -100,4 +102,21 @@ public Stream<? extends Arguments> provideArguments(ExtensionContext extensionCo
void testAssociatedWithThrows(Class<Throwable> throwableType, Path path) {
Assertions.assertThrows(throwableType, () -> Language.associatedWith(path));
}

@Test
void testNextState() {
Language language = Language.PYTHON;
@Cleanup Parser parser = Parser.getFor(language);
@Cleanup Tree tree = parser.parse("pass");
Node root = tree.getRootNode();
Assertions.assertEquals(0, language.nextState(root));
}

@Test
void testNextStateThrows() {
Assertions.assertThrows(NullPointerException.class, () -> Language.JAVA.nextState(null));
Assertions.assertThrows(NullPointerException.class, () -> Language._INVALID_.nextState(null));
Assertions.assertThrows(IllegalArgumentException.class, () -> Language.JAVA.nextState(empty));
Assertions.assertThrows(IllegalArgumentException.class, () -> Language._INVALID_.nextState(empty));
}
}

0 comments on commit 50cd00f

Please # to comment.