Skip to content

Commit

Permalink
Merge pull request #17 from ty1824/indentOption
Browse files Browse the repository at this point in the history
Add option for indentation to processor. Add Kotlinter gradle plugin
  • Loading branch information
ty1824 authored Feb 20, 2023
2 parents 28d7b4d + abed158 commit 61b2acc
Show file tree
Hide file tree
Showing 62 changed files with 658 additions and 593 deletions.
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
kotlin("jvm") apply false
id("org.jetbrains.dokka")
id("org.jetbrains.kotlinx.kover")
id("org.jmailen.kotlinter")
}

/**
Expand All @@ -28,9 +29,12 @@ allprojects {
// TODO: Probably should do this before passing as a parameter
version = version.toString().drop(1)
}
if (project == rootProject) println("Using version for build: $version")
}

subprojects {
apply(plugin = "org.jmailen.kotlinter")

repositories {
mavenCentral()
}
Expand Down
32 changes: 32 additions & 0 deletions dialector-kt-processor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# dialector-kt-processor

A Kotlin Symbol Processor for dialector-kt that generates Node implementations and builders for annotated Node interfaces.

## Usage
This module provides a plugin for [Kotlin Symbol Processor](https://kotlinlang.org/docs/ksp-overview.html) that processes
annotated interfaces extending `Node` and generates implementations along with convenient builder DSLs.

Add the Kotlin Symbol Processor (KSP) plugin to your gradle build
```
plugins {
...
kotlin("jvm") version("1.7.10")
id("com.google.devtools.ksp") version("1.7.10-1.0.6") // Be sure to use a KSP version that is compatible with your Kotlin version!!
...
}
```

Add KSP configuration to set the output package for your generated code
```
ksp {
arg("dev.dialector.targetPackage", "org.example.output") // Required
arg("dev.dialector.indent", " ") // Optional, the indent pattern used for codegen. Defaults to 4 spaces.
}
```

If you are using IntelliJ, add the following to ensure your generated code is indexed & compiled.
```
sourceSets.getByName("main").java
srcDir("build/generated/ksp/main/kotlin")
}
```
6 changes: 6 additions & 0 deletions dialector-kt-processor/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ dependencies {
implementation(kotlin("reflect"))
}

kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(8))
}
}

java {
withJavadocJar()
withSourcesJar()
Expand Down
3 changes: 0 additions & 3 deletions dialector-kt-processor/readme.md

This file was deleted.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,24 @@ fun <S> Result<S, Any>.assumeSuccess(): S = when (this) {

fun KSAnnotated.findAnnotations(annotationType: KClass<out Annotation>): Sequence<KSAnnotation> =
this.annotations.filter {
it.shortName.asString() == annotationType.simpleName
&& it.annotationType.resolve().declaration.qualifiedName?.asString() == annotationType.qualifiedName
it.shortName.asString() == annotationType.simpleName &&
it.annotationType.resolve().declaration.qualifiedName?.asString() == annotationType.qualifiedName
}

fun KSAnnotated.hasAnnotation(annotationType: KClass<out Annotation>): Boolean = this.findAnnotations(annotationType).any()

fun KSClassDeclaration.isSubclassOf(superclass: KClass<out Any>): Boolean {
return this.getAllSuperTypes().any { it.declaration.qualifiedName?.asString() == superclass.qualifiedName}
return this.getAllSuperTypes().any { it.declaration.qualifiedName?.asString() == superclass.qualifiedName }
}

fun KSType.isAssignableTo(type: KSType): Boolean = type.isAssignableFrom(this)

internal fun KSDeclaration.getLocalQualifiedName(): List<String> =
if (this.parentDeclaration != null)
if (this.parentDeclaration != null) {
this.parentDeclaration!!.getLocalQualifiedName() + this.simpleName.asString()
else listOf(this.simpleName.asString())
} else {
listOf(this.simpleName.asString())
}

internal fun KSClassDeclaration.asClassName(): ClassName =
ClassName(this.packageName.asString(), this.getLocalQualifiedName())
Expand All @@ -51,15 +53,16 @@ internal fun KSType.asTypeName(): TypeName {
val declarationName = (this.declaration as KSClassDeclaration).asClassName()
val candidate = if (this.arguments.isNotEmpty()) {
declarationName.parameterizedBy(*this.arguments.map { it.type!!.resolve().asTypeName() }.toTypedArray())
} else declarationName
} else {
declarationName
}

if (this.isMarkedNullable) candidate.copy(nullable = true) else candidate
}
else if (this.declaration is KSTypeParameter) {
} else if (this.declaration is KSTypeParameter) {
val declarationName: TypeVariableName = (this.declaration as KSTypeParameter).asTypeVariableName()
if (this.isMarkedNullable) declarationName.copy(nullable = true) else declarationName
} else {
throw RuntimeException("Failed to create TypeName for ${this.toString()}")
throw RuntimeException("Failed to create TypeName for $this")
}
}

Expand All @@ -74,4 +77,4 @@ internal fun KSTypeParameter.asTypeVariableName(): TypeVariableName {
else -> null
}
)
}
}
3 changes: 3 additions & 0 deletions dialector-kt/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ dependencies {

kotlin {
explicitApiWarning()
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(8))
}
}

java {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package dev.dialector.diagnostic
import dev.dialector.semantic.SemanticModel
import dev.dialector.syntax.Node
import dev.dialector.syntax.NodeClause
import dev.dialector.semantic.type.Type
import dev.dialector.semantic.type.lattice.TypeLattice
import dev.dialector.syntax.SyntacticModel

public interface DiagnosticEvaluationContext : SyntacticModel, SemanticModel {
Expand All @@ -21,7 +19,6 @@ public interface DiagnosticRule<T : Node> {
public val isValidFor: NodeClause<T>
public val diagnostics: DiagnosticEvaluationContext.(node: T) -> Unit


public operator fun invoke(context: DiagnosticEvaluationContext, node: Node) {
@Suppress("UNCHECKED_CAST")
if (isValidFor(node)) context.diagnostics(node as T)
Expand All @@ -32,4 +29,4 @@ public infix fun <T : Node> NodeClause<T>.check(check: DiagnosticEvaluationConte
object : DiagnosticRule<T> {
override val isValidFor: NodeClause<T> = this@check
override val diagnostics: DiagnosticEvaluationContext.(node: T) -> Unit = check
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package dev.dialector.semantic

import dev.dialector.semantic.type.IdentityType
import dev.dialector.semantic.type.Type
import dev.dialector.util.DataGraph
import dev.dialector.semantic.type.inference.new.InferenceOrigin
import dev.dialector.util.DataGraph

public object InferredTopType : IdentityType("InferredTop")

Expand Down Expand Up @@ -58,6 +58,7 @@ public class VariableNode(public val variable: TypeVariable) : BoundGraphNode()
public val equivalentTo: MutableSet<Pair<BoundGraphNode, Bound>> = mutableSetOf()
public val upperBounds: MutableSet<Pair<BoundGraphNode, Bound>> = mutableSetOf()
public val lowerBounds: MutableSet<Pair<BoundGraphNode, Bound>> = mutableSetOf()

/**
* Determines whether the solution for this variable should be the greatest lower bound rather than the least upper bound.
*/
Expand Down Expand Up @@ -165,4 +166,4 @@ public class BoundGraph {

return builder.toString()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ private class BaseTypeVariable(override val id: String) : TypeVariable {
override fun toString(): String = "tv.$id"
}

private class BaseScopeVariable(override val name: String): ScopeVariable {
private class BaseScopeVariable(override val name: String) : ScopeVariable {
override fun equals(other: Any?): Boolean = this === other

override fun hashCode(): Int = super.hashCode()
Expand Down Expand Up @@ -95,6 +95,5 @@ class SampleSemanticSystem {
override fun <T : ConstraintCreator> constraint(creator: T, routine: T.() -> SemanticConstraint) {
constraints += creator.routine()
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ public object Scopes : ConstraintCreator {

public fun ScopeVariable.reference(namespace: Namespace, reference: NodeReference<out Node>): ReferenceIdentifierConstraint =
ReferenceIdentifierConstraint(this, namespace, reference)
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package dev.dialector.semantic

import dev.dialector.util.DataGraph
import dev.dialector.syntax.Node
import dev.dialector.syntax.NodeReference
import dev.dialector.util.DataGraph

public sealed class ScopeGraphNode
public class ScopeNode(public val scope: ScopeVariable) : ScopeGraphNode()
public class ReferenceNode(public val reference: NodeReference<*>): ScopeGraphNode()
public class ElementNode(public val node: Node): ScopeGraphNode()
public class ReferenceNode(public val reference: NodeReference<*>) : ScopeGraphNode()
public class ElementNode(public val node: Node) : ScopeGraphNode()

public sealed class ScopeGraphEdge

public class Declaring(public val name: String, public val namespace: Namespace?): ScopeGraphEdge()
public class Inheriting(public val label: String): ScopeGraphEdge()
public class Referencing(public val namespace: Namespace?): ScopeGraphEdge()
public class ReferencingType(public val namespace: Namespace, public val target: NodeReference<out Node>): ScopeGraphEdge()
public class Declaring(public val name: String, public val namespace: Namespace?) : ScopeGraphEdge()
public class Inheriting(public val label: String) : ScopeGraphEdge()
public class Referencing(public val namespace: Namespace?) : ScopeGraphEdge()
public class ReferencingType(public val namespace: Namespace, public val target: NodeReference<out Node>) : ScopeGraphEdge()

public class ScopeGraph {
private val graph: DataGraph<ScopeGraphNode, ScopeGraphEdge> = DataGraph()
Expand Down Expand Up @@ -65,11 +65,11 @@ public class ScopeGraph {
} else {
val referencingEdge = refNode.getEdgesOfType<Referencing>().first()
getAllDeclarations((referencingEdge.target.data as ScopeNode).scope, referencingEdge.data.namespace)
.first { (name, element) -> reference.targetIdentifier == name}
.first { (name, element) -> reference.targetIdentifier == name }
.second
}
}

public inline fun <reified T : Node> getTarget(reference: NodeReference<T>): T? =
getTargetNode(reference) as? T
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ public interface Namespace {
public val name: String
}

public class SimpleNamespace(override val name: String): Namespace

public class SimpleNamespace(override val name: String) : Namespace

/**
* A constraint indicating that a type variable's value should be assigned to the result
Expand Down Expand Up @@ -211,7 +210,6 @@ public interface ReductionRule<T : SemanticConstraint> {

public class ConstraintSolver {
public fun reduce() {

}

public fun incorporate() {}
Expand All @@ -236,11 +234,11 @@ public val redundantElimination: ReductionRule<TypeRelationConstraint> =

public val leftReduction: ReductionRule<TypeRelationConstraint> =
given<TypeRelationConstraint> { it.left is TypeVariable }.reducesTo("leftReduction") {
bound { BaseBound(it.relation, it.left as TypeVariable, it.right)}
bound { BaseBound(it.relation, it.left as TypeVariable, it.right) }
}
public val rightReduction: ReductionRule<TypeRelationConstraint> =
given<TypeRelationConstraint> { it.right is TypeVariable }.reducesTo("rightReduction") {
bound { BaseBound(it.relation.opposite(), it.right as TypeVariable, it.left)}
bound { BaseBound(it.relation.opposite(), it.right as TypeVariable, it.left) }
}

public val inheritScope: ReductionRule<InheritScopeConstraint> =
Expand All @@ -265,7 +263,6 @@ public val referenceIdentifier: ReductionRule<ReferenceIdentifierConstraint> =

public val declareTypeElement: ReductionRule<DeclareElementTypeConstraint> =
given<DeclareElementTypeConstraint>().reducesTo("declareElementType") {

}

public interface Bound {
Expand All @@ -280,7 +277,7 @@ public interface Bound {
public data class BaseBound(
override val relation: TypeRelation,
override val variable: TypeVariable,
override val boundingType: Type,
override val boundingType: Type
) : Bound

/*
Expand Down Expand Up @@ -502,4 +499,3 @@ class BaseInferenceConstraintSystem : InferenceConstraintSystem {
}
}
*/

Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package dev.dialector.semantic


interface SemanticAnalysisContext {
fun <S : SemanticSystem> getSystem(definition: SemanticSystemDefinition<S>): S

fun <A, D> query(data: SemanticDataDefinition<*, A, D>, argument: A): Query<A, D>
}
}

interface SemanticDsl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ A change to the AST results in a series of invalidations - stepping through the
*/
abstract class SemanticSystemDefinition<S : SemanticSystem> {
companion object {

}
open inner class SemanticDataDef<A, D>(query: (system: S, argument: A) -> Query<A, D>) {
val forSystem: SemanticSystemDefinition<S> = this@SemanticSystemDefinition
Expand Down Expand Up @@ -78,11 +77,10 @@ interface Query<A, D> {
fun getResult(): D
}


interface SemanticAnalysisMetaGraph {
val systems: Map<SemanticSystemDefinition<*>, SemanticSystem>

fun <S: SemanticSystem, A, D> query(data: SemanticDataDefinition<S, A, D>, argument: A): Query<A, D> {
fun <S : SemanticSystem, A, D> query(data: SemanticDataDefinition<S, A, D>, argument: A): Query<A, D> {
return data.query((systems[data.forSystem] ?: error("System implementation not found: ${data.forSystem}")) as S, argument)
}
}
Expand All @@ -95,9 +93,7 @@ data class Waiting(val on: Iterable<Query<*, *>>) : IterationResult()

object Completed : IterationResult()

interface RuleProvider {

}
interface RuleProvider

interface IterativeSolver {
fun initialize(program: Program)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import dev.dialector.syntax.Node
import dev.dialector.syntax.NodeReference
import dev.dialector.syntax.SyntacticModel

interface Scope {

}
interface Scope

/**
* Maintains semantic information relating to a [SyntacticModel]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.dialector.semantic;
package dev.dialector.semantic

import dev.dialector.syntax.Node

Expand Down Expand Up @@ -38,5 +38,4 @@ class SemanticEvaluator(val solvers: List<IterativeSolver>) {
// Allow solvers to complete
solvers.forEach { it.conclude(SemanticSolverContext()) }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public enum class VariableConstraintKind {
*/
public data class TypeVariableConstraint(
val variable: TypeVariable,
val kind: VariableConstraintKind,
val kind: VariableConstraintKind
) : SemanticConstraint

/**
Expand Down Expand Up @@ -86,4 +86,4 @@ public object Types : ConstraintCreator {
*/
public infix fun Type.supertype(type: Type): TypeRelationConstraint =
TypeRelationConstraint(TypeRelation.SUPERTYPE, this, type)
}
}
Loading

0 comments on commit 61b2acc

Please sign in to comment.