Access a parent class for contained class in coffeescript - oop

class ChildItem
constructor : ->
#activate()
activate : ->
if parent.ready #this line will fail
console.log 'activate!'
class ParentItem
constructor : ->
#ready = true;
#child = new ChildItem()
item = new ParentItem()
How can I access item.ready from item.child.activate ? There has got to be a syntax for this!

No, there isn't a special syntax for this. If you need a relationship between a ChildItem and a ParentItem then you have to hook it up yourself; for example:
class ChildItem
constructor: (#parent) ->
#activate()
activate: ->
console.log('activate') if(#parent.ready)
class ParentItem
constructor: ->
#ready = true
#child = new ChildItem(#)
item = new ParentItem()

There's no syntax for magically accessing that unfortunately... Even something like arguments.caller wouldn't help here. However there are a couple of ways you can do it, not sure which you prefer:
1) Pass the ready argument in (or alternatively you could pass in the whole parent).
class ChildItem
constructor: (ready) ->
#activate ready
activate: (ready) ->
if ready
console.log 'activate!'
class ParentItem
constructor : ->
#ready = true
#child = new ChildItem(#ready)
item = new ParentItem()
2) Or you could use extends which would give the ChildItem access to all the properties and functions of the ParentItem:
class ParentItem
constructor : (children) ->
#ready = true
#childItems = (new ChildItem() for child in [0...children])
class ChildItem extends ParentItem
constructor: ->
super()
#activate()
activate: ->
if #ready
console.log 'activate!'
item = new ParentItem(1)

Related

Need to check sub class (of Class type) if it inherits from super class, using custom Detector via method visitCallExpression(UCallExpression)

I have created my own lint Detector.visitCallExpression(UCallExpression) and I need to find a way to check if a MyClass class parameter passed into a method call is a child of MyParent class?
//Example having this below code somewhere to be Lint scanned.
someObject.method(MyClass.class)
How can I determine MyClass.class inherits from MyParent class?
//Using the IntelliJ InheritanceUtil utility class
//Converts argument of MyClass.class -> psiClass
InheritanceUtil.isInheritor(psiClass, "com.somePackage.MyParent")
The PsiClass I get from the MyClass.class parameter, is resolved to the base java.lang.Class object, so the InheritanceUtil check always return false~
Anyway i found the solution
/**
* Detects if a Class<?> => PsiClass:Class<?> is a subclass of a PsiClass(?)
*
* #param type The PsiType object that is a PsiClass of the class to be checked for subclass
* #param compareToParentCanonicalClass The Class canonical name to be compared as a super/parent class
*
* #return true if the PsiType is a subclass of compareToParentCanonicalClass, false otherwise
*/
open fun isPsiTypeSubClassOfParentClassType(type: PsiType, compareToParentCanonicalClass: String): Boolean {
println("superClass checking:$type")
var psiClss = PsiTypesUtil.getPsiClass(type)
val pct = type as PsiClassType
val psiTypes: List<PsiType> = ArrayList<PsiType>(pct.resolveGenerics().substitutor.substitutionMap.values)
for (i in psiTypes.indices) {
println("canonical:"+ psiTypes[i].canonicalText)
var psiClass = psiClss?.let { JavaPsiFacade.getInstance(it.project).findClass(psiTypes[i].canonicalText, psiClss.resolveScope) }
return InheritanceUtil.isInheritor(psiClass, compareToParentCanonicalClass)
}
return false;
}

Kotlin Inheritance - Create child instance using parent contructor

Considering the the parent class:
abstract class Parent(
val arg1: TypeArg1 = defValue,
val arg2: TypeArg2 = defValue,
....
)
and
class Child : Parent()
Is there anyway in Kotlin to create a Child instance using Parent constructor? Like:
val child = Child(arg1, arg2)
I want to avoid doing the proxy like:
class Child(
val arg1: TypeArg1 = defValue,
val arg2: TypeArg2 = defValue,
) : Parent(arg1, arg2)
I inherit Parent in many classes and doing a such a declaration of Child constructor is really unnecessary.
Is there any way to avoid this and just create the instance of child using its parent construcor.
The language doesn't have an automated way, but IntelliJ IDEA can auto-generate it for you.
Type
class Child: Parent()
and then press Alt + Enter and it will give the option to Add constructor parameter(s) ___....

Kotlin and constructors, initializing

