Skip to content

Commit

Permalink
feat: SelectorExpression
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Feb 11, 2025
1 parent b6220ff commit 3690c2b
Show file tree
Hide file tree
Showing 48 changed files with 2,147 additions and 1,671 deletions.
28 changes: 18 additions & 10 deletions selector/src/commonMain/kotlin/li/songe/selector/Exception.kt
Original file line number Diff line number Diff line change
@@ -1,55 +1,63 @@
package li.songe.selector

import li.songe.selector.property.BinaryExpression
import li.songe.selector.property.ValueExpression
import kotlin.js.JsExport

@JsExport
sealed class SelectorCheckException(override val message: String) : Exception(message)
sealed class GkdException(override val message: String) : Exception(message)

@JsExport
data class SyntaxException(override val message: String) : GkdException(message)

@JsExport
sealed class TypeException(override val message: String) : GkdException(message)

@JsExport
data class UnknownIdentifierException(
val value: ValueExpression.Identifier,
) : SelectorCheckException("Unknown Identifier: ${value.stringify()}")
) : TypeException("Unknown Identifier: ${value.stringify()}")

@JsExport
data class UnknownMemberException(
val value: ValueExpression.MemberExpression,
) : SelectorCheckException("Unknown Member: ${value.stringify()}")
) : TypeException("Unknown Member: ${value.stringify()}")

@JsExport
data class UnknownIdentifierMethodException(
val value: ValueExpression.Identifier,
) : SelectorCheckException("Unknown Identifier Method: ${value.stringify()}")
) : TypeException("Unknown Identifier Method: ${value.stringify()}")

@JsExport
data class UnknownIdentifierMethodParamsException(
val value: ValueExpression.CallExpression,
) : SelectorCheckException("Unknown Identifier Method Params: ${value.stringify()}")
) : TypeException("Unknown Identifier Method Params: ${value.stringify()}")

@JsExport
data class UnknownMemberMethodException(
val value: ValueExpression.MemberExpression,
) : SelectorCheckException("Unknown Member Method: ${value.stringify()}")
) : TypeException("Unknown Member Method: ${value.stringify()}")

@JsExport
data class UnknownMemberMethodParamsException(
val value: ValueExpression.CallExpression,
) : SelectorCheckException("Unknown Member Method Params: ${value.stringify()}")
) : TypeException("Unknown Member Method Params: ${value.stringify()}")

@JsExport
data class MismatchParamTypeException(
val call: ValueExpression.CallExpression,
val argument: ValueExpression,
val type: PrimitiveType
) : SelectorCheckException("Mismatch Param Type: ${argument.stringify()} should be ${type.key}")
) : TypeException("Mismatch Param Type: ${argument.stringify()} should be ${type.key}")

@JsExport
data class MismatchExpressionTypeException(
val exception: BinaryExpression,
val leftType: PrimitiveType,
val rightType: PrimitiveType,
) : SelectorCheckException("Mismatch Expression Type: ${exception.stringify()}")
) : TypeException("Mismatch Expression Type: ${exception.stringify()}")

@JsExport
data class MismatchOperatorTypeException(
val exception: BinaryExpression,
) : SelectorCheckException("Mismatch Operator Type: ${exception.stringify()}")
) : TypeException("Mismatch Operator Type: ${exception.stringify()}")
13 changes: 0 additions & 13 deletions selector/src/commonMain/kotlin/li/songe/selector/Expression.kt

This file was deleted.

33 changes: 0 additions & 33 deletions selector/src/commonMain/kotlin/li/songe/selector/FastQuery.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,3 @@ sealed class FastQuery(open val value: String) : Stringify {
data class Vid(override val value: String) : FastQuery(value)
data class Text(override val value: String) : FastQuery(value)
}

internal fun getFastQueryList(segment: PropertySegment): List<FastQuery>? {
val exp = segment.expressions.firstOrNull() ?: return null
if (exp is LogicalExpression) {
if (exp.operator.value != LogicalOperator.OrOperator) return null
val expArray = exp.getSameExpressionArray() ?: return null
val list = mutableListOf<FastQuery>()
expArray.forEach { e ->
val fq = expToFastQuery(e) ?: return null
list.add(fq)
}
return list
}
if (exp is BinaryExpression) {
val fq = expToFastQuery(exp) ?: return null
return listOf(fq)
}
return null
}

