Skip to content

Commit 723f696

Browse files
authored
Closes #188 (#189)
* Closes #188 * Closes #188 * Closes #188
1 parent 230b0b7 commit 723f696

File tree

15 files changed

+75
-64
lines changed

15 files changed

+75
-64
lines changed

.github/workflows/build.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,8 @@ jobs:
6262
echo "coverage = ${{ steps.jacoco.outputs.coverage }}"
6363
echo "branch coverage = ${{ steps.jacoco.outputs.branches }}"
6464
65-
- name: Add new badge
66-
uses: EndBug/add-and-commit@v7
67-
with:
68-
default_author: github_actions
69-
message: 'upload badge'
70-
add: '*.svg'
71-
72-
- name: Upload JaCoCo coverage report
73-
uses: actions/upload-artifact@v2
74-
with:
75-
name: jacoco-report
76-
path: build/reports/jacoco/
65+
- name: Upload coverage reports to Codecov
66+
uses: codecov/[email protected]
67+
env:
68+
token: ${{ secrets.CODECOV_TOKEN }}
69+
slug: xpathqs/core

build.gradle.kts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ group = "org.xpathqs"
2828
val kotestVersion = "5.8.0"
2929

3030
plugins {
31-
kotlin("jvm") version "1.9.22"
31+
kotlin("jvm") version "2.0.0-Beta4"
3232
id("org.jetbrains.dokka") version "1.4.32"
3333
`java-library`
3434
jacoco
3535
`maven-publish`
3636
signing
3737
id("io.codearte.nexus-staging") version "0.30.0"
38-
id("io.gitlab.arturbosch.detekt").version("1.22.0")
38+
id("io.gitlab.arturbosch.detekt").version("1.23.5")
3939
id("info.solidsoft.pitest").version("1.9.0")
4040
id("org.jetbrains.kotlinx.kover") version "0.6.1"
4141
}
@@ -62,7 +62,7 @@ detekt {
6262

6363
dependencies {
6464
implementation("io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0")
65-
implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.22")
65+
implementation("org.jetbrains.kotlin:kotlin-reflect:2.0.0-Beta4")
6666
implementation("org.yaml:snakeyaml:1.28")
6767
implementation("net.oneandone.reflections8:reflections8:0.11.7")
6868

@@ -202,3 +202,7 @@ pitest {
202202
testStrengthThreshold.set(50)
203203
coverageThreshold.set(50)
204204
}
205+
206+
detekt {
207+
208+
}

detekt.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,9 @@ potential-bugs:
485485
active: true
486486
UnreachableCatchBlock:
487487
active: true
488+
# UnreachableCode is turned off
488489
UnreachableCode:
489-
active: true
490+
active: false
490491
UnsafeCallOnNullableType:
491492
active: true
492493
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
@@ -685,7 +686,7 @@ style:
685686
UnusedPrivateClass:
686687
active: true
687688
UnusedPrivateMember:
688-
active: true
689+
active: false
689690
allowedNames: '(_|ignored|expected|serialVersionUID)'
690691
UseAnyOrNoneInsteadOfFind:
691692
active: true

readme.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
[![CI/CD](https://github.com/nachg/xpathqs-core/actions/workflows/build.yml/badge.svg)](https://github.com/nachg/xpathqs-core/actions/workflows/build.yml)
22
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.xpathqs/core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.xpathqs/core/)
33
![GitHub top language](https://img.shields.io/github/languages/top/nachg/xpathqs-core)
4-
[![Coverage](.github/badges/jacoco.svg)](jacoco.svg)
5-
4+
[![codecov](https://codecov.io/gh/xpathqs/core/graph/badge.svg?token=3YVDC15O9T)](https://codecov.io/gh/xpathqs/core)
65
[![License](https://img.shields.io/github/license/nachg/xpathqs-core)](https://github.com/nachg/xpathqs-core/blob/master/LICENSE)
76
[![EO principles respected here](https://www.elegantobjects.org/badge.svg)](https://www.elegantobjects.org)
87

src/main/kotlin/org/xpathqs/core/model/ModelAssociation.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021 XPATH-QS
2+
* Copyright (c) 2024 XPATH-QS
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -29,11 +29,12 @@ import kotlin.reflect.KProperty
2929

3030
data class ModelAssociation(
3131
val sel: BaseSelector,
32-
val field: Field
32+
val field: Field?
3333
) {
3434
constructor(sel: BaseSelector, prop: KProperty<*>) : this(sel, prop.toField())
3535

3636
fun applyTo(source: Any, extractor: ISelectorValueExtractor) {
37+
requireNotNull(field)
3738
field.set(source, extractor.apply(this))
3839
}
3940
}

src/main/kotlin/org/xpathqs/core/reflection/ReflectionExtensions.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023 XPATH-QS
2+
* Copyright (c) 2024 XPATH-QS
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -194,7 +194,7 @@ internal fun Block.setBlank(value: Boolean) {
194194
/**
195195
* Converts Kotlin Reflection property to the Java Reflection field
196196
*/
197-
internal fun KProperty<*>.toField() = this.javaField!!.apply {
197+
internal fun KProperty<*>.toField() = this.javaField?.apply {
198198
isAccessible = true
199199
}
200200

src/main/kotlin/org/xpathqs/core/reflection/SelectorParser.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023 XPATH-QS
2+
* Copyright (c) 2024 XPATH-QS
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -68,7 +68,7 @@ class SelectorParser(
6868
*/
6969
fun parse() {
7070
val baseName = if (base.name.isNotEmpty()) base.name + "." else ""
71-
val rootAnn = rootObj::class.findAnnotation<Name>()?.value ?: rootObj::class.simpleName!!
71+
val rootAnn = rootObj::class.findAnnotation<Name>()?.value ?: rootObj::class.simpleName
7272
val rootName = rootObj.name.ifEmpty { baseName + rootAnn}
7373
val rootFullName = rootObj.fullName.ifEmpty {
7474
rootObj.javaClass.`package`.name + "." + baseName + rootAnn
@@ -135,9 +135,9 @@ class SelectorParser(
135135
annotations: Collection<Annotation>
136136
) {
137137
if(base !is NullSelector) {
138-
val isNoBase = annotations.firstOrNull {
138+
val isNoBase = annotations.any {
139139
it.annotationClass.java == NoBase::class.java
140-
} != null
140+
}
141141

142142
if(!isNoBase) {
143143
val notFreeze = (to.base as? BaseSelector)?.state != SelectorState.FREEZE
@@ -166,9 +166,9 @@ class SelectorParser(
166166
}
167167
}
168168

169-
val noXpBase = annotations.firstOrNull {
169+
val noXpBase = annotations.any {
170170
it.annotationClass.java == NoXpathBase::class.java
171-
} != null
171+
}
172172

173173
if(noXpBase) {
174174
to.setNoBase(true)

src/main/kotlin/org/xpathqs/core/reflection/SelectorReflection.kt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023 XPATH-QS
2+
* Copyright (c) 2024 XPATH-QS
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -58,16 +58,11 @@ internal class SelectorReflection(
5858
}
5959

6060
fun setProp(name: String, value: Any?): SelectorReflection {
61-
val member = findField(name)
62-
63-
if (member != null) {
61+
findField(name).let { member ->
6462
member.isAccessible = true
6563
//Kotlin can't cast KProperty to KMutableProperty
6664
member.set(obj, value)
67-
} else {
68-
throw ReflectionException.NoSuchField()
6965
}
70-
7166
return this
7267
}
7368

@@ -94,7 +89,7 @@ internal class SelectorReflection(
9489
/**
9590
* Set <pre>props.args</pre> field of the [obj]
9691
*/
97-
fun setArgs(args: SelectorArgs) = BaseSelectorProps::args.toField().set(obj.props, args)
92+
fun setArgs(args: SelectorArgs) = BaseSelectorProps::args.toField()?.set(obj.props, args)
9893

9994
/**
10095
* Mark [obj] as freeze

src/main/kotlin/org/xpathqs/core/reflection/SelectorReflectionFields.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023 XPATH-QS
2+
* Copyright (c) 2024 XPATH-QS
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -45,13 +45,20 @@ class SelectorReflectionFields(
4545
* Returns collection of [BaseSelector]s inner objects of [rootObj]
4646
*/
4747
val innerSelectors: Collection<BaseSelector> by lazy {
48-
innerSelectorProps.filter {
49-
it.call(rootObj) !is NullSelector
50-
}.map {
51-
(it.call(rootObj) as BaseSelector).setName(it.name)
48+
innerSelectorProps.mapNotNull {
49+
(safeEvaluate(it) as? BaseSelector)?.setName(it.name)
5250
}
5351
}
5452

53+
private fun safeEvaluate(prop: KProperty<*>) : Any? {
54+
return runCatching {
55+
prop.call(rootObj)
56+
}.getOrNull() ?: run {
57+
runCatching {
58+
prop.call()
59+
}.getOrNull()
60+
}
61+
}
5562
/**
5663
* Returns collection of [Block]s inner objects of [rootObj]
5764
*/

src/main/kotlin/org/xpathqs/core/selector/base/AnnotationExtensions.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 XPATH-QS
2+
* Copyright (c) 2024 XPATH-QS
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to deal
@@ -30,10 +30,9 @@ import kotlin.reflect.KClass
3030
* returns true if provided annotation is present
3131
* in the selector's annotation list
3232
*/
33-
fun BaseSelector.hasAnnotation(annotation: KClass<*>)
34-
= annotations.find {
33+
fun BaseSelector.hasAnnotation(annotation: KClass<*>) = annotations.any {
3534
it.annotationClass.qualifiedName?.removeSuffix(".Container") == annotation.qualifiedName
36-
} != null
35+
}
3736

3837
/**
3938
* returns true if provided annotation is present
@@ -58,8 +57,9 @@ fun BaseSelector.hasParentAnnotation(annotation: KClass<*>)
5857
* Require #2 - when parent [org.xpathqs.core.selector.block.Block] doesn't has provided annotation - return false
5958
* @sample [org.xpathqs.core.selector.base.BaseSelectorAnnotationsTest.r2_hasParentAnnotation]
6059
*/
61-
fun BaseSelector.hasAnyParentAnnotation(annotation: KClass<*>)
62-
= this.parents.find { it.hasAnnotation(annotation) } != null
60+
fun BaseSelector.hasAnyParentAnnotation(annotation: KClass<*>) = this.parents.any {
61+
it.hasAnnotation(annotation)
62+
}
6363

6464
/**
6565
* @return provided annotation object
@@ -76,10 +76,11 @@ inline fun<reified T> BaseSelector.findAnnotation(): T? {
7676
} as? T
7777
}
7878

79+
@Suppress("UNCHECKED_CAST")
7980
inline fun<reified T> BaseSelector.findAnnotations(): Collection<T> {
8081
return annotations.filter {
8182
it.annotationClass.qualifiedName?.removeSuffix(".Container") == T::class.qualifiedName
82-
} as Collection<T>
83+
} as List<T>
8384
}
8485
/**
8586
* @return provided annotation object of parent [org.xpathqs.core.selector.block.Block]

0 commit comments

Comments
 (0)