feat: updated TreeSitterLanguage implementation

This commit is contained in:
Akash Yadav
2022-12-24 22:30:08 +05:30
parent d97ba5e415
commit d4c787ec28
7 changed files with 142 additions and 139 deletions
@@ -152,8 +152,6 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
}
}
viewModel.openedFilesCache = null
executeAsync { IDEColorSchemeProvider.init() }
} catch (err: Throwable) {
log.error("Failed to reopen recently opened files", err)
}
@@ -57,6 +57,8 @@ class IDEApplication : BaseApplication() {
.addIndex(LspApiEventsIndex())
.addIndex(LspJavaEventsIndex())
.installDefaultEventBus()
executeAsync { IDEColorSchemeProvider.init() }
}
private fun handleCrash(thread: Thread, th: Throwable) {
@@ -16,8 +16,6 @@
*/
package com.itsaky.androidide.ui.editor;
import static com.itsaky.androidide.editor.schemes.LanguageSpecProvider.getLanguageSpec;
import static com.itsaky.androidide.editor.schemes.LocalCaptureSpecProvider.newLocalCaptureSpec;
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.FLAG_LINE_BREAK;
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.FLAG_PASSWORD;
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.FLAG_WS_EMPTY_LINE;
@@ -59,7 +57,6 @@ import com.itsaky.androidide.editor.language.cpp.CppLanguage;
import com.itsaky.androidide.editor.language.groovy.GroovyLanguage;
import com.itsaky.androidide.editor.language.java.JavaLanguage;
import com.itsaky.androidide.editor.language.kotlin.KotlinLanguage;
import com.itsaky.androidide.editor.language.treesitter.TreeSitterLanguage;
import com.itsaky.androidide.editor.language.xml.XMLLanguage;
import com.itsaky.androidide.editor.schemes.IDEColorSchemeProvider;
import com.itsaky.androidide.editor.ui.EditorSearchLayout;
@@ -73,7 +70,6 @@ import com.itsaky.androidide.lsp.xml.XMLLanguageServer;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.preferences.internal.EditorPreferencesKt;
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE;
import com.itsaky.androidide.treesitter.java.TSLanguageJava;
import com.itsaky.androidide.utils.FileUtil;
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.LSPUtils;
@@ -212,10 +208,7 @@ public class CodeEditorView extends LinearLayout {
switch (ext) {
case "java":
IDEColorSchemeProvider.INSTANCE.readScheme(binding.editor::setColorScheme);
final var tsLangJava = TSLanguageJava.newInstance();
final var localsSpec = newLocalCaptureSpec(ext);
final var languageSpec = getLanguageSpec(getContext(), ext, tsLangJava, localsSpec);
return new TreeSitterLanguage(new JavaLanguage(), languageSpec, ext);
return new JavaLanguage(getContext());
case "xml":
return new XMLLanguage();
case "gradle":
@@ -0,0 +1,64 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.editor.language
import android.content.Context
import com.itsaky.androidide.editor.schemes.IDEColorSchemeProvider
import com.itsaky.androidide.editor.schemes.LanguageSpecProvider
import com.itsaky.androidide.editor.schemes.LanguageSpecProvider.getLanguageSpec
import com.itsaky.androidide.editor.schemes.LocalCaptureSpecProvider
import com.itsaky.androidide.editor.schemes.LocalCaptureSpecProvider.newLocalCaptureSpec
import com.itsaky.androidide.treesitter.TSLanguage
import io.github.rosemoe.sora.editor.ts.TsAnalyzeManager
import io.github.rosemoe.sora.editor.ts.TsLanguageSpec
import io.github.rosemoe.sora.editor.ts.TsTheme
import io.github.rosemoe.sora.lang.analysis.AnalyzeManager
/**
* Tree Sitter language implementation.
*
* @author Akash Yadav
*/
abstract class TreeSitterLanguage(
context: Context,
lang: TSLanguage,
type: String
) : IDELanguage() {
private lateinit var tsTheme: TsTheme
private lateinit var languageSpec: TsLanguageSpec
private val analyzer by lazy { TsAnalyzeManager(languageSpec, tsTheme) }
init {
this.languageSpec = getLanguageSpec(context, type, lang, newLocalCaptureSpec(type))
this.tsTheme = TsTheme(languageSpec.tsQuery)
IDEColorSchemeProvider.readScheme { scheme ->
val langScheme =
checkNotNull(scheme.languages[type]) { "No color scheme found for file type '$type'" }
langScheme.styles.forEach { tsTheme.putStyleRule(it.key, it.value.makeStyle()) }
}
}
override fun getAnalyzeManager(): AnalyzeManager {
return this.analyzer
}
override fun destroy() {
languageSpec.close()
}
}
@@ -1,129 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.editor.language.java;
import androidx.annotation.NonNull;
import com.itsaky.androidide.editor.language.CommonSymbolPairs;
import com.itsaky.androidide.editor.language.IDELanguage;
import com.itsaky.androidide.editor.language.BraceHandler;
import com.itsaky.androidide.editor.language.CommonCompletionProvider;
import com.itsaky.androidide.lexers.java.JavaLexer;
import com.itsaky.androidide.lexers.java.JavaParser;
import com.itsaky.androidide.lsp.api.ILanguageServer;
import com.itsaky.androidide.lsp.api.ILanguageServerRegistry;
import com.itsaky.androidide.lsp.java.JavaLanguageServer;
import com.itsaky.androidide.utils.ILogger;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Token;
import java.io.StringReader;
import io.github.rosemoe.sora.lang.analysis.AnalyzeManager;
import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler;
import io.github.rosemoe.sora.text.ContentReference;
import io.github.rosemoe.sora.util.MyCharacter;
import io.github.rosemoe.sora.widget.SymbolPairMatch;
public class JavaLanguage extends IDELanguage {
private static final ILogger LOG = ILogger.newInstance("JavaLanguage");
private final NewlineHandler[] newlineHandlers;
private JavaAnalyzer analyzer;
public JavaLanguage() {
final var server = getLanguageServer();
this.analyzer = new JavaAnalyzer();
this.newlineHandlers = new NewlineHandler[1];
this.newlineHandlers[0] = new BraceHandler(this::getIndentAdvance, this::useTab);
}
@Override
protected ILanguageServer getLanguageServer() {
return ILanguageServerRegistry.getDefault().getServer(JavaLanguageServer.SERVER_ID);
}
@Override
protected boolean checkIsCompletionChar(final char c) {
return MyCharacter.isJavaIdentifierPart(c) || c == '.';
}
@Override
public int getIndentAdvance(@NonNull String line) {
try {
JavaLexer lexer = new JavaLexer(CharStreams.fromReader(new StringReader(line)));
Token token;
int advance = 0;
while (((token = lexer.nextToken()) != null && token.getType() != token.EOF)) {
switch (token.getType()) {
case JavaLexer.LBRACE:
advance++;
break;
case JavaParser.RBRACE:
advance--;
break;
}
}
advance = Math.max(0, advance);
return advance * getTabSize();
} catch (Throwable e) {
LOG.error("Error calculating indent advance", e);
}
return 0;
}
@NonNull
@Override
public AnalyzeManager getAnalyzeManager() {
return analyzer;
}
@Override
public int getInterruptionLevel() {
return INTERRUPTION_LEVEL_SLIGHT;
}
@Override
public int getIndentAdvance(@NonNull ContentReference content, int line, int column) {
return getIndentAdvance(content.getLine(line).substring(0, column));
}
@Override
public SymbolPairMatch getSymbolPairs() {
return new JavaSymbolPairs();
}
@Override
public NewlineHandler[] getNewlineHandlers() {
return newlineHandlers;
}
@Override
public void destroy() {
analyzer = null;
}
public static class JavaSymbolPairs extends CommonSymbolPairs {
public JavaSymbolPairs() {
super();
super.putPair('<', new SymbolPairMatch.SymbolPair("<", ">"));
}
}
}
@@ -0,0 +1,75 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.editor.language.java
import android.content.Context
import com.itsaky.androidide.editor.language.BraceHandler
import com.itsaky.androidide.editor.language.CommonSymbolPairs
import com.itsaky.androidide.editor.language.TreeSitterLanguage
import com.itsaky.androidide.lsp.api.ILanguageServer
import com.itsaky.androidide.lsp.api.ILanguageServerRegistry
import com.itsaky.androidide.lsp.java.JavaLanguageServer
import com.itsaky.androidide.treesitter.java.TSLanguageJava
import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler
import io.github.rosemoe.sora.text.ContentReference
import io.github.rosemoe.sora.util.MyCharacter
import io.github.rosemoe.sora.widget.SymbolPairMatch
/**
* Tree Sitter language specification for Java.
*
* @author Akash Yadav
*/
class JavaLanguage(context: Context) :
TreeSitterLanguage(context, TSLanguageJava.newInstance(), TS_TYPE) {
companion object {
const val TS_TYPE = "java"
}
override fun getLanguageServer(): ILanguageServer? {
return ILanguageServerRegistry.getDefault().getServer(JavaLanguageServer.SERVER_ID)
}
override fun checkIsCompletionChar(c: Char): Boolean {
return MyCharacter.isJavaIdentifierPart(c) || c == '.'
}
override fun getInterruptionLevel(): Int {
return INTERRUPTION_LEVEL_SLIGHT
}
override fun getIndentAdvance(content: ContentReference, line: Int, column: Int): Int {
// TODO Implement this with tree-sitter
return 0
}
override fun getSymbolPairs(): SymbolPairMatch {
return JavaSymbolPairs()
}
override fun getNewlineHandlers(): Array<NewlineHandler> {
return arrayOf(BraceHandler({ line -> this.getIndentAdvance(line!!) }) { useTab() })
}
internal open class JavaSymbolPairs : CommonSymbolPairs() {
init {
super.putPair('<', SymbolPair("<", ">"))
}
}
}
Binary file not shown.