Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit 40062ad

Browse files
committed
Implemented logic for showing code blocks in all supported languages
1 parent a806710 commit 40062ad

File tree

7 files changed

+83
-39
lines changed

7 files changed

+83
-39
lines changed

app/src/main/java/com/itsaky/androidide/language/cpp/CppAnalyzer.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,7 @@ public CppAnalyzer() {
4343
}
4444

4545
@Override
46-
public List<CodeBlock> computeBlocks(
47-
final Content text,
48-
final AsyncIncrementalAnalyzeManager<LineState, IncrementalToken>.CodeBlockAnalyzeDelegate
49-
delegate) {
50-
return Collections.emptyList();
51-
}
52-
53-
@Override
54-
protected int[] getBraceTypes() {
46+
protected int[] getCodeBlockTokens() {
5547
return new int[] {LeftBrace, RightBrace};
5648
}
5749

app/src/main/java/com/itsaky/androidide/language/groovy/GroovyAnalyzer.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ import io.github.rosemoe.sora.text.Content
3131
/** @author Akash Yadav */
3232
class GroovyAnalyzer : BaseIncrementalAnalyzeManager(GroovyLexer::class.java) {
3333

34-
override fun computeBlocks(text: Content, delegate: CodeBlockAnalyzeDelegate): List<CodeBlock> {
35-
return emptyList()
36-
}
37-
38-
override fun getBraceTypes() = intArrayOf(GroovyLexer.LBRACE, GroovyLexer.RBRACE)
34+
override fun getCodeBlockTokens() = intArrayOf(GroovyLexer.LBRACE, GroovyLexer.RBRACE)
3935

4036
override fun generateSpans(
4137
tokens: LineTokenizeResult<LineState, IncrementalToken>,

app/src/main/java/com/itsaky/androidide/language/incremental/BaseIncrementalAnalyzeManager.java

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@
4242
import java.util.ArrayList;
4343
import java.util.List;
4444
import java.util.Objects;
45+
import java.util.Stack;
4546
import java.util.stream.Collectors;
4647

4748
import io.github.rosemoe.sora.lang.analysis.AsyncIncrementalAnalyzeManager;
49+
import io.github.rosemoe.sora.lang.styling.CodeBlock;
4850
import io.github.rosemoe.sora.lang.styling.Span;
4951
import io.github.rosemoe.sora.lang.styling.TextStyle;
52+
import io.github.rosemoe.sora.text.Content;
5053
import io.github.rosemoe.sora.util.IntPair;
5154
import kotlin.Pair;
5255

@@ -61,6 +64,7 @@ public abstract class BaseIncrementalAnalyzeManager
6164
protected final Lexer lexer;
6265
private final int[] multilineStartTypes;
6366
private final int[] multilineEndTypes;
67+
private final int[] blockTokens;
6468
private static final ILogger LOG = ILogger.newInstance("BaseIncrementalAnalyzeManager");
6569

6670
public BaseIncrementalAnalyzeManager(final Class<? extends Lexer> lexer) {
@@ -72,6 +76,7 @@ public BaseIncrementalAnalyzeManager(final Class<? extends Lexer> lexer) {
7276

7377
this.multilineStartTypes = multilineTokenTypes[0];
7478
this.multilineEndTypes = multilineTokenTypes[1];
79+
this.blockTokens = Objects.requireNonNullElseGet(getCodeBlockTokens(), () -> new int[] {});
7580
}
7681

7782
@NonNull
@@ -128,6 +133,14 @@ private boolean matchTokenTypes(
128133
return true;
129134
}
130135

136+
protected boolean isCodeBlockStart(IncrementalToken token) {
137+
return blockTokens.length == 2 && token.getType() == blockTokens[0];
138+
}
139+
140+
protected boolean isCodeBlockEnd(IncrementalToken token) {
141+
return blockTokens.length == 2 && token.getType() == blockTokens[1];
142+
}
143+
131144
/**
132145
* Returns the token types which start and end a multiline token.
133146
*
@@ -169,7 +182,7 @@ protected IncrementalToken nextToken() {
169182
*
170183
* @return An array of left and right brace token types.
171184
*/
172-
protected abstract int[] getBraceTypes();
185+
protected abstract int[] getCodeBlockTokens();
173186

174187
/**
175188
* Pop (remove) required number of tokens after an incomplete token has been encountered. <br>
@@ -226,6 +239,59 @@ public boolean stateEquals(final LineState state, final LineState another) {
226239
return state.equals(another);
227240
}
228241

242+
@Override
243+
public List<CodeBlock> computeBlocks(
244+
final Content text,
245+
final AsyncIncrementalAnalyzeManager<LineState, IncrementalToken>.CodeBlockAnalyzeDelegate
246+
delegate) {
247+
final var stack = new Stack<CodeBlock>();
248+
final var blocks = new ArrayList<CodeBlock>();
249+
var line = 0;
250+
var maxSwitch = 0;
251+
var currSwitch = 0;
252+
while (delegate.isNotCancelled() && line < text.getLineCount()) {
253+
final var tokens = getState(line);
254+
final var checkForIdentifiers =
255+
tokens.state.state == NORMAL
256+
|| (tokens.state.state == INCOMPLETE && tokens.tokens.size() > 1);
257+
if (!tokens.state.hasBraces && !checkForIdentifiers) {
258+
line++;
259+
continue;
260+
}
261+
262+
for (int i = 0; i < tokens.tokens.size(); i++) {
263+
final var token = tokens.tokens.get(i);
264+
final var type = token.getType();
265+
var offset = token.getStartIndex();
266+
if (isCodeBlockStart(token)) {
267+
if (stack.isEmpty()) {
268+
if (currSwitch > maxSwitch) {
269+
maxSwitch = currSwitch;
270+
}
271+
currSwitch = 0;
272+
}
273+
currSwitch++;
274+
CodeBlock block = new CodeBlock();
275+
block.startLine = line;
276+
block.startColumn = offset;
277+
stack.push(block);
278+
} else if (isCodeBlockEnd(token)) {
279+
if (!stack.isEmpty()) {
280+
CodeBlock block = stack.pop();
281+
block.endLine = line;
282+
block.endColumn = offset;
283+
if (block.startLine != block.endLine) {
284+
blocks.add(block);
285+
}
286+
}
287+
}
288+
}
289+
290+
line++;
291+
}
292+
return blocks;
293+
}
294+
229295
@Override
230296
public LineTokenizeResult<LineState, IncrementalToken> tokenizeLine(
231297
final CharSequence line, final LineState state) {
@@ -299,7 +365,7 @@ protected int tokenizeNormal(
299365
start.add(token);
300366
end.add(token);
301367
final var type = token.getType();
302-
if (ArrayUtils.contains(getBraceTypes(), type)) {
368+
if (ArrayUtils.contains(getCodeBlockTokens(), type)) {
303369
st.hasBraces = true;
304370
}
305371

app/src/main/java/com/itsaky/androidide/language/java/JavaAnalyzer.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,7 @@ class JavaAnalyzer : BaseIncrementalAnalyzeManager(JavaLexer::class.java) {
4040

4141
private val log = ILogger.newInstance(javaClass.simpleName)
4242

43-
override fun computeBlocks(text: Content, delegate: CodeBlockAnalyzeDelegate): List<CodeBlock> {
44-
return emptyList()
45-
}
46-
47-
override fun getBraceTypes(): IntArray = intArrayOf(JavaLexer.LBRACE, JavaLexer.RBRACE)
43+
override fun getCodeBlockTokens(): IntArray = intArrayOf(JavaLexer.LBRACE, JavaLexer.RBRACE)
4844

4945
override fun generateSpans(
5046
tokens: LineTokenizeResult<LineState, IncrementalToken>,

app/src/main/java/com/itsaky/androidide/language/kotlin/KotlinAnalyzer.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,7 @@ import io.github.rosemoe.sora.text.Content
4141
*/
4242
class KotlinAnalyzer : BaseIncrementalAnalyzeManager(KotlinLexer::class.java) {
4343

44-
override fun computeBlocks(
45-
text: Content?,
46-
delegate: CodeBlockAnalyzeDelegate,
47-
): MutableList<CodeBlock> {
48-
return mutableListOf()
49-
}
50-
51-
override fun getBraceTypes() = intArrayOf(KotlinLexer.LCURL, KotlinLexer.RCURL)
44+
override fun getCodeBlockTokens() = intArrayOf(KotlinLexer.LCURL, KotlinLexer.RCURL)
5245

5346
override fun getMultilineTokenStartEndTypes(): Array<IntArray> {
5447
val start = intArrayOf(KotlinLexer.DIV, KotlinLexer.MULT)

app/src/main/java/com/itsaky/androidide/language/xml/XMLAnalyzer.kt

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@ import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE.XML_TAG
5050
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE.forComment
5151
import com.itsaky.inflater.util.CommonParseUtils
5252
import io.github.rosemoe.sora.lang.analysis.IncrementalAnalyzeManager.LineTokenizeResult
53-
import io.github.rosemoe.sora.lang.styling.CodeBlock
5453
import io.github.rosemoe.sora.lang.styling.Span
5554
import io.github.rosemoe.sora.lang.styling.TextStyle.makeStyle
56-
import io.github.rosemoe.sora.text.Content
5755

5856
/**
5957
* Syntax analyzer for XML.
@@ -62,14 +60,7 @@ import io.github.rosemoe.sora.text.Content
6260
*/
6361
class XMLAnalyzer : BaseIncrementalAnalyzeManager(XMLLexer::class.java) {
6462

65-
override fun computeBlocks(
66-
text: Content?,
67-
delegate: CodeBlockAnalyzeDelegate?,
68-
): MutableList<CodeBlock> {
69-
return mutableListOf()
70-
}
71-
72-
override fun getBraceTypes() = intArrayOf()
63+
override fun getCodeBlockTokens() = intArrayOf()
7364

7465
override fun getMultilineTokenStartEndTypes(): Array<IntArray> {
7566
val start = intArrayOf(COMMENT_START)
@@ -82,6 +73,16 @@ class XMLAnalyzer : BaseIncrementalAnalyzeManager(XMLLexer::class.java) {
8273
return super.isIncompleteTokenEnd(q) || q.peek()!!.getType() == COMMENT_END
8374
}
8475

76+
override fun isCodeBlockStart(token: IncrementalToken): Boolean {
77+
val type = token.getType()
78+
return type == OPEN || type == XMLDeclOpen
79+
}
80+
81+
override fun isCodeBlockEnd(token: IncrementalToken): Boolean {
82+
val type = token.getType()
83+
return type == OPEN_SLASH || type == SPECIAL_CLOSE || type == SLASH_CLOSE
84+
}
85+
8586
override fun popTokensAfterIncomplete(
8687
incompleteToken: IncrementalToken,
8788
tokens: MutableList<IncrementalToken>
Binary file not shown.

0 commit comments

Comments
 (0)