Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4d21285
create `NameType` which describes what a name is referring to
The-Ray-Man Mar 27, 2026
cf38917
Added `NameType` to every `SymbolicName` except `SimpleKotlinName`
The-Ray-Man Apr 9, 2026
b1cc490
Updated `SimpleNameResolver` to produce almost identical output than …
The-Ray-Man Apr 9, 2026
5a610ac
Update expected results
The-Ray-Man Apr 9, 2026
8714b13
Every existing name will be registered now
The-Ray-Man Mar 30, 2026
66b6cec
Introduce the `NamedEntity` interface and `FreshName` interface
The-Ray-Man Apr 9, 2026
1d2c28e
Moved `PredicateKotlinName` and `HavocKotlinName` out of `KotlinName`…
The-Ray-Man Apr 9, 2026
fb1a1e3
Name reorganization and renaming
The-Ray-Man Apr 9, 2026
8528797
Removed name type `Special` as it is unused
The-Ray-Man Apr 9, 2026
8b7f427
Updated expected results
The-Ray-Man Apr 9, 2026
2c5e9d8
Renamed ScopedKotlinName to ScopedName
The-Ray-Man Apr 9, 2026
c857643
Created ``FunctionTypeName``
The-Ray-Man Apr 9, 2026
c7469bb
Make `FreshName` a sealed interface
The-Ray-Man Apr 10, 2026
01d2050
Make `NameOfType` a sealed interface
The-Ray-Man Apr 10, 2026
1d06503
Update NameResolver interface
The-Ray-Man Apr 10, 2026
74a7ea0
Moved resolve logic into resolver
The-Ray-Man Apr 10, 2026
44e405d
Implement SimpleNameResolver. It can be used static or with a cache
The-Ray-Man Apr 10, 2026
d461ba7
Removed DebugNameResolver. Use static version of SimpleNameResolver i…
The-Ray-Man Apr 10, 2026
20285f8
Removed resolver-dependent functions from SymbolicName
The-Ray-Man Apr 10, 2026
91a3404
Updated resolver to produce the same result as before
The-Ray-Man Apr 10, 2026
850a81c
Moved name decisions out of `NameType` and used enums
The-Ray-Man Apr 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import org.jetbrains.kotlin.formver.core.embeddings.properties.*
import org.jetbrains.kotlin.formver.core.embeddings.types.*
import org.jetbrains.kotlin.formver.core.names.*
import org.jetbrains.kotlin.formver.names.SimpleNameResolver
import org.jetbrains.kotlin.formver.names.debugMangled
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.ast.Method
import org.jetbrains.kotlin.formver.viper.ast.Program
import org.jetbrains.kotlin.formver.viper.debugMangled
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.ifFalse
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ package org.jetbrains.kotlin.formver.core.conversion

import org.jetbrains.kotlin.formver.core.embeddings.properties.FieldEmbedding
import org.jetbrains.kotlin.formver.core.embeddings.types.TypeEmbedding
import org.jetbrains.kotlin.formver.core.names.SpecialName
import org.jetbrains.kotlin.formver.core.names.SpecialFieldName
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.ast.Type

