Kotlin: Handle properties better

This commit is contained in:
Ian Lynagh
2021-11-12 14:41:33 +00:00
parent 44bf35e623
commit e6e56238c5
8 changed files with 232 additions and 17 deletions

View File

@@ -948,7 +948,8 @@ javadocText(
/** A program element that has a name. */
@element = @file | @package | @primitive | @class | @interface | @method | @constructor | @modifier | @param | @exception | @field |
@annotation | @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias;
@annotation | @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias |
@kt_property;
@modifiable = @member_modifiable| @param | @localvar ;
@@ -960,7 +961,7 @@ javadocText(
@locatable = @file | @class | @interface | @fielddecl | @field | @constructor | @method | @param | @exception
| @boundedtype | @typebound | @array | @primitive
| @import | @stmt | @expr | @whenbranch | @localvar | @javadoc | @javadocTag | @javadocText
| @xmllocatable | @ktcomment | @kt_type_alias;
| @xmllocatable | @ktcomment | @kt_type_alias | @kt_property;
@top = @element | @locatable | @folder;
@@ -1108,3 +1109,23 @@ ktExtensionFunctions(
int typeid: @type ref,
int kttypeid: @kt_type ref
)
ktProperties(
unique int id: @kt_property,
string nodeName: string ref
)
ktPropertyGetters(
unique int id: @kt_property ref,
int getter: @method ref
)
ktPropertySetters(
unique int id: @kt_property ref,
int setter: @method ref
)
ktPropertyBackingFields(
unique int id: @kt_property ref,
int backingField: @field ref
)

View File

@@ -45,6 +45,8 @@ predicate hasName(Element e, string name) {
modifiers(e, name)
or
kt_type_alias(e, name, _)
or
ktProperties(e, name)
}
/**

View File

@@ -686,6 +686,20 @@ class InstanceField extends Field {
InstanceField() { not this.isStatic() }
}
/** A Kotlin property. */
class Property extends Element, @kt_property {
/** Gets the getter method for this property, if any. */
Method getGetter() { ktPropertyGetters(this, result) }
/** Gets the setter method for this property, if any. */
Method getSetter() { ktPropertySetters(this, result) }
/** Gets the backing field for this property, if any. */
Field getBackingField() { ktPropertyBackingFields(this, result) }
override string getAPrimaryQlClass() { result = "Property" }
}
/** A Kotlin extension function. */
class ExtensionMethod extends Method {
Type extendedType;

View File

@@ -0,0 +1,20 @@
| properties.kt:2:27:2:50 | constructorProp | properties.kt:2:27:2:50 | <get-constructorProp> | file://:0:0:0:0 | <none> | properties.kt:2:27:2:50 | constructorProp |
| properties.kt:2:53:2:83 | mutableConstructorProp | properties.kt:2:53:2:83 | <get-mutableConstructorProp> | properties.kt:2:53:2:83 | <set-mutableConstructorProp> | properties.kt:2:53:2:83 | mutableConstructorProp |
| properties.kt:3:5:3:25 | modifiableInt | properties.kt:3:5:3:25 | <get-modifiableInt> | properties.kt:3:5:3:25 | <set-modifiableInt> | properties.kt:3:5:3:25 | modifiableInt |
| properties.kt:4:5:4:24 | immutableInt | properties.kt:4:5:4:24 | <get-immutableInt> | file://:0:0:0:0 | <none> | properties.kt:4:5:4:24 | immutableInt |
| properties.kt:5:5:5:26 | typedProp | properties.kt:5:5:5:26 | <get-typedProp> | file://:0:0:0:0 | <none> | properties.kt:5:5:5:26 | typedProp |
| properties.kt:6:5:6:38 | abstractTypeProp | properties.kt:6:14:6:38 | <get-abstractTypeProp> | file://:0:0:0:0 | <none> | file://:0:0:0:0 | <none> |
| properties.kt:7:5:7:30 | initialisedInInit | properties.kt:7:5:7:30 | <get-initialisedInInit> | file://:0:0:0:0 | <none> | properties.kt:7:5:7:30 | initialisedInInit |
| properties.kt:11:5:11:40 | useConstructorArg | properties.kt:11:5:11:40 | <get-useConstructorArg> | file://:0:0:0:0 | <none> | properties.kt:11:5:11:40 | useConstructorArg |
| properties.kt:12:5:13:21 | five | properties.kt:13:13:13:21 | <get-five> | file://:0:0:0:0 | <none> | file://:0:0:0:0 | <none> |
| properties.kt:14:5:15:21 | six | properties.kt:15:13:15:21 | <get-six> | file://:0:0:0:0 | <none> | file://:0:0:0:0 | <none> |
| properties.kt:16:5:18:40 | getSet | properties.kt:17:13:17:33 | <get-getSet> | properties.kt:18:13:18:40 | <set-getSet> | file://:0:0:0:0 | <none> |
| properties.kt:19:5:20:15 | defaultGetter | properties.kt:20:13:20:15 | <get-defaultGetter> | file://:0:0:0:0 | <none> | properties.kt:19:5:20:15 | defaultGetter |
| properties.kt:21:5:22:15 | varDefaultGetter | properties.kt:22:13:22:15 | <get-varDefaultGetter> | properties.kt:21:5:22:15 | <set-varDefaultGetter> | properties.kt:21:5:22:15 | varDefaultGetter |
| properties.kt:23:5:24:15 | varDefaultSetter | properties.kt:23:5:24:15 | <get-varDefaultSetter> | properties.kt:24:13:24:15 | <set-varDefaultSetter> | properties.kt:23:5:24:15 | varDefaultSetter |
| properties.kt:25:5:27:15 | varDefaultGetterSetter | properties.kt:26:13:26:15 | <get-varDefaultGetterSetter> | properties.kt:27:13:27:15 | <set-varDefaultGetterSetter> | properties.kt:25:5:27:15 | varDefaultGetterSetter |
| properties.kt:28:5:29:22 | overrideGetter | properties.kt:29:13:29:22 | <get-overrideGetter> | properties.kt:28:5:29:22 | <set-overrideGetter> | properties.kt:28:5:29:22 | overrideGetter |
| properties.kt:30:5:31:29 | overrideGetterUseField | properties.kt:31:13:31:29 | <get-overrideGetterUseField> | properties.kt:30:5:31:29 | <set-overrideGetterUseField> | properties.kt:30:5:31:29 | overrideGetterUseField |
| properties.kt:32:5:33:29 | useField | properties.kt:33:13:33:29 | <get-useField> | file://:0:0:0:0 | <none> | properties.kt:32:5:33:29 | useField |
| properties.kt:34:5:34:36 | lateInitVar | properties.kt:34:14:34:36 | <get-lateInitVar> | properties.kt:34:14:34:36 | <set-lateInitVar> | properties.kt:34:5:34:36 | lateInitVar |
| properties.kt:59:1:59:23 | constVal | properties.kt:59:7:59:23 | <get-constVal> | file://:0:0:0:0 | <none> | properties.kt:59:1:59:23 | constVal |

View File

@@ -0,0 +1,59 @@
abstract class properties(val constructorProp: Int, var mutableConstructorProp: Int, extractorArg: Int) {
var modifiableInt = 1
val immutableInt = 2
val typedProp: Int = 3
abstract val abstractTypeProp: Int
val initialisedInInit: Int
init {
initialisedInInit = 4
}
val useConstructorArg = extractorArg
val five: Int
get() = 5
val six
get() = 6
var getSet
get() = modifiableInt
set(v) { modifiableInt = v }
val defaultGetter = 7
get
var varDefaultGetter = 8
get
var varDefaultSetter = 9
set
var varDefaultGetterSetter = 10
get
set
var overrideGetter = 11
get() = 12
var overrideGetterUseField = 13
get() = field + 1
val useField = 14
get() = field + 1
lateinit var lateInitVar: String
fun useProps(): Int {
return 0 +
constructorProp +
mutableConstructorProp +
modifiableInt +
immutableInt +
typedProp +
abstractTypeProp +
initialisedInInit +
useConstructorArg +
five +
six +
getSet +
defaultGetter +
varDefaultGetter +
varDefaultSetter +
varDefaultGetterSetter +
overrideGetter +
overrideGetterUseField +
useField +
constVal
}
}
const val constVal = 15

View File

@@ -0,0 +1,48 @@
import java
newtype TMaybeElement =
TElement(Element e) or
TNoElement()
class MaybeElement extends TMaybeElement {
abstract string toString();
abstract Location getLocation();
}
class YesMaybeElement extends MaybeElement {
Element e;
YesMaybeElement() { this = TElement(e) }
override string toString() { result = e.toString() }
override Location getLocation() { result = e.getLocation() }
}
class NoMaybeElement extends MaybeElement {
NoMaybeElement() { this = TNoElement() }
override string toString() { result = "<none>" }
override Location getLocation() { none() }
}
MaybeElement getter(Property p) {
if exists(p.getGetter())
then result = TElement(p.getGetter())
else result = TNoElement()
}
MaybeElement setter(Property p) {
if exists(p.getSetter())
then result = TElement(p.getSetter())
else result = TNoElement()
}
MaybeElement backingField(Property p) {
if exists(p.getBackingField())
then result = TElement(p.getBackingField())
else result = TNoElement()
}
from Property p
where p.fromSource()
select p, getter(p), setter(p), backingField(p)