port the rest of the built-in zig features
This commit is contained in:
parent
d5fc288ffd
commit
19b0b09826
12 changed files with 520 additions and 12 deletions
|
@ -17,20 +17,22 @@ val rootPackagePath = "com/falsepattern/zigbrains/zig"
|
|||
|
||||
val parserDir = layout.buildDirectory.dir("$grammarGenRoot/parser")
|
||||
val lexerDir = layout.buildDirectory.dir("$grammarGenRoot/lexer")
|
||||
val lexerStringDir = layout.buildDirectory.dir("$grammarGenRoot/lexerstring")
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir(parserDir)
|
||||
srcDir(lexerDir)
|
||||
srcDir(lexerStringDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
sourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile))
|
||||
generatedSourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile))
|
||||
sourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile, lexerStringDir.get().asFile))
|
||||
generatedSourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile, lexerStringDir.get().asFile))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,10 +43,10 @@ tasks {
|
|||
targetOutputDir = layout.buildDirectory.dir("$grammarGenRoot/lexer/$rootPackagePath/lexer")
|
||||
}
|
||||
|
||||
register<GenerateLexerTask>("generateStringLexer") {
|
||||
register<GenerateLexerTask>("generateLexerString") {
|
||||
purgeOldFiles = true
|
||||
sourceFile = file("src/main/grammar/ZigString.flex")
|
||||
targetOutputDir = layout.buildDirectory.dir("$grammarGenRoot/stringlexer/$rootPackagePath/stringlexer")
|
||||
targetOutputDir = layout.buildDirectory.dir("$grammarGenRoot/lexerstring/$rootPackagePath/lexerstring")
|
||||
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,7 @@ tasks {
|
|||
register<DefaultTask>("generateGrammars") {
|
||||
group = "grammarkit"
|
||||
dependsOn("generateLexer")
|
||||
dependsOn("generateStringLexer")
|
||||
dependsOn("generateLexerString")
|
||||
dependsOn("generateParser")
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.falsepattern.zigbrains.zig.stringlexer;
|
||||
package com.falsepattern.zigbrains.zig.lexerstring;
|
||||
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
@ -26,15 +26,10 @@ import static com.intellij.psi.StringEscapesTokenTypes.*;
|
|||
%%
|
||||
|
||||
%public
|
||||
%class ZigStringLexer
|
||||
%class ZigLexerString
|
||||
%implements FlexLexer
|
||||
%function advance
|
||||
%type IElementType
|
||||
%{
|
||||
public ZigStringLexer() {
|
||||
|
||||
}
|
||||
%}
|
||||
|
||||
hex=[0-9a-fA-F]
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.falsepattern.zigbrains.zig.comments
|
||||
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||
import com.intellij.codeInsight.generation.IndentedCommenter
|
||||
import com.intellij.lang.CodeDocumentationAwareCommenter
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.tree.IElementType
|
||||
|
||||
class ZigCommenter: CodeDocumentationAwareCommenter, IndentedCommenter {
|
||||
override fun getLineCommentPrefix() = COMMENT
|
||||
|
||||
override fun getBlockCommentPrefix() = null
|
||||
|
||||
override fun getBlockCommentSuffix() = null
|
||||
|
||||
override fun getCommentedBlockCommentPrefix() = null
|
||||
|
||||
override fun getCommentedBlockCommentSuffix() = null
|
||||
|
||||
override fun forceIndentedLineComment() = true
|
||||
|
||||
override fun getLineCommentTokenType() = ZigTypes.LINE_COMMENT!!
|
||||
|
||||
override fun getBlockCommentTokenType() = null
|
||||
|
||||
override fun getDocumentationCommentTokenType() = ZigTypes.DOC_COMMENT!!
|
||||
|
||||
override fun getDocumentationCommentPrefix() = null
|
||||
|
||||
override fun getDocumentationCommentLinePrefix() = DOC_COMMENT
|
||||
|
||||
override fun getDocumentationCommentSuffix() = null
|
||||
|
||||
override fun isDocumentationComment(element: PsiComment?): Boolean {
|
||||
val type = element?.tokenType ?: return false
|
||||
return type == ZigTypes.DOC_COMMENT || type == ZigTypes.CONTAINER_DOC_COMMENT
|
||||
}
|
||||
}
|
||||
|
||||
const val COMMENT = "// "
|
||||
const val DOC_COMMENT = "/// "
|
|
@ -0,0 +1,136 @@
|
|||
package com.falsepattern.zigbrains.zig.formatter
|
||||
|
||||
import com.intellij.formatting.*
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.psi.TokenType
|
||||
import com.intellij.psi.formatter.common.AbstractBlock
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes.*
|
||||
|
||||
class ZigBlock(
|
||||
node: ASTNode,
|
||||
wrap: Wrap?,
|
||||
alignment: Alignment?,
|
||||
val spacingBuilder: SpacingBuilder
|
||||
) : AbstractBlock(node, wrap, alignment) {
|
||||
|
||||
override fun getSpacing(child1: Block?, child2: Block) = null
|
||||
|
||||
override fun isLeaf() = myNode.firstChildNode == null
|
||||
|
||||
override fun buildChildren(): MutableList<Block> {
|
||||
val blocks = ArrayList<Block>()
|
||||
var child = myNode.firstChildNode
|
||||
while (child != null) {
|
||||
if (child.elementType != TokenType.WHITE_SPACE) {
|
||||
blocks.add(ZigBlock(child, null, null, spacingBuilder))
|
||||
}
|
||||
child = child.treeNext
|
||||
}
|
||||
|
||||
return blocks
|
||||
}
|
||||
|
||||
override fun getChildIndent(): Indent {
|
||||
val node = this.node
|
||||
return getIndentBasedOnParentType(node, null, node.elementType, PLACEHOLDER)
|
||||
}
|
||||
|
||||
override fun getIndent(): Indent {
|
||||
val node = this.node
|
||||
val parent = node.treeParent ?: return noneIndent
|
||||
return getIndentBasedOnParentType(parent, node, parent.elementType, node.elementType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getIndentBasedOnParentType(
|
||||
parent: ASTNode,
|
||||
child: ASTNode?,
|
||||
parentType: IElementType,
|
||||
childType: IElementType
|
||||
): Indent {
|
||||
//Statement blocks
|
||||
if (parentType == BLOCK && !childType.isBrace)
|
||||
return normalIndent
|
||||
|
||||
//Struct/tuple initializers
|
||||
if (parentType == INIT_LIST && !childType.isBrace)
|
||||
return normalIndent
|
||||
|
||||
//Function call args
|
||||
if (parentType == EXPR_LIST ||
|
||||
parentType == FN_CALL_ARGUMENTS && childType === PLACEHOLDER
|
||||
)
|
||||
return normalIndent
|
||||
|
||||
//Function declaration parameters
|
||||
if (parentType == PARAM_DECL_LIST ||
|
||||
parentType == FN_PROTO && childType === PLACEHOLDER
|
||||
)
|
||||
return normalIndent
|
||||
|
||||
//Chained operations on newlines
|
||||
if ((parentType == BOOL_OR_EXPR ||
|
||||
parentType == BOOL_AND_EXPR ||
|
||||
parentType == COMPARE_EXPR ||
|
||||
parentType == BITWISE_EXPR ||
|
||||
parentType == BIT_SHIFT_EXPR ||
|
||||
parentType == ADDITION_EXPR ||
|
||||
parentType == MULTIPLY_EXPR) &&
|
||||
parent.firstChildNode != child
|
||||
)
|
||||
return normalIndent
|
||||
|
||||
//Switch prongs
|
||||
if (parentType == SWITCH_PRONG_LIST ||
|
||||
parentType == SWITCH_EXPR && childType == PLACEHOLDER
|
||||
)
|
||||
return normalIndent
|
||||
|
||||
//If expressions/statements
|
||||
if ((parentType == IF_EXPR ||
|
||||
parentType == IF_STATEMENT) &&
|
||||
childType != KEYWORD_ELSE &&
|
||||
childType != IF_PREFIX
|
||||
)
|
||||
return normalIndent
|
||||
|
||||
//Struct members
|
||||
if (parentType == CONTAINER_DECL_AUTO &&
|
||||
childType != CONTAINER_DECL_TYPE &&
|
||||
childType != CONTAINER_DOC_COMMENT &&
|
||||
!childType.isBrace
|
||||
)
|
||||
return normalIndent
|
||||
|
||||
//Inline assembly body
|
||||
if (parentType == ASM_EXPR &&
|
||||
childType != KEYWORD_ASM &&
|
||||
childType != KEYWORD_VOLATILE &&
|
||||
!childType.isParen)
|
||||
return normalIndent
|
||||
|
||||
//Assembly params
|
||||
if (parentType == ASM_INPUT_LIST || parentType == ASM_OUTPUT_LIST)
|
||||
return spaceIndent(2)
|
||||
|
||||
return noneIndent
|
||||
}
|
||||
|
||||
private val normalIndent: Indent get() = Indent.getNormalIndent()
|
||||
|
||||
private fun spaceIndent(spaces: Int) = Indent.getSpaceIndent(2)
|
||||
|
||||
private val noneIndent: Indent get() = Indent.getNoneIndent()
|
||||
|
||||
private val IElementType?.isBrace: Boolean
|
||||
get() {
|
||||
return this == LBRACE || this == RBRACE
|
||||
}
|
||||
|
||||
private val IElementType?.isParen: Boolean
|
||||
get() {
|
||||
return this == LPAREN || this == RPAREN
|
||||
}
|
||||
|
||||
private val PLACEHOLDER = IElementType("placeholder", null)
|
|
@ -0,0 +1,15 @@
|
|||
package com.falsepattern.zigbrains.zig.formatter
|
||||
|
||||
import com.falsepattern.zigbrains.zig.ZigLanguage
|
||||
import com.intellij.formatting.*
|
||||
|
||||
class ZigFormattingModelBuilder: FormattingModelBuilder {
|
||||
override fun createModel(context: FormattingContext): FormattingModel {
|
||||
val settings = context.codeStyleSettings
|
||||
return FormattingModelProvider.createFormattingModelForPsiFile(
|
||||
context.containingFile,
|
||||
ZigBlock(context.node, null, null, SpacingBuilder(settings, ZigLanguage)),
|
||||
settings
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package com.falsepattern.zigbrains.zig.highlighter
|
||||
|
||||
import com.falsepattern.zigbrains.zig.Icons
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.options.colors.AttributesDescriptor
|
||||
import com.intellij.openapi.options.colors.ColorDescriptor
|
||||
import com.intellij.openapi.options.colors.ColorSettingsPage
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
|
||||
|
||||
class ZigColorSettingsPage: ColorSettingsPage {
|
||||
override fun getAttributeDescriptors() = DESCRIPTORS
|
||||
|
||||
override fun getColorDescriptors(): Array<ColorDescriptor> = ColorDescriptor.EMPTY_ARRAY
|
||||
|
||||
override fun getDisplayName() = "Zig"
|
||||
|
||||
override fun getIcon() = Icons.ZIG
|
||||
|
||||
override fun getHighlighter() = ZigSyntaxHighlighter()
|
||||
|
||||
override fun getDemoText() = """
|
||||
///This is a documentation comment
|
||||
const <ns_decl>std</ns_decl> = @import("std");
|
||||
|
||||
const <enum_decl>AnEnum</enum_decl> = enum {
|
||||
<enum_member_decl>A</enum_member_decl>,
|
||||
<enum_member_decl>B</enum_member_decl>,
|
||||
<enum_member_decl>C</enum_member_decl>,
|
||||
};
|
||||
|
||||
const <struct_decl>AStruct</struct_decl> = struct {
|
||||
<property_decl>fieldA</property_decl>: <type>u32</type>,
|
||||
<property_decl>fieldB</property_decl>: <type>u16</type>
|
||||
};
|
||||
|
||||
const <type_decl>AnError</type_decl> = error {
|
||||
<error_tag_decl>SomeError</error_tag_decl>
|
||||
};
|
||||
|
||||
pub fn <function_decl>main</function_decl>() <type>AnError</type>.<error_tag>SomeError</error_tag>!<type>void</type> {
|
||||
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
|
||||
<namespace>std</namespace>.<namespace>debug</namespace>.<function>print</function>("All your {s} are belong to us.\n", .{"codebase"});
|
||||
|
||||
// stdout is for the actual output of your application, for example if you
|
||||
// are implementing gzip, then only the compressed bytes should be sent to
|
||||
// stdout, not any debugging messages.
|
||||
const <variable_decl>stdout_file</variable_decl> = <namespace>std</namespace>.<namespace>io</namespace>.<function>getStdOut</function>().<method>writer</method>();
|
||||
var <variable_decl>bw</variable_decl> = <namespace>std</namespace>.<namespace>io</namespace>.<function>bufferedWriter</function>(<variable>stdout_file</variable>);
|
||||
const <variable_decl>stdout</variable_decl> = <variable>bw</variable>.<method>writer</method>();
|
||||
|
||||
try <variable>stdout</variable>.<method>print</method>(\\Run `zig build test` to run the tests.
|
||||
\\
|
||||
, .{});
|
||||
|
||||
_ = <enum>AnEnum</enum>.<enum_member>A</enum_member>;
|
||||
|
||||
try <variable>bw</variable>.<method>flush</method>(); // don't forget to flush!
|
||||
}
|
||||
|
||||
test "simple test" {
|
||||
var <variable_decl>list</variable_decl> = <namespace>std</namespace>.<type>ArrayList</type>(<type>i32</type>).<function>init</function>(<namespace>std</namespace>.<namespace>testing</namespace>.<variable>allocator</variable>);
|
||||
defer <variable>list</variable>.<method>deinit</method>(); // try commenting this out and see if zig detects the memory leak!
|
||||
try <variable>list</variable>.<method>append</method>(42);
|
||||
try <namespace>std</namespace>.<namespace>testing</namespace>.<method_gen>expectEqual</method_gen>(@as(<type>i32</type>, 42), <variable>list</variable>.<method>pop</method>());
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
override fun getAdditionalHighlightingTagToDescriptorMap() =
|
||||
ADD_HIGHLIGHT
|
||||
}
|
||||
|
||||
private val ADD_HIGHLIGHT = HashMap<String, TextAttributesKey>().apply {
|
||||
this["enum"] = ZigSyntaxHighlighter.ENUM_REF
|
||||
this["enum_decl"] = ZigSyntaxHighlighter.ENUM_DECL
|
||||
this["enum_member"] = ZigSyntaxHighlighter.ENUM_MEMBER_REF
|
||||
this["enum_member_decl"] = ZigSyntaxHighlighter.ENUM_MEMBER_DECL
|
||||
this["error_tag"] = ZigSyntaxHighlighter.ERROR_TAG_REF
|
||||
this["error_tag_decl"] = ZigSyntaxHighlighter.ERROR_TAG_DECL
|
||||
this["function"] = ZigSyntaxHighlighter.FUNCTION_REF
|
||||
this["function_decl"] = ZigSyntaxHighlighter.FUNCTION_DECL
|
||||
this["method"] = ZigSyntaxHighlighter.METHOD_REF
|
||||
this["method_gen"] = ZigSyntaxHighlighter.METHOD_REF_GEN
|
||||
this["namespace"] = ZigSyntaxHighlighter.NAMESPACE_REF
|
||||
this["property_decl"] = ZigSyntaxHighlighter.PROPERTY_DECL
|
||||
this["struct"] = ZigSyntaxHighlighter.STRUCT_REF
|
||||
this["struct_decl"] = ZigSyntaxHighlighter.STRUCT_DECL
|
||||
this["type"] = ZigSyntaxHighlighter.TYPE_REF
|
||||
this["type_decl"] = ZigSyntaxHighlighter.TYPE_DECL
|
||||
this["variable"] = ZigSyntaxHighlighter.VARIABLE_REF
|
||||
this["variable_decl"] = ZigSyntaxHighlighter.VARIABLE_DECL
|
||||
}.toImmutableMap()
|
||||
|
||||
private val DESCRIPTORS: Array<AttributesDescriptor> = arrayOf(
|
||||
AttributesDescriptor("Bad character", ZigSyntaxHighlighter.BAD_CHAR),
|
||||
AttributesDescriptor("Builtin", ZigSyntaxHighlighter.BUILTIN),
|
||||
AttributesDescriptor("Character literal", ZigSyntaxHighlighter.CHAR),
|
||||
AttributesDescriptor("Comment//Regular", ZigSyntaxHighlighter.COMMENT),
|
||||
AttributesDescriptor("Comment//Documentation", ZigSyntaxHighlighter.COMMENT_DOC),
|
||||
AttributesDescriptor("Enum//Reference", ZigSyntaxHighlighter.ENUM_REF),
|
||||
AttributesDescriptor("Enum//Declaration", ZigSyntaxHighlighter.ENUM_DECL),
|
||||
AttributesDescriptor("Enum//Member//Declaration", ZigSyntaxHighlighter.ENUM_MEMBER_DECL),
|
||||
AttributesDescriptor("Enum//Member//Reference", ZigSyntaxHighlighter.ENUM_MEMBER_REF),
|
||||
AttributesDescriptor("Error tag//Declaration", ZigSyntaxHighlighter.ERROR_TAG_DECL),
|
||||
AttributesDescriptor("Error tag//Reference", ZigSyntaxHighlighter.ERROR_TAG_REF),
|
||||
AttributesDescriptor("Function//Declaration", ZigSyntaxHighlighter.FUNCTION_DECL),
|
||||
AttributesDescriptor("Function//Declaration//Generic", ZigSyntaxHighlighter.FUNCTION_DECL_GEN),
|
||||
AttributesDescriptor("Function//Reference", ZigSyntaxHighlighter.FUNCTION_REF),
|
||||
AttributesDescriptor("Function//Reference//Generic", ZigSyntaxHighlighter.FUNCTION_REF_GEN),
|
||||
AttributesDescriptor("Keyword", ZigSyntaxHighlighter.KEYWORD),
|
||||
AttributesDescriptor("Label//Declaration", ZigSyntaxHighlighter.LABEL_REF),
|
||||
AttributesDescriptor("Label//Reference", ZigSyntaxHighlighter.LABEL_REF),
|
||||
AttributesDescriptor("Method//Declaration", ZigSyntaxHighlighter.METHOD_DECL),
|
||||
AttributesDescriptor("Method//Declaration//Generic", ZigSyntaxHighlighter.METHOD_DECL_GEN),
|
||||
AttributesDescriptor("Method//Reference", ZigSyntaxHighlighter.METHOD_REF),
|
||||
AttributesDescriptor("Method//Reference//Generic", ZigSyntaxHighlighter.METHOD_REF_GEN),
|
||||
AttributesDescriptor("Namespace//Declaration", ZigSyntaxHighlighter.NAMESPACE_DECL),
|
||||
AttributesDescriptor("Namespace//Reference", ZigSyntaxHighlighter.NAMESPACE_REF),
|
||||
AttributesDescriptor("Number", ZigSyntaxHighlighter.NUMBER),
|
||||
AttributesDescriptor("Operator", ZigSyntaxHighlighter.OPERATOR),
|
||||
AttributesDescriptor("Parameter", ZigSyntaxHighlighter.PARAMETER),
|
||||
AttributesDescriptor("Property//Declaration", ZigSyntaxHighlighter.PROPERTY_DECL),
|
||||
AttributesDescriptor("Property//Reference", ZigSyntaxHighlighter.PROPERTY_REF),
|
||||
AttributesDescriptor("String", ZigSyntaxHighlighter.STRING),
|
||||
AttributesDescriptor("String//Escape", ZigSyntaxHighlighter.STRING_ESC_V),
|
||||
AttributesDescriptor("String//Escape//Invalid char", ZigSyntaxHighlighter.STRING_ESC_I_C),
|
||||
AttributesDescriptor("String//Escape//Invalid unicode", ZigSyntaxHighlighter.STRING_ESC_I_U),
|
||||
AttributesDescriptor("Struct//Declaration", ZigSyntaxHighlighter.STRUCT_DECL),
|
||||
AttributesDescriptor("Struct//Reference", ZigSyntaxHighlighter.STRUCT_REF),
|
||||
AttributesDescriptor("Type//Declaration", ZigSyntaxHighlighter.TYPE_DECL),
|
||||
AttributesDescriptor("Type//Declaration//Generic", ZigSyntaxHighlighter.TYPE_DECL_GEN),
|
||||
AttributesDescriptor("Type//Reference", ZigSyntaxHighlighter.TYPE_REF),
|
||||
AttributesDescriptor("Type//Reference//Generic", ZigSyntaxHighlighter.TYPE_REF_GEN),
|
||||
AttributesDescriptor("Type parameter//Reference", ZigSyntaxHighlighter.TYPE_PARAM),
|
||||
AttributesDescriptor("Type parameter//Declaration", ZigSyntaxHighlighter.TYPE_PARAM_DECL),
|
||||
AttributesDescriptor("Variable//Declaration", ZigSyntaxHighlighter.VARIABLE_DECL),
|
||||
AttributesDescriptor("Variable//Declaration//Deprecated", ZigSyntaxHighlighter.VARIABLE_DECL_DEPR),
|
||||
AttributesDescriptor("Variable//Reference", ZigSyntaxHighlighter.VARIABLE_REF),
|
||||
AttributesDescriptor("Variable//Reference//Deprecated", ZigSyntaxHighlighter.VARIABLE_REF_DEPR),
|
||||
)
|
|
@ -0,0 +1,104 @@
|
|||
package com.falsepattern.zigbrains.zig.highlighter
|
||||
|
||||
import com.falsepattern.zigbrains.zig.lexer.ZigHighlightingLexer
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
|
||||
import com.intellij.openapi.editor.HighlighterColors
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase
|
||||
import com.intellij.psi.StringEscapesTokenTypes
|
||||
import com.intellij.psi.TokenType
|
||||
import com.intellij.psi.tree.IElementType
|
||||
|
||||
class ZigSyntaxHighlighter: SyntaxHighlighterBase() {
|
||||
override fun getHighlightingLexer() = ZigHighlightingLexer()
|
||||
|
||||
override fun getTokenHighlights(tokenType: IElementType?) =
|
||||
KEYMAP.getOrDefault(tokenType, EMPTY_KEYS)
|
||||
|
||||
companion object {
|
||||
|
||||
// @formatter:off
|
||||
val BAD_CHAR = createKey("BAD_CHARACTER" , HighlighterColors.BAD_CHARACTER )
|
||||
val BUILTIN = createKey("BUILTIN" , DefaultLanguageHighlighterColors.STATIC_METHOD )
|
||||
val CHAR = createKey("CHAR" , DefaultLanguageHighlighterColors.NUMBER )
|
||||
val COMMENT = createKey("COMMENT" , DefaultLanguageHighlighterColors.LINE_COMMENT )
|
||||
val COMMENT_DOC = createKey("COMMENT_DOC" , DefaultLanguageHighlighterColors.DOC_COMMENT )
|
||||
val ENUM_DECL = createKey("ENUM_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
|
||||
val ENUM_REF = createKey("ENUM" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
|
||||
val ENUM_MEMBER_DECL = createKey("ENUM_MEMBER_DECL" , DefaultLanguageHighlighterColors.STATIC_FIELD )
|
||||
val ENUM_MEMBER_REF = createKey("ENUM_MEMBER" , ENUM_MEMBER_DECL )
|
||||
val ERROR_TAG_DECL = createKey("ERROR_TAG_DECL" , DefaultLanguageHighlighterColors.STATIC_FIELD )
|
||||
val ERROR_TAG_REF = createKey("ERROR_TAG" , ERROR_TAG_DECL )
|
||||
val PROPERTY_DECL = createKey("PROPERTY_DECL" , DefaultLanguageHighlighterColors.STATIC_FIELD )
|
||||
val PROPERTY_REF = createKey("PROPERTY" , PROPERTY_DECL )
|
||||
val FUNCTION_DECL = createKey("FUNCTION_DECL" , DefaultLanguageHighlighterColors.FUNCTION_DECLARATION )
|
||||
val FUNCTION_DECL_GEN = createKey("FUNCTION_DECL_GEN" , FUNCTION_DECL )
|
||||
val FUNCTION_REF = createKey("FUNCTION" , DefaultLanguageHighlighterColors.FUNCTION_CALL )
|
||||
val FUNCTION_REF_GEN = createKey("FUNCTION_GEN" , FUNCTION_REF )
|
||||
val KEYWORD = createKey("KEYWORD" , DefaultLanguageHighlighterColors.KEYWORD )
|
||||
val LABEL_DECL = createKey("LABEL_DECL" , DefaultLanguageHighlighterColors.LABEL )
|
||||
val LABEL_REF = createKey("LABEL" , LABEL_DECL )
|
||||
val METHOD_DECL = createKey("METHOD_DECL" , FUNCTION_DECL )
|
||||
val METHOD_DECL_GEN = createKey("METHOD_DECL_GEN" , METHOD_DECL )
|
||||
val METHOD_REF = createKey("METHOD" , FUNCTION_REF )
|
||||
val METHOD_REF_GEN = createKey("METHOD_GEN" , METHOD_REF )
|
||||
val NAMESPACE_DECL = createKey("NAMESPACE_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
|
||||
val NAMESPACE_REF = createKey("NAMESPACE" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
|
||||
val NUMBER = createKey("NUMBER" , DefaultLanguageHighlighterColors.NUMBER )
|
||||
val OPERATOR = createKey("OPERATOR" , DefaultLanguageHighlighterColors.OPERATION_SIGN )
|
||||
val PARAMETER = createKey("PARAMETER" , DefaultLanguageHighlighterColors.PARAMETER )
|
||||
val STRING = createKey("STRING" , DefaultLanguageHighlighterColors.STRING )
|
||||
val STRING_ESC_V = createKey("STRING_ESC_V" , DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE )
|
||||
val STRING_ESC_I_C = createKey("STRING_ESC_I_C" , DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE )
|
||||
val STRING_ESC_I_U = createKey("STRING_ESC_I_U" , DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE )
|
||||
val STRUCT_DECL = createKey("STRUCT_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
|
||||
val STRUCT_REF = createKey("STRUCT" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
|
||||
val TYPE_DECL = createKey("TYPE_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
|
||||
val TYPE_DECL_GEN = createKey("TYPE_DECL_GEN" , TYPE_DECL )
|
||||
val TYPE_REF = createKey("TYPE" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
|
||||
val TYPE_REF_GEN = createKey("TYPE_GEN" , TYPE_REF )
|
||||
val TYPE_PARAM = createKey("TYPE_PARAM" , DefaultLanguageHighlighterColors.PARAMETER )
|
||||
val TYPE_PARAM_DECL = createKey("TYPE_PARAM_DECL" , TYPE_PARAM )
|
||||
val VARIABLE_DECL = createKey("VARIABLE_DECL" , DefaultLanguageHighlighterColors.LOCAL_VARIABLE )
|
||||
val VARIABLE_DECL_DEPR= createKey("VARIABLE_DECL_DEPR" , VARIABLE_DECL )
|
||||
val VARIABLE_REF = createKey("VARIABLE" , VARIABLE_DECL )
|
||||
val VARIABLE_REF_DEPR = createKey("VARIABLE_REF_DEPL" , VARIABLE_REF )
|
||||
// @formatter:on
|
||||
|
||||
private val EMPTY_KEYS = arrayOf<TextAttributesKey>()
|
||||
private val KEYMAP = HashMap<IElementType, Array<TextAttributesKey>>()
|
||||
|
||||
init {
|
||||
addMapping(COMMENT, ZigTypes.LINE_COMMENT)
|
||||
addMapping(COMMENT_DOC, ZigTypes.DOC_COMMENT, ZigTypes.CONTAINER_DOC_COMMENT)
|
||||
|
||||
addMapping(
|
||||
KEYWORD,
|
||||
*ZigTypes::class.java
|
||||
.fields
|
||||
.filter { it.name.startsWith("KEYWORD_") }
|
||||
.map { it.get(null) as IElementType }
|
||||
.toTypedArray()
|
||||
)
|
||||
addMapping(BUILTIN, ZigTypes.BUILTINIDENTIFIER)
|
||||
addMapping(STRING, ZigTypes.STRING_LITERAL_SINGLE, ZigTypes.STRING_LITERAL_MULTI)
|
||||
addMapping(STRING_ESC_V, StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN)
|
||||
addMapping(STRING_ESC_I_C, StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN)
|
||||
addMapping(STRING_ESC_I_U, StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN)
|
||||
addMapping(BAD_CHAR, TokenType.BAD_CHARACTER)
|
||||
addMapping(NUMBER, ZigTypes.INTEGER, ZigTypes.FLOAT)
|
||||
addMapping(CHAR, ZigTypes.CHAR_LITERAL)
|
||||
}
|
||||
|
||||
private fun addMapping(key: TextAttributesKey, vararg types: IElementType) {
|
||||
val a = arrayOf(key)
|
||||
for (type in types) {
|
||||
KEYMAP[type] = a
|
||||
}
|
||||
}
|
||||
|
||||
private fun createKey(name: String, fallback: TextAttributesKey) =
|
||||
TextAttributesKey.createTextAttributesKey("ZIG_$name", fallback)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.falsepattern.zigbrains.zig.highlighter
|
||||
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighter
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
|
||||
class ZigSyntaxHighlighterFactory: SyntaxHighlighterFactory() {
|
||||
override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?) =
|
||||
ZigSyntaxHighlighter()
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.falsepattern.zigbrains.zig.lexer
|
||||
|
||||
import com.falsepattern.zigbrains.zig.lexerstring.ZigLexerStringAdapter
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||
import com.intellij.lexer.LayeredLexer
|
||||
import com.intellij.lexer.MergingLexerAdapter
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
|
||||
class ZigHighlightingLexer: LayeredLexer(ZigLexerAdapter()) {
|
||||
init {
|
||||
registerSelfStoppingLayer(
|
||||
MergingLexerAdapter(
|
||||
ZigLexerStringAdapter(),
|
||||
TokenSet.create(ZigTypes.STRING_LITERAL_SINGLE)
|
||||
),
|
||||
arrayOf(ZigTypes.STRING_LITERAL_SINGLE),
|
||||
IElementType.EMPTY_ARRAY
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.falsepattern.zigbrains.zig.lexerstring
|
||||
|
||||
import com.intellij.lexer.FlexAdapter
|
||||
|
||||
class ZigLexerStringAdapter: FlexAdapter(ZigLexerString(null)) {
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.falsepattern.zigbrains.zig.pairing
|
||||
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||
import com.intellij.lang.BracePair
|
||||
import com.intellij.lang.PairedBraceMatcher
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.tree.IElementType
|
||||
|
||||
class ZigBraceMatcher: PairedBraceMatcher {
|
||||
override fun getPairs() =
|
||||
PAIRS
|
||||
|
||||
override fun isPairedBracesAllowedBeforeType(lbraceType: IElementType, contextType: IElementType?) =
|
||||
true
|
||||
|
||||
override fun getCodeConstructStart(file: PsiFile?, openingBraceOffset: Int) =
|
||||
file?.findElementAt(openingBraceOffset)?.parent?.textOffset ?: openingBraceOffset
|
||||
}
|
||||
|
||||
private val BRACE_PAIR = BracePair(ZigTypes.LBRACE, ZigTypes.RBRACE, true)
|
||||
private val PAREN_PAIR = BracePair(ZigTypes.LPAREN, ZigTypes.RPAREN, false)
|
||||
private val BRACKET_PAIR = BracePair(ZigTypes.LBRACKET, ZigTypes.RBRACKET, false)
|
||||
private val PAIRS = arrayOf(BRACE_PAIR, PAREN_PAIR, BRACKET_PAIR)
|
|
@ -7,15 +7,29 @@
|
|||
|
||||
<!-- region Zig -->
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<colorSettingsPage
|
||||
implementation="com.falsepattern.zigbrains.zig.highlighter.ZigColorSettingsPage"/>
|
||||
<fileType
|
||||
name="Zig File"
|
||||
implementationClass="com.falsepattern.zigbrains.zig.ZigFileType"
|
||||
fieldName="INSTANCE"
|
||||
language="Zig"
|
||||
extensions="zig"/>
|
||||
<lang.braceMatcher
|
||||
language="Zig"
|
||||
implementationClass="com.falsepattern.zigbrains.zig.pairing.ZigBraceMatcher"/>
|
||||
<lang.commenter
|
||||
language="Zig"
|
||||
implementationClass="com.falsepattern.zigbrains.zig.comments.ZigCommenter"/>
|
||||
<lang.formatter
|
||||
language="Zig"
|
||||
implementationClass="com.falsepattern.zigbrains.zig.formatter.ZigFormattingModelBuilder"/>
|
||||
<lang.parserDefinition
|
||||
language="Zig"
|
||||
implementationClass="com.falsepattern.zigbrains.zig.parser.ZigParserDefinition"/>
|
||||
<lang.syntaxHighlighterFactory
|
||||
language="Zig"
|
||||
implementationClass="com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighterFactory"/>
|
||||
</extensions>
|
||||
<!-- endregion Zig -->
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue