Skip to content

Commit 87f22dd

Browse files
committed
feat(documentation): add documentation for TL-B types
Fixes #77
1 parent 6af5401 commit 87f22dd

File tree

3 files changed

+103
-2
lines changed

3 files changed

+103
-2
lines changed

src/main/kotlin/org/tonstudio/tact/ide/documentation/TactDocumentationProvider.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@ class TactDocumentationProvider : AbstractDocumentationProvider() {
2525
is TactParamDefinition -> element.generateDoc()
2626
is TactFieldDefinition -> element.generateDoc()
2727
is TactAsmInstruction -> element.generateDoc()
28+
is TactTlb -> element.generateDoc()
2829
else -> null
2930
}
3031

3132
override fun getCustomDocumentationElement(editor: Editor, file: PsiFile, contextElement: PsiElement?, targetOffset: Int): PsiElement? {
32-
if (contextElement?.parent is TactAsmInstruction) {
33-
return contextElement.parent
33+
val parent = contextElement?.parent
34+
val grand = parent?.parent
35+
if (parent is TactAsmInstruction) {
36+
return parent
37+
}
38+
if (grand is TactTlb) {
39+
return grand
3440
}
3541
return super.getCustomDocumentationElement(editor, file, contextElement, targetOffset)
3642
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package org.tonstudio.tact.ide.documentation
2+
3+
data class TypeDoc(
4+
val range: String,
5+
val size: String,
6+
val description: String? = null,
7+
val tlb: String? = null,
8+
)
9+
10+
val TYPE_DOCS: Map<String, TypeDoc> = mapOf(
11+
"uint8" to TypeDoc(range = "0 to 255 (2^8 - 1)", size = "8 bits = 1 byte"),
12+
"uint16" to TypeDoc(range = "0 to 65,535 (2^16 - 1)", size = "16 bits = 2 bytes"),
13+
"uint32" to TypeDoc(range = "0 to 4,294,967,295 (2^32 - 1)", size = "32 bits = 4 bytes"),
14+
"uint64" to TypeDoc(range = "0 to 2^64 - 1", size = "64 bits = 8 bytes"),
15+
"uint128" to TypeDoc(range = "0 to 2^128 - 1", size = "128 bits = 16 bytes"),
16+
"uint256" to TypeDoc(range = "0 to 2^256 - 1", size = "256 bits = 32 bytes"),
17+
18+
"int8" to TypeDoc(range = "-128 to 127 (-2^7 to 2^7 - 1)", size = "8 bits = 1 byte"),
19+
"int16" to TypeDoc(range = "-32,768 to 32,767 (-2^15 to 2^15 - 1)", size = "16 bits = 2 bytes"),
20+
"int32" to TypeDoc(range = "-2^31 to 2^31 - 1", size = "32 bits = 4 bytes"),
21+
"int64" to TypeDoc(range = "-2^63 to 2^63 - 1", size = "64 bits = 8 bytes"),
22+
"int128" to TypeDoc(range = "-2^127 to 2^127 - 1", size = "128 bits = 16 bytes"),
23+
"int256" to TypeDoc(range = "-2^255 to 2^255 - 1", size = "256 bits = 32 bytes"),
24+
"int257" to TypeDoc(range = "-2^256 to 2^256 - 1", size = "257 bits = 32 bytes + 1 bit"),
25+
26+
"coins" to TypeDoc(
27+
range = "0 to 2^120 - 1",
28+
size = "4 to 124 bits",
29+
description = "An alias to `VarUInteger16`, commonly used for storing `nanoToncoin` amounts. Takes variable bit length depending on the optimal number of bytes needed.",
30+
tlb = "varuint16"
31+
),
32+
"varuint16" to TypeDoc(range = "0 to 2^120 - 1", size = "4 to 124 bits"),
33+
"varint16" to TypeDoc(range = "-2^119 to 2^119 - 1", size = "4 to 124 bits"),
34+
"varuint32" to TypeDoc(range = "0 to 2^248 - 1", size = "5 to 253 bits"),
35+
"varint32" to TypeDoc(range = "-2^247 to 2^247 - 1", size = "5 to 253 bits")
36+
)
37+
38+
fun generateArbitraryIntDoc(type: String): TypeDoc? {
39+
val match = Regex("""^(u?int)(\d+)$""").matchEntire(type) ?: return null
40+
val (prefix, bitsStr) = match.destructured
41+
val bitWidth = bitsStr.toInt()
42+
43+
if (prefix == "uint" && (bitWidth < 1 || bitWidth > 256)) return null
44+
if (prefix == "int" && (bitWidth < 1 || bitWidth > 257)) return null
45+
46+
return if (prefix == "uint") {
47+
TypeDoc(
48+
range = "0 to 2^$bitWidth - 1",
49+
size = "$bitWidth bits",
50+
description = "Arbitrary bit-width unsigned integer type (available since Tact 1.5)"
51+
)
52+
} else {
53+
TypeDoc(
54+
range = "-2^${bitWidth - 1} to 2^${bitWidth - 1} - 1",
55+
size = "$bitWidth bits",
56+
description = "Arbitrary bit-width signed integer type (available since Tact 1.5)"
57+
)
58+
}
59+
}
60+
61+
fun generateTlBTypeDoc(word: String): String? {
62+
if (word == "remaining") {
63+
return """
64+
**remaining** — direct serialization modifier
65+
66+
- **Applies to**: Cell, Builder, and Slice types
67+
- **Effect**: Stores/loads data directly in the current cell instead of as a reference
68+
- **Usage**: `value: Type as remaining`
69+
70+
Affects how values are serialized into cells. Instead of using references (default), stores data directly in the current cell.
71+
72+
Learn more in documentation: https://docs.tact-lang.org/book/cells/#serialization-remaining
73+
""".trimIndent()
74+
}
75+
76+
val typeInfo = TYPE_DOCS[word] ?: generateArbitraryIntDoc(word) ?: return null
77+
val isVariable = word.startsWith("var") || word == "coins"
78+
val isUnsigned = word.startsWith("uint") || word == "coins"
79+
val bitSizePrefix = if (isVariable) "variable-length" else "${typeInfo.size.split(' ')[0]}-bit"
80+
81+
return buildString {
82+
appendLine("**$word** — $bitSizePrefix ${if (isUnsigned) "unsigned" else "signed"} integer")
83+
appendLine()
84+
appendLine("- **Range**: ${typeInfo.range}")
85+
appendLine("- **Size**: ${typeInfo.size}")
86+
append("- **TL-B**: ${typeInfo.tlb ?: word}")
87+
typeInfo.description?.let { appendLine("\n\n$it") }
88+
}
89+
}

src/main/kotlin/org/tonstudio/tact/ide/documentation/documentation.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,12 @@ fun TactAsmInstruction.generateDoc(): String {
497497
return actualInstructionDescription.joinToString("\n")
498498
}
499499

500+
fun TactTlb.generateDoc(): String? {
501+
val word = typeReferenceExpression?.text ?: return null
502+
val markdownDoc = generateTlBTypeDoc(word) ?: return null
503+
return documentationAsHtml(markdownDoc, null, TactDocRenderMode.QUICK_DOC_POPUP, this)
504+
}
505+
500506
fun wrapDefinition(content: String): String = DocumentationMarkup.DEFINITION_START + content + DocumentationMarkup.DEFINITION_END
501507

502508
fun TactExpression.generateDoc(): String {

0 commit comments

Comments
 (0)