class SpecialField(baseName: String, override val type: TypeEmbedding, override val viperType: Type) : FieldEmbedding {
override val name: SymbolicName = SpecialName(baseName)
override val name: SymbolicName = SpecialFieldName(baseName)
override val accessPolicy: AccessPolicy = AccessPolicy.ALWAYS_WRITEABLE
override val includeInShortDump: Boolean = false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package org.jetbrains.kotlin.formver.core.domains

import org.jetbrains.kotlin.formver.core.names.PlaceholderArgumentName
import org.jetbrains.kotlin.formver.core.names.SpecialName
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.ast.BuiltinFunction
import org.jetbrains.kotlin.formver.viper.ast.Exp
import org.jetbrains.kotlin.formver.viper.ast.Type
Expand Down Expand Up @@ -38,10 +38,10 @@ class FunctionBuilder private constructor() {
get() = Exp.Result(retType)

companion object {
fun build(name: String, action: FunctionBuilder.() -> Unit): BuiltinFunction {
fun build(name: SymbolicName, action: FunctionBuilder.() -> Unit): BuiltinFunction {
val builder = FunctionBuilder()
builder.action()
return object : BuiltinFunction(SpecialName(name)) {
return object : BuiltinFunction(name) {
override val formalArgs = builder.formalArgs.map { it.decl() }
override val retType: Type = builder.retType
override val body = builder.functionBody
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.jetbrains.kotlin.formver.core.domains

import org.jetbrains.kotlin.formver.core.domains.RuntimeTypeDomain.Companion.isOf
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.ast.*
import org.jetbrains.kotlin.formver.viper.ast.Function

Expand Down Expand Up @@ -98,7 +99,7 @@ val Injection?.viperType: Type
* @param additionalConditions allows to add additional preconditions and/or postconditions
*/
class InjectionImageFunction(
name: String,
name: SymbolicName,
val original: Applicable,
argsInjections: List<Injection>,
resultInjection: Injection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbedd
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.DivIntInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.Implies
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.MulIntInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.NegInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.Not
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.RemIntInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.StringGet
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.SubCharChar
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.SubCharInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.SubIntInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.RemIntInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings.NegInt
import org.jetbrains.kotlin.formver.core.embeddings.expression.UnitLit
import org.jetbrains.kotlin.formver.core.embeddings.expression.toBlock
import org.jetbrains.kotlin.formver.core.embeddings.types.buildFunctionPretype
Expand All @@ -33,7 +33,7 @@ import org.jetbrains.kotlin.name.Name
val SpecialKotlinFunction.callableId: CallableId
get() = CallableId(FqName.fromSegments(packageName), className?.let { FqName(it) }, Name.identifier(name))

fun SpecialKotlinFunction.embedName(): ScopedKotlinName = callableId.embedFunctionName(callableType)
fun SpecialKotlinFunction.embedName(): ScopedName = callableId.embedFunctionName(callableType)

/**
* We store here all the __Kotlin__ functions that need a (fully) special `ExpEmbedding`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import org.jetbrains.kotlin.formver.core.linearization.LinearizationContext
import org.jetbrains.kotlin.formver.core.linearization.pureToViper
import org.jetbrains.kotlin.formver.core.purity.PurityContext
import org.jetbrains.kotlin.formver.names.SimpleNameResolver
import org.jetbrains.kotlin.formver.names.debugMangled
import org.jetbrains.kotlin.formver.viper.NameResolver
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.ast.Exp
import org.jetbrains.kotlin.formver.viper.ast.PermExp
import org.jetbrains.kotlin.formver.viper.ast.Stmt
import org.jetbrains.kotlin.formver.viper.debugMangled
import org.jetbrains.kotlin.formver.viper.mangled

sealed interface ExpEmbedding : DebugPrintable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import org.jetbrains.kotlin.formver.core.embeddings.types.FunctionPretypeBuilder
import org.jetbrains.kotlin.formver.core.embeddings.types.FunctionTypeEmbedding
import org.jetbrains.kotlin.formver.core.embeddings.types.buildFunctionPretype
import org.jetbrains.kotlin.formver.core.embeddings.types.injection
import org.jetbrains.kotlin.formver.core.names.DomainAssociatedFuncName
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.ast.*

/**
Expand All @@ -20,7 +22,7 @@ import org.jetbrains.kotlin.formver.viper.ast.*
* Then we should just set its signature (`(Int, Int) -> Int`) and Viper implementation (`Exp.Add`).
*/
class OperatorExpEmbeddingBuilder {
private var runtimeTypeFunctionName: String? = null
private var runtimeTypeFunctionName: SymbolicName? = null
private var viperApplicable: Applicable? = null
private var callableType: FunctionTypeEmbedding? = null
private var additionalConditions: (FunctionBuilder.() -> Unit)? = null
Expand All @@ -41,7 +43,7 @@ class OperatorExpEmbeddingBuilder {

fun setName(name: String) {
check(runtimeTypeFunctionName == null) { "Name for underlying viper function is already set." }
runtimeTypeFunctionName = name
runtimeTypeFunctionName = DomainAssociatedFuncName(name)
}

fun setSignature(signature: FunctionTypeEmbedding) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import org.jetbrains.kotlin.formver.core.embeddings.expression.IntLit
import org.jetbrains.kotlin.formver.core.embeddings.expression.OperatorExpEmbeddings
import org.jetbrains.kotlin.formver.core.embeddings.types.*
import org.jetbrains.kotlin.formver.core.names.NameMatcher
import org.jetbrains.kotlin.formver.core.names.ScopedKotlinName
import org.jetbrains.kotlin.formver.core.names.SpecialName
import org.jetbrains.kotlin.formver.core.names.ScopedName
import org.jetbrains.kotlin.formver.core.names.SpecialFieldName
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.ast.Field
import org.jetbrains.kotlin.formver.viper.ast.PermExp
Expand Down Expand Up @@ -55,7 +55,7 @@ interface FieldEmbedding {
}

class UserFieldEmbedding(
override val name: ScopedKotlinName,
override val name: ScopedName,
override val type: TypeEmbedding,
override val symbol: FirPropertySymbol,
override val isUnique: Boolean,
Expand All @@ -80,7 +80,7 @@ class UserFieldEmbedding(


object ListSizeFieldEmbedding : FieldEmbedding {
override val name = SpecialName("size")
override val name = SpecialFieldName("size")
override val type = buildType { int() }
override val viperType = Type.Ref
override val accessPolicy = AccessPolicy.ALWAYS_WRITEABLE
Expand All @@ -94,7 +94,7 @@ object ListSizeFieldEmbedding : FieldEmbedding {
}
}

fun ScopedKotlinName.specialEmbedding(embedding: ClassTypeEmbedding): FieldEmbedding? =
fun ScopedName.specialEmbedding(embedding: ClassTypeEmbedding): FieldEmbedding? =
NameMatcher.Companion.matchClassScope(this) {
ifBackingFieldName("size") {
return embedding.isCollectionInheritor.ifTrue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
package org.jetbrains.kotlin.formver.core.embeddings.types

import org.jetbrains.kotlin.formver.core.embeddings.properties.FieldEmbedding
import org.jetbrains.kotlin.formver.core.names.PredicateKotlinName
import org.jetbrains.kotlin.formver.core.names.ScopedKotlinName
import org.jetbrains.kotlin.formver.core.names.PredicateName
import org.jetbrains.kotlin.formver.core.names.ScopedName
import org.jetbrains.kotlin.formver.core.names.SimpleKotlinName
import org.jetbrains.kotlin.formver.core.names.asScope
import org.jetbrains.kotlin.formver.viper.ast.PermExp
Expand Down Expand Up @@ -78,8 +78,8 @@ class ClassEmbeddingDetails(
}
}

private val sharedPredicateName = ScopedKotlinName(type.name.asScope(), PredicateKotlinName("shared"))
private val uniquePredicateName = ScopedKotlinName(type.name.asScope(), PredicateKotlinName("unique"))
private val sharedPredicateName = ScopedName(type.name.asScope(), PredicateName("shared"))
private val uniquePredicateName = ScopedName(type.name.asScope(), PredicateName("unique"))

/**
* Find an embedding of a backing field by this name amongst the ancestors of this type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.formver.core.linearization.pureToViper
import org.jetbrains.kotlin.formver.core.names.DispatchReceiverName
import org.jetbrains.kotlin.formver.core.names.SimpleKotlinName
import org.jetbrains.kotlin.formver.viper.SymbolicName
import org.jetbrains.kotlin.formver.viper.NameResolver
import org.jetbrains.kotlin.formver.viper.ast.PermExp
import org.jetbrains.kotlin.formver.viper.ast.Predicate
import org.jetbrains.kotlin.name.Name
Expand Down Expand Up @@ -71,10 +70,6 @@ class FieldAssertionsBuilder(private val subject: VariableEmbedding, private val
val isAlwaysReadable = field.accessPolicy == AccessPolicy.ALWAYS_READABLE
val isUnique = field.isUnique

context(nameResolver: NameResolver)
val nameAsString: String
get() = field.name.name.mangledBaseName

fun forType(action: TypeInvariantsBuilder.() -> Unit) {
val builder = TypeInvariantsBuilder(field.type)
builder.action()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import org.jetbrains.kotlin.formver.core.domains.RuntimeTypeDomain
import org.jetbrains.kotlin.formver.core.embeddings.expression.ExpEmbedding
import org.jetbrains.kotlin.formver.core.linearization.pureToViper
import org.jetbrains.kotlin.formver.core.names.NameMatcher
import org.jetbrains.kotlin.formver.core.names.ScopedKotlinName
import org.jetbrains.kotlin.formver.core.names.ScopedName
import org.jetbrains.kotlin.formver.names.debugMangled
import org.jetbrains.kotlin.formver.viper.ast.DomainFunc
import org.jetbrains.kotlin.formver.viper.ast.Exp
import org.jetbrains.kotlin.formver.viper.debugMangled

// TODO: incorporate generic parameters.
data class ClassTypeEmbedding(override val name: ScopedKotlinName) : PretypeEmbedding {
data class ClassTypeEmbedding(override val name: ScopedName) : PretypeEmbedding {
private var _details: ClassEmbeddingDetails? = null
val details: ClassEmbeddingDetails
get() = _details ?: error("Details of $name have not been initialised yet.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
package org.jetbrains.kotlin.formver.core.embeddings.types

import org.jetbrains.kotlin.formver.core.domains.RuntimeTypeDomain
import org.jetbrains.kotlin.formver.core.names.SetOfNames
import org.jetbrains.kotlin.formver.core.names.FunctionTypeName
import org.jetbrains.kotlin.formver.core.names.ListOfNames
import org.jetbrains.kotlin.formver.core.names.NameOfType

data class FunctionTypeEmbedding(
val dispatchReceiverType: TypeEmbedding?,
Expand All @@ -17,7 +19,8 @@ data class FunctionTypeEmbedding(
) : PretypeEmbedding {
override val runtimeType = RuntimeTypeDomain.functionType()

override val name: SetOfNames = SetOfNames(formalArgTypes.map { it -> it.name } + listOf(returnType.name))
private val argsTypeNames = ListOfNames<NameOfType>(formalArgTypes.map { it.name })
override val name: FunctionTypeName = FunctionTypeName(argsTypeNames, returnType.name)

/**
* The flattened structure of the callable parameters: in case the callable has a receiver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

package org.jetbrains.kotlin.formver.core.embeddings.types

import org.jetbrains.kotlin.formver.core.names.ScopedKotlinName
import org.jetbrains.kotlin.formver.core.names.ScopedName

/**
* We use "pretype" to refer to types that do not contain information on nullability or
Expand Down Expand Up @@ -90,9 +90,9 @@ fun buildFunctionPretype(init: FunctionPretypeBuilder.() -> Unit): FunctionTypeE
FunctionPretypeBuilder().apply(init).complete()

class ClassPretypeBuilder : PretypeBuilder {
private var className: ScopedKotlinName? = null
private var className: ScopedName? = null

fun withName(name: ScopedKotlinName) {
fun withName(name: ScopedName) {
require(className == null) { "Class name already set" }
className = name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.formver.core.embeddings.expression.debug.PlaintextLe
import org.jetbrains.kotlin.formver.core.embeddings.expression.debug.TreeView
import org.jetbrains.kotlin.formver.core.embeddings.properties.FieldEmbedding
import org.jetbrains.kotlin.formver.core.linearization.pureToViper
import org.jetbrains.kotlin.formver.core.names.HavocKotlinName
import org.jetbrains.kotlin.formver.core.names.HavocName
import org.jetbrains.kotlin.formver.core.names.PlaceholderReturnVariableName
import org.jetbrains.kotlin.formver.core.names.TypeName
import org.jetbrains.kotlin.formver.viper.NameResolver
Expand All @@ -37,11 +37,11 @@ data class TypeEmbedding(val pretype: PretypeEmbedding, val flags: TypeEmbedding
* It may at some point necessary to make a `TypeName` hierarchy of some sort to
* represent these names, but we do it inline for now.
*/
val name: SymbolicName
val name: TypeName
get() = TypeName(pretype, flags.nullable)

val havocMethodName: SymbolicName by lazy {
HavocKotlinName(this)
HavocName(this)
}

val havocMethod: Method by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal sealed class NameMatcher(val name: SymbolicName) {
}
}

protected val scopedName = name as? ScopedKotlinName
protected val scopedName = name as? ScopedName
protected val packageName = scopedName?.scope?.packageNameIfAny
protected abstract val className: ClassKotlinName?

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

package org.jetbrains.kotlin.formver.core.names

import org.jetbrains.kotlin.formver.core.embeddings.types.TypeEmbedding
import org.jetbrains.kotlin.formver.viper.NameType
import org.jetbrains.kotlin.formver.viper.NameType.Label
import org.jetbrains.kotlin.formver.viper.SymbolicName

/* This file contains mangled names for constructs introduced during the conversion to Viper.
*
* See the NameEmbeddings file for guidelines on good name choices.
*/


sealed interface FreshName : SymbolicName

abstract class TypedFreshName(override val mangledType: NameType, val baseName: String) : FreshName {
}

/**
* Representation for names not present in the original source,
* e.g. storage for the result of subexpressions.
*/
data class AnonymousName(val n: Int) : TypedFreshName(NameType.Base.Variable, "anon$$n")

data class AnonymousBuiltinName(val n: Int) : TypedFreshName(NameType.Base.Variable, $$"anon$builtin$$$n")

/**
* Name for return variable that should *only* be used in signatures of methods without a body.
*/
data object PlaceholderReturnVariableName : TypedFreshName(NameType.Base.Variable, "ret")

data class ReturnVariableName(val n: Int) : TypedFreshName(NameType.Base.Variable, "ret$$n")

/**
* Name for return variable that should *only* be used in signatures of pure functions
* This variable will be translated into the special result variable in Viper
*/
data object FunctionResultVariableName : TypedFreshName(NameType.Base.Variable, "result")

data object DispatchReceiverName : TypedFreshName(NameType.Base.Variable, $$"this$dispatch")

data object ExtensionReceiverName : TypedFreshName(NameType.Base.Variable, $$"this$extension")

data class SpecialFieldName(val name: String) : TypedFreshName(NameType.Member.Property, name)


abstract class NumberedLabelName(override val mangledType: NameType, originalN: Int) :
TypedFreshName(mangledType, originalN.toString())

data class ReturnLabelName(val n: Int) : NumberedLabelName(Label.Return, n)
data class BreakLabelName(val n: Int) : NumberedLabelName(Label.Break, n)
data class ContinueLabelName(val n: Int) : NumberedLabelName(Label.Continue, n)
data class CatchLabelName(val n: Int) : NumberedLabelName(Label.Catch, n)
data class TryExitLabelName(val n: Int) : NumberedLabelName(Label.TryExit, n)


data class DomainAssociatedFuncName(val name: String) : TypedFreshName(NameType.Base.DomainFunction, name)

data class PlaceholderArgumentName(val n: Int) : TypedFreshName(NameType.Base.Variable, "arg$$n")

data class DomainFuncParameterName(val name: String) : TypedFreshName(NameType.Base.Variable, name)

data class SsaVariableName(val ssaIndex: Int, val baseName: SymbolicName) : FreshName {
override val mangledType: NameType
get() = NameType.Base.Variable

}

data class PredicateName(val name: String) : TypedFreshName(NameType.Base.Predicate, name)

data class HavocName(val type: TypeEmbedding) : SymbolicName {
override val mangledType: NameType
get() = NameType.Base.Havoc
}
Loading
Loading