private fun expToFastQuery(e: BinaryExpression): FastQuery? {
if (e.left !is ValueExpression.Identifier) return null
if (e.right !is ValueExpression.StringLiteral) return null
if (e.right.value.isEmpty()) return null
if (e.left.value == "id" && e.operator.value == CompareOperator.Equal) {
return FastQuery.Id(e.right.value)
} else if (e.left.value == "vid" && e.operator.value == CompareOperator.Equal) {
return FastQuery.Vid(e.right.value)
} else if (e.left.value == "text" && (e.operator.value == CompareOperator.Equal || e.operator.value == CompareOperator.Start || e.operator.value == CompareOperator.Include || e.operator.value == CompareOperator.End)) {
return FastQuery.Text(e.right.value)
}
return null
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import kotlin.js.JsExport

@JsExport
data class MatchOption(
val quickFind: Boolean = false,
val fastQuery: Boolean = false,
)

val defaultMatchOption = MatchOption()
) {
companion object {
val default = MatchOption()
}
}
26 changes: 0 additions & 26 deletions selector/src/commonMain/kotlin/li/songe/selector/Position.kt

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,22 @@ package li.songe.selector
import kotlin.js.JsExport

@JsExport
data class Context<T>(
data class QueryContext<T>(
val current: T,
val prev: Context<T>? = null,
val prev: QueryContext<T>? = null,
val matched: Boolean = true,
) {
fun getPrev(index: Int): Context<T>? {
@Suppress("unused")
val originalContext: QueryContext<T>
get() {
var context = this
while (context.prev != null) {
context = context.prev
}
return context
}

fun getPrev(index: Int): QueryContext<T>? {
if (index < 0) return null
var context = prev ?: return null
repeat(index) {
Expand All @@ -16,7 +27,7 @@ data class Context<T>(
return context
}

fun get(index: Int): Context<T> {
fun get(index: Int): QueryContext<T> {
if (index == 0) return this
return getPrev(index - 1) ?: throw IndexOutOfBoundsException()
}
Expand All @@ -31,12 +42,16 @@ data class Context<T>(
return list
}

@Suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST", "unused")
fun toArray(): Array<T> {
return (toList() as List<Any>).toTypedArray() as Array<T>
}

fun next(value: T): Context<T> {
return Context(value, this)
fun next(value: T): QueryContext<T> {
return QueryContext(value, this)
}

fun mismatch(): QueryContext<T> {
return copy(matched = false)
}
}
67 changes: 67 additions & 0 deletions selector/src/commonMain/kotlin/li/songe/selector/QueryResult.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package li.songe.selector

import li.songe.selector.unit.LogicalSelectorExpression
import li.songe.selector.unit.NotSelectorExpression
import li.songe.selector.unit.SelectorExpression
import li.songe.selector.unit.UnitSelectorExpression
import kotlin.js.JsExport

@JsExport
sealed class QueryResult<T> {
abstract val context: QueryContext<T>
abstract val expression: SelectorExpression
abstract val targetIndex: Int
abstract val matched: Boolean

@Suppress("unused")
val target: T
get() = context.get(targetIndex).current

data class UnitResult<T>(
override val context: QueryContext<T>,
override val expression: UnitSelectorExpression,
override val targetIndex: Int,
) : QueryResult<T>() {
override val matched: Boolean
get() = context.matched
}

data class AndResult<T>(
override val expression: LogicalSelectorExpression,
val left: QueryResult<T>,
val right: QueryResult<T>? = null,
) : QueryResult<T>() {
override val matched: Boolean
get() = left.matched && right?.matched == true
override val context: QueryContext<T>
get() = right?.context ?: error("No matched result")
override val targetIndex: Int
get() = right?.targetIndex ?: error("No matched result")
}

data class OrResult<T>(
override val expression: LogicalSelectorExpression,
val left: QueryResult<T>,
val right: QueryResult<T>? = null,
) : QueryResult<T>() {
override val matched: Boolean
get() = left.matched || right?.matched == true
override val context: QueryContext<T>
get() = (if (left.matched) left else right)?.context ?: error("No matched result")
override val targetIndex: Int
get() = (if (left.matched) left else right)?.targetIndex ?: error("No matched result")
}

data class NotResult<T>(
override val expression: NotSelectorExpression,
val originalContext: QueryContext<T>,
val result: QueryResult<T>,
) : QueryResult<T>() {
override val matched: Boolean
get() = !result.matched
override val context: QueryContext<T>
get() = originalContext
override val targetIndex: Int
get() = 0
}
}
Loading

0 comments on commit 3690c2b

Please sign in to comment.