New J2K: Add basic tree structure and visitor generation script
This commit is contained in:
committed by
Ilya Kirillov
parent
9d9dbb4c25
commit
5fd3a78dbe
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.File
|
||||
|
||||
|
||||
val JK_ROOT = File("./j2k/newSrc/org/jetbrains/kotlin/j2k/tree")
|
||||
|
||||
val JK_KT_FILE = File(JK_ROOT, "k.kt")
|
||||
val JK_JAVA_FILE = File(JK_ROOT, "j.kt")
|
||||
val JK_COMMON_FILE = File(JK_ROOT, "jk.kt")
|
||||
|
||||
|
||||
val interfaceRegex = "interface (JK[a-zA-Z]+)".toRegex()
|
||||
|
||||
|
||||
fun File.interfaceNames() =
|
||||
sequenceOf(this)
|
||||
.map { it.readText() }
|
||||
.flatMap { interfaceRegex.findAll(it) }
|
||||
.map { match -> match.groupValues[1] }
|
||||
.toList()
|
||||
|
||||
|
||||
fun String.safeVarName() = when (this) {
|
||||
"class" -> "klass"
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun genVisitors(interfaceNames: List<String>, visitorName: String, extends: String = "") {
|
||||
|
||||
val outFile = File(JK_ROOT, "$visitorName.kt")
|
||||
|
||||
outFile.writeText(buildString {
|
||||
appendln("package org.jetbrains.kotlin.j2k.tree")
|
||||
appendln()
|
||||
val extends = if (extends.isNotBlank()) ": $extends<R, D>" else ""
|
||||
appendln("interface $visitorName<R, D> $extends {")
|
||||
interfaceNames.joinTo(this, separator = "\n") { name ->
|
||||
val nameWithoutPrefix = name.removePrefix("JK")
|
||||
"""
|
||||
| fun visit$nameWithoutPrefix(${nameWithoutPrefix.decapitalize().safeVarName()}: $name, data: D): R
|
||||
""".trimMargin()
|
||||
}
|
||||
appendln()
|
||||
appendln("}")
|
||||
})
|
||||
|
||||
|
||||
val outVoidFile = File(JK_ROOT, "${visitorName}Void.kt")
|
||||
|
||||
outVoidFile.writeText(buildString {
|
||||
appendln("package org.jetbrains.kotlin.j2k.tree")
|
||||
appendln()
|
||||
val extends = if (extends.isNotBlank()) ", ${extends}Void" else ""
|
||||
appendln("interface ${visitorName}Void : $visitorName<Unit, Nothing?>$extends {")
|
||||
interfaceNames.joinTo(this, separator = "\n") { name ->
|
||||
val nameWithoutPrefix = name.removePrefix("JK")
|
||||
val argName = nameWithoutPrefix.decapitalize().safeVarName()
|
||||
val arg = "$argName: $name"
|
||||
"""
|
||||
| fun visit$nameWithoutPrefix($arg)
|
||||
| override fun visit$nameWithoutPrefix($arg, data: Nothing?) = visit$nameWithoutPrefix($argName)
|
||||
""".trimMargin()
|
||||
}
|
||||
appendln()
|
||||
appendln("}")
|
||||
})
|
||||
}
|
||||
|
||||
// JKVisitor<R,D> + Void
|
||||
genVisitors(JK_COMMON_FILE.interfaceNames(), "JKVisitor")
|
||||
genVisitors(JK_JAVA_FILE.interfaceNames(), "JKJavaVisitor", "JKVisitor")
|
||||
genVisitors(JK_KT_FILE.interfaceNames(), "JKKtVisitor", "JKVisitor")
|
||||
genVisitors(JK_JAVA_FILE.interfaceNames() + JK_KT_FILE.interfaceNames(), "JKJavaKtVisitor", "JKVisitor")
|
||||
|
||||
/* JKKtVisitor<R,D> : JKVisitor<R,D> + Void
|
||||
JKJavaVisitor<R,D> : JKVisitor<R,D> + Void
|
||||
JKJavaKtVisitor<R, D> : JKVisitor<R,D> + Void
|
||||
*/
|
||||
|
||||
//val visitNames =
|
||||
|
||||
|
||||
@@ -18,16 +18,37 @@ package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.psi.JavaElementVisitor
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiField
|
||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||
import org.jetbrains.kotlin.j2k.tree.JKElement
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassImpl
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKJavaFieldImpl
|
||||
|
||||
class JavaToJKTreeBuilder {
|
||||
|
||||
private class ElementVisitor : JavaElementVisitor()
|
||||
|
||||
fun buildTree(psi: PsiElement): Nothing {
|
||||
|
||||
private class ElementVisitor : JavaElementVisitor() {
|
||||
|
||||
var currentClass: JKClass? = null
|
||||
|
||||
override fun visitClass(aClass: PsiClass) {
|
||||
currentClass = JKClassImpl()
|
||||
super.visitClass(aClass)
|
||||
}
|
||||
|
||||
override fun visitField(field: PsiField) {
|
||||
currentClass!!.declarations.add(JKJavaFieldImpl(field.name!!))
|
||||
super.visitField(field)
|
||||
}
|
||||
}
|
||||
|
||||
fun buildTree(psi: PsiElement): JKElement? {
|
||||
assert(psi.language.`is`(JavaLanguage.INSTANCE)) { "Unable to build JK Tree using Java Visitor for language ${psi.language}" }
|
||||
val elementVisitor = ElementVisitor()
|
||||
psi.accept(elementVisitor)
|
||||
TODO("Tree output type")
|
||||
return elementVisitor.currentClass
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaKtVisitor<R, D> : JKVisitor<R, D> {
|
||||
fun visitJavaElement(javaElement: JKJavaElement, data: D): R
|
||||
fun visitJavaField(javaField: JKJavaField, data: D): R
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: D): R
|
||||
fun visitKtElement(ktElement: JKKtElement, data: D): R
|
||||
fun visitKtFun(ktFun: JKKtFun, data: D): R
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor, data: D): R
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: D): R
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaKtVisitorVoid : JKJavaKtVisitor<Unit, Nothing?>, JKVisitorVoid {
|
||||
fun visitJavaElement(javaElement: JKJavaElement)
|
||||
override fun visitJavaElement(javaElement: JKJavaElement, data: Nothing?) = visitJavaElement(javaElement)
|
||||
fun visitJavaField(javaField: JKJavaField)
|
||||
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod)
|
||||
override fun visitJavaMethod(javaMethod: JKJavaMethod, data: Nothing?) = visitJavaMethod(javaMethod)
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop)
|
||||
override fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: Nothing?) = visitJavaForLoop(javaForLoop)
|
||||
fun visitKtElement(ktElement: JKKtElement)
|
||||
override fun visitKtElement(ktElement: JKKtElement, data: Nothing?) = visitKtElement(ktElement)
|
||||
fun visitKtFun(ktFun: JKKtFun)
|
||||
override fun visitKtFun(ktFun: JKKtFun, data: Nothing?) = visitKtFun(ktFun)
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor)
|
||||
override fun visitKtConstructor(ktConstructor: JKKtConstructor, data: Nothing?) = visitKtConstructor(ktConstructor)
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor)
|
||||
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: Nothing?) = visitKtPrimaryConstructor(ktPrimaryConstructor)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaVisitor<R, D> : JKVisitor<R, D> {
|
||||
fun visitJavaElement(javaElement: JKJavaElement, data: D): R
|
||||
fun visitJavaField(javaField: JKJavaField, data: D): R
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: D): R
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaVisitorVoid : JKJavaVisitor<Unit, Nothing?>, JKVisitorVoid {
|
||||
fun visitJavaElement(javaElement: JKJavaElement)
|
||||
override fun visitJavaElement(javaElement: JKJavaElement, data: Nothing?) = visitJavaElement(javaElement)
|
||||
fun visitJavaField(javaField: JKJavaField)
|
||||
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod)
|
||||
override fun visitJavaMethod(javaMethod: JKJavaMethod, data: Nothing?) = visitJavaMethod(javaMethod)
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop)
|
||||
override fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: Nothing?) = visitJavaForLoop(javaForLoop)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKKtVisitor<R, D> : JKVisitor<R, D> {
|
||||
fun visitKtElement(ktElement: JKKtElement, data: D): R
|
||||
fun visitKtFun(ktFun: JKKtFun, data: D): R
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor, data: D): R
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: D): R
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKKtVisitorVoid : JKKtVisitor<Unit, Nothing?>, JKVisitorVoid {
|
||||
fun visitKtElement(ktElement: JKKtElement)
|
||||
override fun visitKtElement(ktElement: JKKtElement, data: Nothing?) = visitKtElement(ktElement)
|
||||
fun visitKtFun(ktFun: JKKtFun)
|
||||
override fun visitKtFun(ktFun: JKKtFun, data: Nothing?) = visitKtFun(ktFun)
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor)
|
||||
override fun visitKtConstructor(ktConstructor: JKKtConstructor, data: Nothing?) = visitKtConstructor(ktConstructor)
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor)
|
||||
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: Nothing?) = visitKtPrimaryConstructor(ktPrimaryConstructor)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKVisitor<R, D> {
|
||||
fun visitElement(element: JKElement, data: D): R
|
||||
fun visitClass(klass: JKClass, data: D): R
|
||||
fun visitMember(member: JKMember, data: D): R
|
||||
fun visitExpression(expression: JKExpression, data: D): R
|
||||
fun visitStatement(statement: JKStatement, data: D): R
|
||||
fun visitLoop(loop: JKLoop, data: D): R
|
||||
fun visitDeclaration(declaration: JKDeclaration, data: D): R
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
|
||||
fun visitElement(element: JKElement)
|
||||
override fun visitElement(element: JKElement, data: Nothing?) = visitElement(element)
|
||||
fun visitClass(klass: JKClass)
|
||||
override fun visitClass(klass: JKClass, data: Nothing?) = visitClass(klass)
|
||||
fun visitMember(member: JKMember)
|
||||
override fun visitMember(member: JKMember, data: Nothing?) = visitMember(member)
|
||||
fun visitExpression(expression: JKExpression)
|
||||
override fun visitExpression(expression: JKExpression, data: Nothing?) = visitExpression(expression)
|
||||
fun visitStatement(statement: JKStatement)
|
||||
override fun visitStatement(statement: JKStatement, data: Nothing?) = visitStatement(statement)
|
||||
fun visitLoop(loop: JKLoop)
|
||||
override fun visitLoop(loop: JKLoop, data: Nothing?) = visitLoop(loop)
|
||||
fun visitDeclaration(declaration: JKDeclaration)
|
||||
override fun visitDeclaration(declaration: JKDeclaration, data: Nothing?) = visitDeclaration(declaration)
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree.impl
|
||||
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaElement
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaField
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaVisitor
|
||||
import org.jetbrains.kotlin.j2k.tree.JKVisitor
|
||||
|
||||
abstract class JKJavaElementBase : JKJavaElement {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R {
|
||||
return if (visitor is JKJavaVisitor) {
|
||||
visitor.visitJavaElement(this, data)
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {}
|
||||
}
|
||||
|
||||
|
||||
class JKJavaFieldImpl(val name: String) : JKJavaField, JKJavaElementBase() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R {
|
||||
return if (visitor is JKJavaVisitor) {
|
||||
visitor.visitJavaField(this, data)
|
||||
}
|
||||
else {
|
||||
visitor.visitDeclaration(this, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree.impl
|
||||
|
||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||
import org.jetbrains.kotlin.j2k.tree.JKDeclaration
|
||||
import org.jetbrains.kotlin.j2k.tree.JKElement
|
||||
import org.jetbrains.kotlin.j2k.tree.JKVisitor
|
||||
|
||||
abstract class JKElementBase : JKElement {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitElement(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {}
|
||||
}
|
||||
|
||||
class JKClassImpl : JKClass, JKElementBase() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClass(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
|
||||
declarations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override val declarations = mutableListOf<JKDeclaration>()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree.impl
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaElement : JKElement
|
||||
|
||||
interface JKJavaField : JKJavaElement, JKDeclaration, JKMember
|
||||
|
||||
interface JKJavaMethod : JKJavaElement, JKDeclaration, JKMember
|
||||
|
||||
interface JKJavaForLoop : JKJavaElement, JKLoop
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
|
||||
interface JKElement {
|
||||
fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R
|
||||
|
||||
fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D)
|
||||
}
|
||||
|
||||
interface JKClass : JKElement {
|
||||
val declarations: MutableList<JKDeclaration>
|
||||
}
|
||||
|
||||
interface JKMember : JKElement
|
||||
|
||||
interface JKExpression : JKElement
|
||||
|
||||
interface JKStatement : JKElement
|
||||
|
||||
interface JKLoop : JKStatement
|
||||
|
||||
interface JKDeclaration : JKElement
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKKtElement: JKElement
|
||||
|
||||
interface JKKtFun: JKKtElement, JKDeclaration
|
||||
|
||||
interface JKKtConstructor: JKKtElement, JKDeclaration
|
||||
|
||||
interface JKKtPrimaryConstructor: JKKtElement, JKKtConstructor
|
||||
Reference in New Issue
Block a user