-
Notifications
You must be signed in to change notification settings - Fork 46
Generics in Kotlin codegen (#88) #720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a35be48
to
a456874
Compare
47fb89f
to
b2ed51f
Compare
...rc/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgCallableAccessManager.kt
Outdated
Show resolved
Hide resolved
@@ -760,8 +930,7 @@ open class ClassId @JvmOverloads constructor( | |||
open val allConstructors: Sequence<ConstructorId> | |||
get() = jClass.declaredConstructors.asSequence().map { it.executableId } | |||
|
|||
open val typeParameters: TypeParameters | |||
get() = TypeParameters() | |||
open val typeParameters: TypeParameters = TypeParameters() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write a comment about issues with reusing ClassIds for different models.
caller[executable](*args.toTypedArray()) | ||
caller[executable]( | ||
*args.toTypedArray(), | ||
typeParameters = executable.returnType.typeParameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xD
@@ -692,6 +692,7 @@ internal abstract class CgAbstractRenderer(val context: CgContext, val printer: | |||
|
|||
override fun toString(): String = printer.toString() | |||
|
|||
protected abstract fun <T: Import> reorderImports(imports: List<T>): List<T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain, please, for what purpose?
utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/visitor/CgKotlinRenderer.kt
Outdated
Show resolved
Hide resolved
b2ed51f
to
af60704
Compare
else -> { | ||
// we cannot access kClass for BuiltinClassId | ||
// we cannot use simple name here because this class can be not imported | ||
if (id is BuiltinClassId) id.name else id.kClass.id.asString() | ||
var main = builtInNameOrNull(id) ?: if (id is BuiltinClassId) id.name else id.kClass.id.asString() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rewrite it with buildString { ... }
@@ -821,8 +821,8 @@ internal fun CgContextOwner.importUtilMethodDependencies(id: MethodId) { | |||
for (classId in outerMostTestClass.regularImportsByUtilMethod(id, codegenLanguage)) { | |||
importIfNeeded(classId) | |||
} | |||
for (methodId in outerMostTestClass.staticImportsByUtilMethod(id)) { | |||
collectedImports += StaticImport(methodId.classId.canonicalName, methodId.name) | |||
for (methodId in currentTestClass.staticImportsByUtilMethod(id)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
}.map { processGenerics(it, engine.methodUnderTest.callable) } | ||
} | ||
|
||
private fun processGenericsForEnvironmentModels(models: EnvironmentModels, callable: KCallable<*>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe move it to another file?
} | ||
} | ||
|
||
private fun processGenerics(result: UtResult, callable: KCallable<*>): UtResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same
override fun processGenerics(type: KType) { | ||
classId.typeParameters.fromType(type) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add TODO on propagating generics into fields and mocks.
@@ -505,6 +531,150 @@ data class UtAssembleModel( | |||
val finalInstantiationModel | |||
get() = instantiationChain.lastOrNull() | |||
|
|||
private fun TypeTree.cmp(other: TypeTree): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to another module
|
||
class WildcardTypeParameter : TypeParameters(emptyList()) | ||
class WildcardTypeParameter: ClassId("org.utbot.framework.plugin.api.WildcardTypeParameter") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not Object?
// TODO might cause problems with type params when program synthesis comes | ||
// assume that last statement is constructor call | ||
instantiationChain.lastOrNull()?.let inst@ { lastStatement -> | ||
(lastStatement as? UtExecutableCallModel)?.let { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add explicit identifier for it
} | ||
|
||
it.params.mapIndexed { i, param -> | ||
function?.parameters?.getOrNull(i)?.type?.let { it1 -> param.processGenerics(it1) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it1
} | ||
is Method -> { | ||
try { | ||
val f = Method::class.java.getDeclaredField("signature") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to ReflectionUtil.kt
parsedSignature.parameterTypes.forEachIndexed { paramId, param -> | ||
if (param::class != parsedSignature.returnType::class) return@forEachIndexed | ||
|
||
param as? TypeArgument ?: error("Only TypeArgument is expected") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
// check if parameter types are equal to return types | ||
// e.g. <T:Ljava/lang/Object;>(Ljava/util/List<TT;>;)Ljava/util/List<TT;>; | ||
parsedSignature.parameterTypes.forEachIndexed { paramId, param -> | ||
if (param::class != parsedSignature.returnType::class) return@forEachIndexed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
} | ||
} | ||
|
||
for (model in modificationsChain) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe mark it as hack?
39d0e5f
to
3fabd2b
Compare
Refactored imports to support kotlin builtins (List, Map, e.t.c). Added generics propagation using callables. Added filling generics with Any? and *. Reworked Kotlin type render. Fixed assemble model generation in concrete. Fixed bug with backticks.
3fabd2b
to
5900dc3
Compare
We need to refactor our type system to safely support generic types. Now the have very implicit and error prone realization. |
Description
Refactored imports to support kotlin builtins (List, Map, e.t.c).
Added generics propagation using callables.
Added filling generics with Any? and *.
Reworked Kotlin type render.
Fixed assemble model generation in concrete.
Fixed bug with backticks.
Fixes #88
Slides
Type of Change
Please delete options that are not relevant.
How Has This Been Tested?
Automated Testing
All previously disabled tests for Kotlin compilation.
Manual Scenario
Not applicable.
Checklist (remove irrelevant options):
This is the author self-check list