Add type alias to shorten signatures

This commit is contained in:
Clément Fournier
2019-05-22 19:55:36 +02:00
parent 8cc2c2377b
commit ee27db8c60
4 changed files with 58 additions and 48 deletions

View File

@ -1,9 +1,8 @@
package net.sourceforge.pmd.lang.java.ast
import com.github.oowekyala.treeutils.matchers.TreeNodeWrapper
import io.kotlintest.shouldBe
import net.sourceforge.pmd.lang.ast.Node
import net.sourceforge.pmd.lang.ast.test.NodeSpec
import net.sourceforge.pmd.lang.ast.test.ValuedNodeSpec
import net.sourceforge.pmd.lang.ast.test.shouldBe
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.*
@ -270,7 +269,7 @@ class ASTLiteralTest : ParserTestSpec({
inContext(ExpressionParsingCtx) {
fun hex15(type: PrimitiveType): TreeNodeWrapper<Node, *>.() -> ASTNumericLiteral = {
fun hex15(type: PrimitiveType): ValuedNodeSpec<*, ASTNumericLiteral> = {
number(type) {
it::getValueAsDouble shouldBe 15.0
it::getValueAsFloat shouldBe 15f
@ -279,21 +278,24 @@ class ASTLiteralTest : ParserTestSpec({
}
}
"0x0fl" should parseAs(hex15(LONG))
"0x0fL" should parseAs(hex15(LONG))
"0X0fl" should parseAs(hex15(LONG))
"0X0fL" should parseAs(hex15(LONG))
"0X0FL" should parseAs(hex15(LONG))
"0x0f" should parseAs(hex15(INT))
"0x0F" should parseAs(hex15(INT))
"0X0f" should parseAs(hex15(INT))
"0X0F" should parseAs(hex15(INT))
"0x0_0__0f" should parseAs(hex15(INT))
"0x0_0__0F" should parseAs(hex15(INT))
val hex15l = hex15(LONG)
val hex15i = hex15(INT)
"0x0fl" should parseAs(hex15l)
"0x0fL" should parseAs(hex15l)
"0X0fl" should parseAs(hex15l)
"0X0fL" should parseAs(hex15l)
"0X0FL" should parseAs(hex15l)
"0x0f" should parseAs(hex15i)
"0x0F" should parseAs(hex15i)
"0X0f" should parseAs(hex15i)
"0X0F" should parseAs(hex15i)
"0x0_0__0f" should parseAs(hex15i)
"0x0_0__0F" should parseAs(hex15i)
"-0X0000_000f" should parseAs {
unaryExpr(UnaryOp.UNARY_MINUS) {
hex15(INT)()
hex15i()
}
}
}

View File

@ -4,10 +4,7 @@ import com.github.oowekyala.treeutils.matchers.TreeNodeWrapper
import io.kotlintest.*
import io.kotlintest.specs.IntelliMarker
import net.sourceforge.pmd.lang.ast.Node
import net.sourceforge.pmd.lang.ast.test.Assertions
import net.sourceforge.pmd.lang.ast.test.matchNode
import net.sourceforge.pmd.lang.ast.test.numChildren
import net.sourceforge.pmd.lang.ast.test.parent
import net.sourceforge.pmd.lang.ast.test.*
import io.kotlintest.should as kotlintestShould
/**
@ -149,7 +146,7 @@ abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : AbstractSpec(),
*/
fun parse(): Matcher<String> = this@VersionedTestCtx.parseIn(nodeParsingCtx)
fun parseAs(matcher: TreeNodeWrapper<Node, *>.() -> Any): Assertions<String> = { str ->
fun parseAs(matcher: ValuedNodeSpec<Node, Any>): Assertions<String> = { str ->
val node = nodeParsingCtx.parseNode(str, this@VersionedTestCtx)
val idx = node.jjtGetChildIndex()
node.parent kotlintestShould matchNode<Node> {

View File

@ -2,6 +2,8 @@ package net.sourceforge.pmd.lang.java.ast
import com.github.oowekyala.treeutils.matchers.TreeNodeWrapper
import net.sourceforge.pmd.lang.ast.Node
import net.sourceforge.pmd.lang.ast.test.NodeSpec
import net.sourceforge.pmd.lang.ast.test.ValuedNodeSpec
import net.sourceforge.pmd.lang.ast.test.shouldBe
import net.sourceforge.pmd.lang.ast.test.shouldMatch
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.*
@ -31,18 +33,19 @@ fun String.addArticle() = when (this[0].toLowerCase()) {
else -> "a $this"
}
fun TreeNodeWrapper<Node, *>.annotation(spec: TreeNodeWrapper<Node, ASTAnnotation>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.annotation(spec: ValuedNodeSpec<ASTAnnotation, Unit> = EmptyAssertions) =
child(ignoreChildren = spec == EmptyAssertions, nodeSpec = spec)
fun TreeNodeWrapper<Node, *>.annotation(name: String, spec: TreeNodeWrapper<Node, ASTAnnotation>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.annotation(name: String, spec: NodeSpec<ASTAnnotation> = EmptyAssertions) =
child<ASTAnnotation>(ignoreChildren = spec == EmptyAssertions) {
it::getAnnotationName shouldBe name
spec()
}
fun TreeNodeWrapper<Node, *>.enumConstant(name: String, spec: TreeNodeWrapper<Node, ASTEnumConstant>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.enumConstant(name: String, spec: NodeSpec<ASTEnumConstant> = EmptyAssertions) =
child<ASTEnumConstant> {
it::getName shouldBe name
spec()
@ -54,7 +57,7 @@ fun TreeNodeWrapper<Node, *>.variableId(name: String, otherAssertions: (ASTVaria
otherAssertions(it)
}
fun TreeNodeWrapper<Node, *>.variableDeclarator(name: String, spec: TreeNodeWrapper<Node, ASTVariableDeclarator>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.variableDeclarator(name: String, spec: NodeSpec<ASTVariableDeclarator> = EmptyAssertions) =
child<ASTVariableDeclarator> {
it::getVariableId shouldBe variableId(name)
spec()
@ -66,13 +69,13 @@ fun TreeNodeWrapper<Node, *>.variableRef(name: String, otherAssertions: (ASTVari
it::getVariableName shouldBe name
otherAssertions(it)
}
fun TreeNodeWrapper<Node, *>.fieldAccess(name: String, otherAssertions: TreeNodeWrapper<Node, ASTFieldAccess>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.fieldAccess(name: String, otherAssertions: NodeSpec<ASTFieldAccess>) =
child<ASTFieldAccess> {
it::getFieldName shouldBe name
otherAssertions()
}
fun TreeNodeWrapper<Node, *>.parenthesized(inside: TreeNodeWrapper<Node, ASTParenthesizedExpression>.() -> ASTExpression) =
fun TreeNodeWrapper<Node, *>.parenthesized(inside: ValuedNodeSpec<ASTParenthesizedExpression, ASTExpression>) =
child<ASTParenthesizedExpression> {
it::getWrappedExpression shouldBe inside()
}
@ -93,16 +96,16 @@ fun TreeNodeWrapper<Node, *>.unaryExpr(op: UnaryOp, baseExpr: TreeNodeWrapper<No
}
fun TreeNodeWrapper<Node, *>.postfixExpr(op: UnaryOp, baseExpr: TreeNodeWrapper<Node, ASTPostfixExpression>.() -> ASTPrimaryExpression) =
fun TreeNodeWrapper<Node, *>.postfixExpr(op: UnaryOp, baseExpr: ValuedNodeSpec<ASTPostfixExpression, ASTPrimaryExpression>) =
child<ASTPostfixExpression> {
it::getOp shouldBe op
it::getBaseExpression shouldBe baseExpr()
}
fun TreeNodeWrapper<Node, *>.typeParamList(contents: TreeNodeWrapper<Node, ASTTypeParameters>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.typeParamList(contents: NodeSpec<ASTTypeParameters>) =
child(nodeSpec = contents)
fun TreeNodeWrapper<Node, *>.typeArgList(contents: TreeNodeWrapper<Node, ASTTypeArguments>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.typeArgList(contents: NodeSpec<ASTTypeArguments> = EmptyAssertions) =
child(ignoreChildren = contents == EmptyAssertions, nodeSpec = contents)
fun TreeNodeWrapper<Node, *>.diamond() =
@ -110,24 +113,24 @@ fun TreeNodeWrapper<Node, *>.diamond() =
it::isDiamond shouldBe true
}
fun TreeNodeWrapper<Node, *>.block(contents: TreeNodeWrapper<Node, ASTBlock>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.block(contents: NodeSpec<ASTBlock> = EmptyAssertions) =
child<ASTBlock>(ignoreChildren = contents == EmptyAssertions) {
contents()
}
fun TreeNodeWrapper<Node, *>.fieldDecl(contents: TreeNodeWrapper<Node, ASTFieldDeclaration>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.fieldDecl(contents: NodeSpec<ASTFieldDeclaration>) =
child<ASTFieldDeclaration> {
contents()
}
fun TreeNodeWrapper<Node, *>.typeParam(name: String, contents: TreeNodeWrapper<Node, ASTTypeParameter>.() -> ASTType? = { null }) =
fun TreeNodeWrapper<Node, *>.typeParam(name: String, contents: ValuedNodeSpec<ASTTypeParameter, ASTType?> = { null }) =
child<ASTTypeParameter> {
it::getParameterName shouldBe name
it::getTypeBoundNode shouldBe contents()
}
fun TreeNodeWrapper<Node, *>.classType(simpleName: String, contents: TreeNodeWrapper<Node, ASTClassOrInterfaceType>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.classType(simpleName: String, contents: NodeSpec<ASTClassOrInterfaceType> = EmptyAssertions) =
child<ASTClassOrInterfaceType>(ignoreChildren = contents == EmptyAssertions) {
it::getSimpleName shouldBe simpleName
contents()
@ -141,63 +144,63 @@ fun TreeNodeWrapper<Node, *>.primitiveType(type: ASTPrimitiveType.PrimitiveType)
}
fun TreeNodeWrapper<Node, *>.castExpr(contents: TreeNodeWrapper<Node, ASTCastExpression>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.castExpr(contents: NodeSpec<ASTCastExpression>) =
child<ASTCastExpression> {
contents()
}
fun TreeNodeWrapper<Node, *>.stringLit(image: String, contents: TreeNodeWrapper<Node, ASTStringLiteral>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.stringLit(image: String, contents: NodeSpec<ASTStringLiteral> = EmptyAssertions) =
child<ASTStringLiteral> {
it::getImage shouldBe image
contents()
}
fun TreeNodeWrapper<Node, *>.ambiguousName(image: String, contents: TreeNodeWrapper<Node, ASTAmbiguousName>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.ambiguousName(image: String, contents: NodeSpec<ASTAmbiguousName> = EmptyAssertions) =
child<ASTAmbiguousName> {
it::getImage shouldBe image
contents()
}
fun TreeNodeWrapper<Node, *>.memberValuePair(name: String, contents: TreeNodeWrapper<Node, ASTMemberValuePair>.() -> ASTMemberValue) =
fun TreeNodeWrapper<Node, *>.memberValuePair(name: String, contents: ValuedNodeSpec<ASTMemberValuePair, ASTMemberValue>) =
child<ASTMemberValuePair> {
it::getMemberName shouldBe name
it::getMemberValue shouldBe contents()
}
fun TreeNodeWrapper<Node, *>.additiveExpr(op: BinaryOp, assertions: TreeNodeWrapper<Node, ASTAdditiveExpression>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.additiveExpr(op: BinaryOp, assertions: NodeSpec<ASTAdditiveExpression>) =
child<ASTAdditiveExpression> {
it::getOp shouldBe op
assertions()
}
fun TreeNodeWrapper<Node, *>.equalityExpr(op: BinaryOp, assertions: TreeNodeWrapper<Node, ASTEqualityExpression>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.equalityExpr(op: BinaryOp, assertions: NodeSpec<ASTEqualityExpression>) =
child<ASTEqualityExpression> {
it::getOp shouldBe op
assertions()
}
fun TreeNodeWrapper<Node, *>.andExpr(assertions: TreeNodeWrapper<Node, ASTAndExpression>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.andExpr(assertions: NodeSpec<ASTAndExpression>) =
child<ASTAndExpression> {
assertions()
}
fun TreeNodeWrapper<Node, *>.multiplicativeExpr(op: BinaryOp, assertions: TreeNodeWrapper<Node, ASTMultiplicativeExpression>.() -> Unit) =
fun TreeNodeWrapper<Node, *>.multiplicativeExpr(op: BinaryOp, assertions: NodeSpec<ASTMultiplicativeExpression>) =
child<ASTMultiplicativeExpression> {
it::getOp shouldBe op
assertions()
}
private val EmptyAssertions: TreeNodeWrapper<Node, out Node>.() -> Unit = {}
private val EmptyAssertions: NodeSpec<out Node> = {}
fun TreeNodeWrapper<Node, *>.switchExpr(assertions: TreeNodeWrapper<Node, ASTSwitchExpression>.() -> Unit = EmptyAssertions): ASTSwitchExpression =
fun TreeNodeWrapper<Node, *>.switchExpr(assertions: NodeSpec<ASTSwitchExpression> = EmptyAssertions): ASTSwitchExpression =
child(ignoreChildren = assertions == EmptyAssertions) {
assertions()
}
fun TreeNodeWrapper<Node, *>.number(primitiveType: ASTPrimitiveType.PrimitiveType? = null, assertions: TreeNodeWrapper<Node, ASTNumericLiteral>.() -> Unit = EmptyAssertions) =
fun TreeNodeWrapper<Node, *>.number(primitiveType: ASTPrimitiveType.PrimitiveType? = null, assertions: NodeSpec<ASTNumericLiteral> = EmptyAssertions) =
child<ASTNumericLiteral> {
if (primitiveType != null) {
it::getPrimitiveType shouldBe primitiveType

View File

@ -20,12 +20,20 @@ object NodeTreeLikeAdapter : DoublyLinkedTreeLikeAdapter<Node> {
override fun getParent(node: Node): Node? = node.parent
}
/** A [NodeSpec] that returns a value. */
typealias ValuedNodeSpec<I, O> = TreeNodeWrapper<Node, I>.() -> O
/** A subtree matcher written in the DSL documented on [TreeNodeWrapper]. */
typealias NodeSpec<N> = TreeNodeWrapper<Node, N>.() -> Unit
typealias NodeSpec<N> = ValuedNodeSpec<N, Unit>
/** A function feedable to [io.kotlintest.should], which fails the test if an [AssertionError] is thrown. */
typealias Assertions<M> = (M) -> Unit
fun <N : Node> ValuedNodeSpec<N, *>.ignoreResult(): NodeSpec<N> {
val me = this
return { this.me() }
}
val DefaultMatchingConfig = MatchingConfig(
adapter = NodeTreeLikeAdapter,
errorPrinter = KotlintestBeanTreePrinter(NodeTreeLikeAdapter),
@ -33,8 +41,8 @@ val DefaultMatchingConfig = MatchingConfig(
)
/** A shorthand for [baseShouldMatchSubtree] providing the [NodeTreeLikeAdapter]. */
inline fun <reified N : Node> Node?.shouldMatchNode(ignoreChildren: Boolean = false, noinline nodeSpec: NodeSpec<N>) {
this.baseShouldMatchSubtree(DefaultMatchingConfig, ignoreChildren, nodeSpec)
inline fun <reified N : Node> Node?.shouldMatchNode(ignoreChildren: Boolean = false, noinline nodeSpec: ValuedNodeSpec<N, *>) {
this.baseShouldMatchSubtree(DefaultMatchingConfig, ignoreChildren, nodeSpec.ignoreResult())
}
/**
@ -55,5 +63,5 @@ inline fun <reified N : Node> Node?.shouldMatchNode(ignoreChildren: Boolean = fa
*
* @return A matcher for AST nodes, suitable for use by [io.kotlintest.should].
*/
inline fun <reified N : Node> matchNode(ignoreChildren: Boolean = false, noinline nodeSpec: NodeSpec<N>)
inline fun <reified N : Node> matchNode(ignoreChildren: Boolean = false, noinline nodeSpec: ValuedNodeSpec<N, *>)
: Assertions<Node?> = { it.shouldMatchNode(ignoreChildren, nodeSpec) }