Sorry for asking a very newbie Kotlin question, but I'm struggling to understand some of the things related to constructors and intitializing.
I have this class and constructor:
class TestCaseBuilder constructor(
caseTag: String = "Case",
applType: Buy.ApplFor = Buy.ApplFor.PROOFFINANCE,
komnr: String = "5035") {
var caseTag: String = caseTag
var applType: Buy.ApplFor = applType
var komnr: String = komnr
What I'm trying to do here is to have three optional parameters in the constructors, using default values for them. The reason I'm declaring them in the class body is because I need to have access to them from the main class.
Now, this code works. No errors when I run it. But IntelliJ gives the following comment for the variables (ex.: caseTag):
Property is explicitly assigned to parameter caseTag, can be declared
directly in constructor.
What I've found when searching this is examples using an init {}, but the result I've gotten to includes initializing the variables twice, once in the constructor and then in the init {}. Which clearly isn't correct, I'd say?
What's a better what to have (or than having) optional parameters in the constructor, and then creating class variables from them?
You can declare properties directly in primary constructor. That means you can drop explicit declarations in class body:
class TestCaseBuilder constructor(
var caseTag: String = "Case",
var applType: Buy.ApplFor = Buy.ApplFor.PROOFFINANCE,
var komnr: String = "5035")
You can also drop the constructor keyword if your primary constructor does not have any annotations or visibility modifiers (defaults to public).
#JvmOverloads annotation can over load the constructor with different param size
class TestCaseBuilder #JvmOverloads constructor(
var caseTag: String = "Case",
var applType: Buy.ApplFor = Buy.ApplFor.PROOFFINANCE,
var komnr: String = "5035"
)
Then the class got three constructor with optional param
val a = TestCaseBuilder("CaseA")
val b = TestCaseBuilder("CaseB", Buy.ApplFor.SomethingElse)
val c = TestCaseBuilder("CaseB", Buy.ApplFor.SomethingElse, "1111")

Support deserialization of inheritance chained objects in kotlin with jackson

Assume we need to comply deserialization of such object inheritance structure:
open class Parent(
#JsonProperty("parent_value")
val parentValue: String = "default"
)
class Child(
#JsonProperty("child_value")
val childValue: String) : Parent()
Both parent & child object define own fields and #JsonProperty over it.
Also i have a test to check deserialization:
#Test
fun testDeserializeWithInheritance() {
val map = mapOf("child_value" to "success", "parent_value" to "success")
val jsonResult = objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(map)
println("serialized object: $jsonResult")
val deserialized: JsonConverterModuleTest.Child = objectMapper.readValue(jsonResult)
println("deserialized object: withdraw=${deserialized.childValue} parentValue = ${deserialized.parentValue}, exchangeFrom = ${deserialized.parentValue}")
assertEquals("success", deserialized.childValue)
assertEquals("success", deserialized.parentValue)
}
But a problem is the test fails with error:
serialized object: { "child_value" : "success", "parent_value" :
"success" }
org.junit.ComparisonFailure: parent value not equal:
Expected:success
Actual :default
How to deserialize the child object properly? The main goal is to not duplicate fields nor #JsonProperty annotations in child class.
I have a solution for the issue, but open to accept better one
The issue happens because annotation over constructor field is not applied to field nor getter automatically (kotlin mechanizm). Also Seems that it is not processed on deserialization of a child object.
Jackson supports annotations over field or over getter methods, so an appropriate solutions are either
open class Parent(
#get:JsonProperty("parent_value")
val parentValue: String = "default"
)
or
open class Parent(
#field:JsonProperty("parent_value")
val parentValue: String = "default"
)
With this the test completes

Kotlin: secondary constructor with this keyword

data class DisjointSetNode<T>(var parent: DisjointSetNode<T>, var data: T, var rank: Int) {
constructor(data: T): this(parent = this, data = data, rank = 0)
I was wondering why I am getting an error saying that I cannot use the this keyword in the constructor call because I have not called the superclass constructor first. There is no superclass, and I want to make itself a parent. Any ideas of how I would go about doing this?
the problem is that you can't calling this during calling another constructor by this(...). you can take a look at JLS:
It is a compile-time error for a constructor to directly or indirectly invoke itself through a series of one or more explicit constructor invocations involving this.
directly means calling this in this(...) at the first statement, e.g: this(this);.
indirectly means calling its members during call this(...), e.g:this(parent).
but you can makes the primary constructor to a secondary constructor to achieve your way, for example:
data class DisjointSetNode<T>(var data: T, var rank: Int = 0) {
var parent: DisjointSetNode<T> = this
constructor(parent: DisjointSetNode<T>, data: T) : this(data = data){
this.parent = parent
}
}
You cannot reference this in this context because it is not yet defined.
You can however move parent to outside the constructor signature. e.g.:
data class DisjointSetNode<T>(var data: T, var rank: Int = 0) {
var parent: DisjointSetNode<T> = this
}