global: idea generation support

This commit is contained in:
Alex Zenla 2023-09-17 00:37:58 -07:00
parent 821aa3563a
commit 3b101bd48a
Signed by: alex
GPG Key ID: C0780728420EBFE5
57 changed files with 618 additions and 47 deletions

View File

@ -1,8 +1,10 @@
import gay.pizza.pork.buildext.AstCodegenType
plugins {
id("gay.pizza.pork.module")
id("gay.pizza.pork.ast")
}
tasks.compileKotlin {
dependsOn(tasks.generateAstCode)
porkAst {
astCodegenType.set(AstCodegenType.Standard)
}

View File

@ -36,6 +36,7 @@ types:
type: List<Definition>
LetAssignment:
parent: Expression
namedElementValue: symbol
values:
- name: symbol
type: Symbol
@ -43,6 +44,7 @@ types:
type: Expression
VarAssignment:
parent: Expression
namedElementValue: symbol
values:
- name: symbol
type: Symbol
@ -50,6 +52,7 @@ types:
type: Expression
SetAssignment:
parent: Expression
namedElementValue: symbol
values:
- name: symbol
type: Symbol
@ -141,6 +144,7 @@ types:
defaultValue: "false"
FunctionDefinition:
parent: Definition
namedElementValue: symbol
values:
- name: modifiers
type: DefinitionModifiers
@ -154,6 +158,7 @@ types:
type: Native?
LetDefinition:
parent: Definition
namedElementValue: symbol
values:
- name: modifiers
type: DefinitionModifiers
@ -251,6 +256,7 @@ types:
type: String
SymbolReference:
parent: Expression
namedElementValue: symbol
values:
- name: symbol
type: Symbol

View File

@ -0,0 +1,6 @@
package gay.pizza.pork.buildext
enum class AstCodegenType {
Standard,
PorkIdea
}

View File

@ -0,0 +1,27 @@
package gay.pizza.pork.buildext
import gay.pizza.pork.buildext.ast.AstPorkIdeaCodegen
import gay.pizza.pork.buildext.ast.AstWorld
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import java.io.File
open class GeneratePorkIdeaAstCode : DefaultTask() {
@get:InputFile
var astDescriptionFile: File = project.project(":ast").file("src/main/ast/pork.yml")
@get:Input
var codePackage: String = "gay.pizza.pork.idea.psi.gen"
@get:OutputDirectory
var outputDirectory: File = project.file("src/main/kotlin/gay/pizza/pork/idea/psi/gen")
@TaskAction
fun generate() {
val world = AstWorld.read(astDescriptionFile.toPath())
AstPorkIdeaCodegen.run(codePackage, world, outputDirectory.toPath())
}
}

View File

@ -1,6 +1,6 @@
package gay.pizza.pork.buildext
import gay.pizza.pork.buildext.ast.AstCodegen
import gay.pizza.pork.buildext.ast.AstStandardCodegen
import gay.pizza.pork.buildext.ast.AstGraph
import gay.pizza.pork.buildext.ast.AstWorld
import org.gradle.api.DefaultTask
@ -14,7 +14,7 @@ import kotlin.io.path.createDirectories
import kotlin.io.path.deleteIfExists
import kotlin.io.path.writeText
open class GenerateAstCode : DefaultTask() {
open class GenerateStandardAstCode : DefaultTask() {
@get:InputFile
var astDescriptionFile: File = project.file("src/main/ast/pork.yml")
@ -30,7 +30,7 @@ open class GenerateAstCode : DefaultTask() {
@TaskAction
fun generate() {
val world = AstWorld.read(astDescriptionFile.toPath())
AstCodegen.run(codePackage, world, outputDirectory.toPath())
AstStandardCodegen.run(codePackage, world, outputDirectory.toPath())
val typeGraphPath = typeGraphFile.toPath()
typeGraphPath.deleteIfExists()

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.buildext
import org.gradle.api.provider.Property
interface PorkAstExtension {
val astCodegenType: Property<AstCodegenType>
}

View File

@ -2,15 +2,32 @@ package gay.pizza.pork.buildext
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.getByType
class PorkAstPlugin : Plugin<Project> {
override fun apply(target: Project) {
val generateAstCode = createGenerateAstCode(target)
val processResources = target.tasks.getByName("processResources")
processResources.dependsOn(generateAstCode)
target.extensions.create("porkAst", PorkAstExtension::class)
target.afterEvaluate {
val generateAstCode = createGenerateAstCode(target)
val processResources = target.tasks.getByName("processResources")
processResources.dependsOn(generateAstCode)
val compileKotlin = target.tasks.getByName("compileKotlin")
compileKotlin.dependsOn(generateAstCode)
}
}
private fun createGenerateAstCode(project: Project): GenerateAstCode =
project.tasks.create("generateAstCode", GenerateAstCode::class)
private fun getAstExtension(project: Project): PorkAstExtension =
project.extensions.getByType<PorkAstExtension>()
private fun createGenerateAstCode(project: Project): Task {
val extension = getAstExtension(project)
val codegenType = extension.astCodegenType.get()
if (codegenType == AstCodegenType.Standard) {
return project.tasks.create("generateAstCode", GenerateStandardAstCode::class)
}
return project.tasks.create("generateAstCode", GeneratePorkIdeaAstCode::class)
}
}

View File

@ -0,0 +1,24 @@
package gay.pizza.pork.buildext.ast
import gay.pizza.pork.buildext.codegen.KotlinWriter
import java.nio.charset.StandardCharsets
import java.nio.file.Path
import kotlin.io.path.deleteExisting
import kotlin.io.path.deleteIfExists
import kotlin.io.path.listDirectoryEntries
import kotlin.io.path.writeText
open class AstCodegenShared(val pkg: String, val outputDirectory: Path, val world: AstWorld) {
protected fun deleteAllContents() {
for (child in outputDirectory.listDirectoryEntries("*.kt")) {
child.deleteExisting()
}
}
protected fun write(fileName: String, writer: KotlinWriter) {
val content = "// GENERATED CODE FROM PORK AST CODEGEN\n$writer"
val path = outputDirectory.resolve(fileName)
path.deleteIfExists()
path.writeText(content, StandardCharsets.UTF_8)
}
}

View File

@ -0,0 +1,164 @@
package gay.pizza.pork.buildext.ast
import gay.pizza.pork.buildext.codegen.KotlinClass
import gay.pizza.pork.buildext.codegen.KotlinFunction
import gay.pizza.pork.buildext.codegen.KotlinParameter
import gay.pizza.pork.buildext.codegen.KotlinWriter
import java.nio.file.Path
import kotlin.io.path.createDirectories
import kotlin.io.path.exists
class AstPorkIdeaCodegen(pkg: String, outputDirectory: Path, world: AstWorld) :
AstCodegenShared(pkg, outputDirectory, world) {
companion object {
fun run(pkg: String, world: AstWorld, outputDirectory: Path) {
if (!outputDirectory.exists()) {
outputDirectory.createDirectories()
}
val codegen = AstPorkIdeaCodegen(pkg, outputDirectory, world)
codegen.generate()
}
}
fun generate() {
deleteAllContents()
writePorkElement()
writeNamedElement()
for (type in world.typeRegistry.types) {
writePsiElement(type)
}
writeElementFactory()
}
fun writePorkElement() {
val baseClass = KotlinClass(
pkg,
"PorkElement",
isAbstract = true,
constructorParameters = mutableMapOf(
"node" to "ASTNode"
),
inherits = mutableListOf(
"ASTWrapperPsiElement(node)"
),
imports = mutableListOf(
"com.intellij.extapi.psi.ASTWrapperPsiElement",
"com.intellij.lang.ASTNode"
)
)
write("PorkElement.kt", KotlinWriter(baseClass))
}
fun writePsiElement(type: AstType) {
val role = world.typeRegistry.roleOfType(type)
if (role != AstTypeRole.AstNode) {
return
}
val baseType =
if (type.namedElementValue != null) "PorkNamedElement" else "PorkElement"
val kotlinClass = KotlinClass(
pkg,
"${type.name}Element",
constructorParameters = mutableMapOf(
"node" to "ASTNode"
),
inherits = mutableListOf("${baseType}(node)"),
imports = mutableListOf(
"com.intellij.lang.ASTNode"
)
)
if (baseType == "PorkNamedElement") {
kotlinClass.imports.add(0, "com.intellij.psi.PsiElement")
kotlinClass.imports.add("gay.pizza.pork.ast.NodeType")
kotlinClass.imports.add("gay.pizza.pork.idea.PorkElementTypes")
val getNameFunction = KotlinFunction(
"getName",
overridden = true,
returnType = "String?",
isImmediateExpression = true
)
getNameFunction.body.add("node.findChildByType(PorkElementTypes.elementTypeFor(NodeType.${type.name}))?.text")
kotlinClass.functions.add(getNameFunction)
val setNameFunction = KotlinFunction(
"setName",
overridden = true,
returnType = "PsiElement",
isImmediateExpression = true,
parameters = mutableListOf(
KotlinParameter("name", "String")
)
)
setNameFunction.body.add("this")
kotlinClass.functions.add(setNameFunction)
}
write("${type.name}Element.kt", KotlinWriter(kotlinClass))
}
fun writeElementFactory() {
val kotlinClass = KotlinClass(
pkg,
"PorkElementFactory",
isObject = true,
imports = mutableListOf(
"com.intellij.extapi.psi.ASTWrapperPsiElement",
"com.intellij.lang.ASTNode",
"com.intellij.psi.PsiElement",
"gay.pizza.pork.ast.NodeType",
"gay.pizza.pork.idea.PorkElementTypes"
)
)
val createFunction = KotlinFunction(
"create",
returnType = "PsiElement",
parameters = mutableListOf(
KotlinParameter("node", "ASTNode")
),
isImmediateExpression = true
)
createFunction.body.add("when (PorkElementTypes.nodeTypeFor(node.elementType)) {")
for (type in world.typeRegistry.types) {
val role = world.typeRegistry.roleOfType(type)
if (role != AstTypeRole.AstNode) {
continue
}
createFunction.body.add(" NodeType.${type.name} -> ${type.name}Element(node)")
}
createFunction.body.add(" else -> ASTWrapperPsiElement(node)")
createFunction.body.add("}")
kotlinClass.functions.add(createFunction)
write("PorkElementFactory.kt", KotlinWriter(kotlinClass))
}
fun writeNamedElement() {
val kotlinClass = KotlinClass(
pkg,
"PorkNamedElement",
isAbstract = true,
constructorParameters = mutableMapOf(
"node" to "ASTNode"
),
inherits = mutableListOf(
"PorkElement(node)",
"PsiNamedElement"
),
imports = mutableListOf(
"com.intellij.lang.ASTNode",
"com.intellij.psi.PsiNamedElement"
)
)
write("PorkNamedElement.kt", KotlinWriter(kotlinClass))
}
}

View File

@ -2,17 +2,12 @@
package gay.pizza.pork.buildext.ast
import gay.pizza.pork.buildext.codegen.*
import java.nio.charset.StandardCharsets
import java.nio.file.Path
import kotlin.io.path.*
class AstCodegen(val pkg: String, val outputDirectory: Path, val world: AstWorld) {
private fun deleteAllContents() {
for (child in outputDirectory.listDirectoryEntries("*.kt")) {
child.deleteExisting()
}
}
import kotlin.io.path.createDirectories
import kotlin.io.path.exists
class AstStandardCodegen(pkg: String, outputDirectory: Path, world: AstWorld) :
AstCodegenShared(pkg, outputDirectory, world) {
fun generate() {
deleteAllContents()
for (type in world.typeRegistry.types) {
@ -247,7 +242,7 @@ class AstCodegen(val pkg: String, val outputDirectory: Path, val world: AstWorld
val kotlinClass = KotlinClass(pkg, type.name)
kotlinClassLike = kotlinClass
if (role == AstTypeRole.RootNode || role == AstTypeRole.HierarchyNode) {
kotlinClass.sealed = true
kotlinClass.isSealed = true
}
}
@ -494,13 +489,6 @@ class AstCodegen(val pkg: String, val outputDirectory: Path, val world: AstWorld
}
}
private fun write(fileName: String, writer: KotlinWriter) {
val content = "// GENERATED CODE FROM PORK AST CODEGEN\n$writer"
val path = outputDirectory.resolve(fileName)
path.deleteIfExists()
path.writeText(content, StandardCharsets.UTF_8)
}
companion object {
private const val enableVisitAnyInline = false
@ -508,7 +496,7 @@ class AstCodegen(val pkg: String, val outputDirectory: Path, val world: AstWorld
if (!outputDirectory.exists()) {
outputDirectory.createDirectories()
}
val codegen = AstCodegen(pkg, outputDirectory, world)
val codegen = AstStandardCodegen(pkg, outputDirectory, world)
codegen.generate()
}
}

View File

@ -1,6 +1,6 @@
package gay.pizza.pork.buildext.ast
class AstType(val name: String, var parent: AstType? = null) {
class AstType(val name: String, var parent: AstType? = null, var namedElementValue: String? = null) {
private var internalValues: MutableList<AstValue>? = null
private val internalEnums = mutableListOf<AstEnum>()

View File

@ -3,5 +3,6 @@ package gay.pizza.pork.buildext.ast
data class AstTypeDescription(
val parent: String? = null,
val values: List<AstValueDescription>? = null,
val enums: List<AstEnumDescription> = emptyList()
val enums: List<AstEnumDescription> = emptyList(),
val namedElementValue: String? = null
)

View File

@ -55,6 +55,10 @@ class AstWorld {
type.parent = world.typeRegistry.lookup(typeDescription.parent)
}
if (typeDescription.namedElementValue != null) {
type.namedElementValue = typeDescription.namedElementValue
}
if (typeDescription.values != null) {
type.markHasValues()
for (value in typeDescription.values) {

View File

@ -6,7 +6,7 @@ object RunCodegenIde {
@JvmStatic
fun main(args: Array<String>) {
val world = AstWorld.read(Path("src/main/ast/pork.yml"))
AstCodegen.run(
AstStandardCodegen.run(
pkg = "gay.pizza.pork.ast",
world = world,
outputDirectory = Path("src/main/kotlin/gay/pizza/pork/ast")

View File

@ -3,12 +3,16 @@ package gay.pizza.pork.buildext.codegen
class KotlinClass(
override val pkg: String,
override var name: String,
var sealed: Boolean = false,
var isSealed: Boolean = false,
var isInterface: Boolean = false,
var isOpen: Boolean = false,
var isAbstract: Boolean = false,
var isObject: Boolean = false,
override var imports: MutableList<String> = mutableListOf(),
override var annotations: MutableList<String> = mutableListOf(),
override var typeParameters: MutableList<String> = mutableListOf(),
override var inherits: MutableList<String> = mutableListOf(),
override var members: MutableList<KotlinMember> = mutableListOf(),
override var functions: MutableList<KotlinFunction> = mutableListOf()
override var functions: MutableList<KotlinFunction> = mutableListOf(),
override var constructorParameters: MutableMap<String, String> = mutableMapOf()
) : KotlinClassLike()

View File

@ -9,4 +9,5 @@ abstract class KotlinClassLike {
abstract var inherits: MutableList<String>
abstract var members: MutableList<KotlinMember>
abstract var functions: MutableList<KotlinFunction>
abstract var constructorParameters: MutableMap<String, String>
}

View File

@ -9,5 +9,6 @@ class KotlinEnum(
override var inherits: MutableList<String> = mutableListOf(),
override var members: MutableList<KotlinMember> = mutableListOf(),
override var functions: MutableList<KotlinFunction> = mutableListOf(),
var entries: MutableList<KotlinEnumEntry> = mutableListOf()
override var constructorParameters: MutableMap<String, String> = mutableMapOf(),
var entries: MutableList<KotlinEnumEntry> = mutableListOf(),
) : KotlinClassLike()

View File

@ -8,11 +8,26 @@ class KotlinWriter() {
}
fun writeClass(kotlinClass: KotlinClass): Unit = buffer.run {
val classType = when {
kotlinClass.sealed -> "sealed class"
kotlinClass.isInterface -> "interface"
else -> "class"
val classType = buildString {
if (kotlinClass.isOpen) {
append("open ")
}
if (kotlinClass.isAbstract) {
append("abstract ")
}
if (kotlinClass.isSealed) {
append("sealed ")
}
append(when {
kotlinClass.isInterface -> "interface"
kotlinClass.isObject -> "object"
else -> "class"
})
}
writeClassLike(classType, kotlinClass)
val members = kotlinClass.members.filter {
it.abstract || (it.overridden && it.value != null) || it.notInsideConstructor
@ -136,6 +151,11 @@ class KotlinWriter() {
} else start
}
append("(${constructor})")
} else if (kotlinClass.constructorParameters.isNotEmpty()) {
val constructor = kotlinClass.constructorParameters.entries.joinToString(", ") {
"${it.key}: ${it.value}"
}
append("(${constructor})")
}
if (kotlinClass.inherits.isNotEmpty()) {

View File

@ -1,12 +1,19 @@
import gay.pizza.pork.buildext.AstCodegenType
plugins {
id("org.jetbrains.intellij") version "1.15.0"
id("gay.pizza.pork.module")
id("gay.pizza.pork.ast")
}
dependencies {
implementation(project(":parser"))
}
porkAst {
astCodegenType.set(AstCodegenType.PorkIdea)
}
intellij {
pluginName.set(properties["pluginName"].toString())
version.set(properties["platformVersion"].toString())

View File

@ -1,10 +1,7 @@
package gay.pizza.pork.idea
import com.intellij.extapi.psi.ASTWrapperPsiElement
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import gay.pizza.pork.ast.Node
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.parser.TokenType

View File

@ -9,5 +9,5 @@ class PorkFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, PorkL
return PorkFileType
}
override fun toString(): String = "Pork File"
override fun toString(): String = "Pork"
}

View File

@ -9,7 +9,7 @@ import javax.swing.Icon
@Suppress("UnstableApiUsage")
object PorkFileType : LanguageFileType(PorkLanguage) {
override fun getName(): @NonNls String {
return "Pork File"
return "Pork"
}
override fun getDescription(): @NlsContexts.Label String {

View File

@ -1,6 +1,5 @@
package gay.pizza.pork.idea
import com.intellij.extapi.psi.ASTWrapperPsiElement
import com.intellij.lang.ASTNode
import com.intellij.lang.ParserDefinition
import com.intellij.lang.PsiParser
@ -11,6 +10,8 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.tree.IFileElementType
import com.intellij.psi.tree.TokenSet
import gay.pizza.pork.idea.psi.gen.PorkElementFactory
import gay.pizza.pork.parser.TokenType
class PorkParserDefinition : ParserDefinition {
val fileElementType = IFileElementType(PorkLanguage)
@ -35,8 +36,12 @@ class PorkParserDefinition : ParserDefinition {
return PorkElementTypes.StringSet
}
override fun getWhitespaceTokens(): TokenSet {
return TokenSet.create(PorkElementTypes.elementTypeFor(TokenType.Whitespace))
}
override fun createElement(node: ASTNode): PsiElement {
return ASTWrapperPsiElement(node)
return PorkElementFactory.create(node)
}
override fun createFile(viewProvider: FileViewProvider): PsiFile {

View File

@ -28,5 +28,5 @@ class PsiBuilderTokenSource(val builder: PsiBuilder) : TokenSource {
return Token(tokenType, builder.currentOffset, builder.tokenText!!)
}
class BadCharacterError(val error: String) : RuntimeException(error)
class BadCharacterError(error: String) : RuntimeException(error)
}

View File

@ -0,0 +1,11 @@
package gay.pizza.pork.idea.psi
import gay.pizza.pork.ast.Node
import gay.pizza.pork.idea.PorkNodeKey
import gay.pizza.pork.idea.psi.gen.PorkElement
val PorkElement.porkNode: Node?
get() = node.getUserData(PorkNodeKey)
val PorkElement.porkNodeChecked: Node
get() = porkNode!!

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class BlockElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class BooleanLiteralElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class BreakElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class CompilationUnitElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class ContinueElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class DoubleLiteralElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class ForInElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class FunctionCallElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,15 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.psi.PsiElement
import com.intellij.lang.ASTNode
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.idea.PorkElementTypes
class FunctionDefinitionElement(node: ASTNode) : PorkNamedElement(node) {
override fun getName(): String? =
node.findChildByType(PorkElementTypes.elementTypeFor(NodeType.FunctionDefinition))?.text
override fun setName(name: String): PsiElement =
this
}

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class IfElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class ImportDeclarationElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class InfixOperationElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class IntegerLiteralElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,15 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.psi.PsiElement
import com.intellij.lang.ASTNode
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.idea.PorkElementTypes
class LetAssignmentElement(node: ASTNode) : PorkNamedElement(node) {
override fun getName(): String? =
node.findChildByType(PorkElementTypes.elementTypeFor(NodeType.LetAssignment))?.text
override fun setName(name: String): PsiElement =
this
}

View File

@ -0,0 +1,15 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.psi.PsiElement
import com.intellij.lang.ASTNode
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.idea.PorkElementTypes
class LetDefinitionElement(node: ASTNode) : PorkNamedElement(node) {
override fun getName(): String? =
node.findChildByType(PorkElementTypes.elementTypeFor(NodeType.LetDefinition))?.text
override fun setName(name: String): PsiElement =
this
}

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class ListLiteralElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class LongLiteralElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class NativeElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class NoneLiteralElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class ParenthesesElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,7 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.extapi.psi.ASTWrapperPsiElement
import com.intellij.lang.ASTNode
abstract class PorkElement(node: ASTNode) : ASTWrapperPsiElement(node)

View File

@ -0,0 +1,43 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.extapi.psi.ASTWrapperPsiElement
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.idea.PorkElementTypes
object PorkElementFactory {
fun create(node: ASTNode): PsiElement =
when (PorkElementTypes.nodeTypeFor(node.elementType)) {
NodeType.Symbol -> SymbolElement(node)
NodeType.Block -> BlockElement(node)
NodeType.CompilationUnit -> CompilationUnitElement(node)
NodeType.LetAssignment -> LetAssignmentElement(node)
NodeType.VarAssignment -> VarAssignmentElement(node)
NodeType.SetAssignment -> SetAssignmentElement(node)
NodeType.InfixOperation -> InfixOperationElement(node)
NodeType.BooleanLiteral -> BooleanLiteralElement(node)
NodeType.FunctionCall -> FunctionCallElement(node)
NodeType.FunctionDefinition -> FunctionDefinitionElement(node)
NodeType.LetDefinition -> LetDefinitionElement(node)
NodeType.If -> IfElement(node)
NodeType.ImportDeclaration -> ImportDeclarationElement(node)
NodeType.IntegerLiteral -> IntegerLiteralElement(node)
NodeType.LongLiteral -> LongLiteralElement(node)
NodeType.DoubleLiteral -> DoubleLiteralElement(node)
NodeType.ListLiteral -> ListLiteralElement(node)
NodeType.Parentheses -> ParenthesesElement(node)
NodeType.PrefixOperation -> PrefixOperationElement(node)
NodeType.SuffixOperation -> SuffixOperationElement(node)
NodeType.StringLiteral -> StringLiteralElement(node)
NodeType.SymbolReference -> SymbolReferenceElement(node)
NodeType.While -> WhileElement(node)
NodeType.ForIn -> ForInElement(node)
NodeType.Break -> BreakElement(node)
NodeType.Continue -> ContinueElement(node)
NodeType.NoneLiteral -> NoneLiteralElement(node)
NodeType.Native -> NativeElement(node)
else -> ASTWrapperPsiElement(node)
}
}

View File

@ -0,0 +1,7 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiNamedElement
abstract class PorkNamedElement(node: ASTNode) : PorkElement(node), PsiNamedElement

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class PrefixOperationElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,15 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.psi.PsiElement
import com.intellij.lang.ASTNode
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.idea.PorkElementTypes
class SetAssignmentElement(node: ASTNode) : PorkNamedElement(node) {
override fun getName(): String? =
node.findChildByType(PorkElementTypes.elementTypeFor(NodeType.SetAssignment))?.text
override fun setName(name: String): PsiElement =
this
}

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class StringLiteralElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class SuffixOperationElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class SymbolElement(node: ASTNode) : PorkElement(node)

View File

@ -0,0 +1,15 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.psi.PsiElement
import com.intellij.lang.ASTNode
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.idea.PorkElementTypes
class SymbolReferenceElement(node: ASTNode) : PorkNamedElement(node) {
override fun getName(): String? =
node.findChildByType(PorkElementTypes.elementTypeFor(NodeType.SymbolReference))?.text
override fun setName(name: String): PsiElement =
this
}

View File

@ -0,0 +1,15 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.psi.PsiElement
import com.intellij.lang.ASTNode
import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.idea.PorkElementTypes
class VarAssignmentElement(node: ASTNode) : PorkNamedElement(node) {
override fun getName(): String? =
node.findChildByType(PorkElementTypes.elementTypeFor(NodeType.VarAssignment))?.text
override fun setName(name: String): PsiElement =
this
}

View File

@ -0,0 +1,6 @@
// GENERATED CODE FROM PORK AST CODEGEN
package gay.pizza.pork.idea.psi.gen
import com.intellij.lang.ASTNode
class WhileElement(node: ASTNode) : PorkElement(node)

View File

@ -6,7 +6,7 @@
<vendor>Gay Pizza Specifications</vendor>
<depends>com.intellij.modules.platform</depends>
<extensions defaultExtensionNs="com.intellij">
<fileType name="Pork File" language="Pork" extensions="pork" fieldName="INSTANCE"
<fileType name="Pork" language="Pork" extensions="pork" fieldName="INSTANCE"
implementationClass="gay.pizza.pork.idea.PorkFileType"/>
<lang.syntaxHighlighterFactory
language="Pork"