FIR: Expression typing and simple call resolver

This commit is contained in:
Simon Ogorodnik
2019-02-28 18:27:44 +03:00
parent 28873e61d4
commit 099f98f817
31 changed files with 637 additions and 117 deletions
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.fir.symbols
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
object StandardClassIds {
private val BASE_KOTLIN_PACKAGE = FqName("kotlin")
private fun String.baseId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier(this))
val Nothing = "Nothing".baseId()
val Any = "Any".baseId()
val Boolean = "Boolean".baseId()
val Char = "Char".baseId()
val Byte = "Byte".baseId()
val Short = "Short".baseId()
val Int = "Int".baseId()
val Long = "Long".baseId()
val String = "String".baseId()
val Float = "Float".baseId()
val Double = "Double".baseId()
}
@@ -109,7 +109,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver {
is FirImplicitBuiltinTypeRef -> {
resolveToSymbol(typeRef, scope, position)!!.constructType(emptyList(), isNullable = false)
}
is FirDynamicTypeRef, is FirImplicitTypeRef, is FirDelegatedTypeRef -> {
is FirDynamicTypeRef, is FirDelegatedTypeRef -> {
ConeKotlinErrorType("Not supported: ${typeRef::class.simpleName}")
}
else -> error("!")
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope
@@ -24,105 +24,4 @@ import org.jetbrains.kotlin.fir.visitors.compose
class FirAccessResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority = true) {
private lateinit var session: FirSession
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
session = file.fileSession
return withScopeCleanup {
towerScope.scopes += FirTopLevelDeclaredMemberScope(file, session)
super.transformFile(file, data)
}
}
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
return withScopeCleanup {
towerScope.scopes += regularClass.buildUseSiteScope(session)
super.transformRegularClass(regularClass, data)
}
}
private var lookupFunctions = false
private var lookupProperties = false
private inline fun <T> withNewSettings(block: () -> T): T {
val prevFunctions = lookupFunctions
val prevProperties = lookupProperties
val result = block()
lookupFunctions = prevFunctions
lookupProperties = prevProperties
return result
}
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult<FirStatement> {
return withNewSettings {
lookupFunctions = true
lookupProperties = false
super.transformFunctionCall(functionCall, data)
}
}
override fun transformQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression,
data: Nothing?
): CompositeTransformResult<FirStatement> {
return withNewSettings {
lookupProperties = true
lookupFunctions = false
super.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
}
}
override fun transformCallableReferenceAccess(
callableReferenceAccess: FirCallableReferenceAccess,
data: Nothing?
): CompositeTransformResult<FirStatement> {
return withNewSettings {
lookupProperties = true
lookupFunctions = true
super.transformCallableReferenceAccess(callableReferenceAccess, data)
}
}
override fun transformAssignment(assignment: FirAssignment, data: Nothing?): CompositeTransformResult<FirStatement> {
return withNewSettings {
lookupProperties = true
lookupFunctions = false
super.transformAssignment(assignment, data)
}
}
override fun transformNamedReference(namedReference: FirNamedReference, data: Nothing?): CompositeTransformResult<FirNamedReference> {
if (namedReference is FirResolvedCallableReference) return namedReference.compose()
val name = namedReference.name
val referents = mutableListOf<ConeCallableSymbol>()
fun collect(it: ConeCallableSymbol): ProcessorAction {
referents.add(it)
return NEXT
}
if (lookupFunctions)
towerScope.processFunctionsByName(name, ::collect)
if (lookupProperties)
towerScope.processPropertiesByName(name, ::collect)
return when (referents.size) {
0 -> FirErrorNamedReference(
session, namedReference.psi, "Unresolved name: $name"
).compose()
1 -> FirResolvedCallableReferenceImpl(
session, namedReference.psi,
name, referents.single()
).compose()
else -> FirErrorNamedReference(
session, namedReference.psi, "Ambiguity: $name, ${referents.map { it.callableId }}"
).compose()
}
}
}
}
@@ -0,0 +1,392 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.fir.resolve.transformers
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.scopes.lookupSuperTypes
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.compose
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.utils.addIfNotNull
class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>() {
val symbolProvider = session.service<FirSymbolProvider>()
override fun <E : FirElement> transformElement(element: E, data: Any?): CompositeTransformResult<E> {
@Suppress("UNCHECKED_CAST")
return (element.transformChildren(this, data) as E).compose()
}
override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Any?): CompositeTransformResult<FirTypeRef> {
if (data == null)
return implicitTypeRef.compose()
require(data is FirTypeRef)
return data.compose()
}
private fun ConeClassLikeType.buildSubstitutionScope(
useSiteSession: FirSession,
unsubstituted: FirScope,
regularClass: FirRegularClass
): FirClassSubstitutionScope? {
if (this.typeArguments.isEmpty()) return null
val substitution = regularClass.typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type
}.filter { (_, type) -> type != null }.toMap() as Map<ConeTypeParameterSymbol, ConeKotlinType>
return FirClassSubstitutionScope(useSiteSession, unsubstituted, substitution, true)
}
private fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession = session): FirClassUseSiteScope {
val superTypeScope = FirCompositeScope(mutableListOf())
val declaredScope = FirClassDeclaredMemberScope(this, useSiteSession)
lookupSuperTypes(this, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNullTo(superTypeScope.scopes) { useSiteSuperType ->
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
val symbol = useSiteSuperType.symbol
if (symbol is FirClassSymbol) {
val scope = symbol.fir.buildUseSiteScope(useSiteSession)
useSiteSuperType.buildSubstitutionScope(useSiteSession, scope, symbol.fir) ?: scope
} else {
null
}
}
return FirClassUseSiteScope(useSiteSession, superTypeScope, declaredScope, true)
}
fun ConeKotlinType.scope(useSiteSession: FirSession): FirScope {
when (this) {
is ConeClassTypeImpl -> return (this.symbol as FirBasedSymbol<FirRegularClass>).fir.buildUseSiteScope(useSiteSession)
else -> error("Failed type ${this}")
}
}
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirDeclaration> {
return withScopeCleanup {
scopes += regularClass.buildUseSiteScope()
super.transformRegularClass(regularClass, data)
}
}
protected inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
val sizeBefore = scopes.size
val result = l()
val size = scopes.size
assert(size >= sizeBefore)
repeat(size - sizeBefore) {
scopes.let { it.removeAt(it.size - 1) }
}
return result
}
val scopes = mutableListOf<FirScope>()
enum class CandidateApplicability {
HIDDEN,
PARAMETER_MAPPING_ERROR,
SYNTHETIC_RESOLVED,
RESOLVED
}
inner class ApplicabilityChecker {
var groupCounter = 0
val groupNumbers = mutableListOf<Int>()
val candidates = mutableListOf<ConeCallableSymbol>()
var currentApplicability = CandidateApplicability.HIDDEN
var expectedType: FirTypeRef? = null
var explicitReceiverType: FirTypeRef? = null
fun newDataSet() {
groupNumbers.clear()
candidates.clear()
groupCounter = 0
expectedType = null
currentApplicability = CandidateApplicability.HIDDEN
}
fun newGroup() {
groupCounter++
}
fun isSubtypeOf(superType: FirTypeRef?, subType: FirTypeRef?): Boolean {
if (superType == null && subType == null) return true
if (superType != null && subType != null) return true
return false
}
private fun getApplicability(symbol: ConeCallableSymbol): CandidateApplicability {
val declaration = (symbol as? FirBasedSymbol<FirCallableMember>)?.fir
?: return CandidateApplicability.HIDDEN
if (!isSubtypeOf(declaration.receiverTypeRef, explicitReceiverType)) return CandidateApplicability.PARAMETER_MAPPING_ERROR
return CandidateApplicability.RESOLVED
}
fun consumeCandidate(symbol: ConeCallableSymbol) {
val applicability = getApplicability(symbol)
if (applicability > currentApplicability) {
groupNumbers.clear()
candidates.clear()
currentApplicability = applicability
}
if (applicability == currentApplicability) {
candidates.add(symbol)
groupNumbers.add(groupCounter)
}
}
}
override fun transformQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression,
data: Any?
): CompositeTransformResult<FirStatement> {
qualifiedAccessExpression.explicitReceiver?.visitNoTransform(this, null)
val callee = qualifiedAccessExpression.calleeReference as? FirNamedReference ?: return qualifiedAccessExpression.compose()
with(ApplicabilityChecker()) {
expectedType = data as FirTypeRef?
explicitReceiverType = qualifiedAccessExpression.explicitReceiver?.resultType
newDataSet()
for (scope in scopes.asReversed()) {
newGroup()
val name = callee.name
scope.processPropertiesByName(name) {
consumeCandidate(symbol = it)
ProcessorAction.NEXT
}
if (currentApplicability == CandidateApplicability.RESOLVED) {
break
}
}
val result = candidates
qualifiedAccessExpression.transformCalleeReference(this@FirBodyResolveTransformer, result)
bindingContext[qualifiedAccessExpression] =
when (val newCallee = qualifiedAccessExpression.calleeReference) {
is FirErrorNamedReference ->
FirErrorTypeRefImpl(session, qualifiedAccessExpression.psi, newCallee.errorReason)
is FirResolvedCallableReference ->
(newCallee.callableSymbol as FirBasedSymbol<FirCallableMember>).fir.returnTypeRef
else -> error("WTF!")
}
}
return qualifiedAccessExpression.compose()
}
override fun transformNamedReference(namedReference: FirNamedReference, data: Any?): CompositeTransformResult<FirNamedReference> {
if (namedReference is FirResolvedCallableReference) return namedReference.compose()
val name = namedReference.name
val referents = data as? List<ConeCallableSymbol> ?: return namedReference.compose()
return when (referents.size) {
0 -> FirErrorNamedReference(
namedReference.session, namedReference.psi, "Unresolved name: $name"
).compose()
1 -> FirResolvedCallableReferenceImpl(
namedReference.session, namedReference.psi,
name, referents.single()
).compose()
else -> FirErrorNamedReference(
namedReference.session, namedReference.psi, "Ambiguity: $name, ${referents.map { it.callableId }}"
).compose()
}
}
//
// override fun transformAssignment(assignment: FirAssignment, data: Any?): CompositeTransformResult<FirStatement> {
// return withNewSettings {
// lookupProperties = true
// lookupFunctions = false
// super.transformAssignment(assignment, data)
// }
// }
//
// override fun transformNamedReference(namedReference: FirNamedReference, data: Any?): CompositeTransformResult<FirNamedReference> {
// if (namedReference is FirResolvedCallableReference) return namedReference.compose()
// val name = namedReference.name
// val referents = mutableListOf<ConeCallableSymbol>()
// fun collect(it: ConeCallableSymbol): ProcessorAction {
// referents.add(it)
// return ProcessorAction.NEXT
// }
//
// if (lookupFunctions)
// towerScope.processFunctionsByName(name, ::collect)
// if (lookupProperties)
// towerScope.processPropertiesByName(name, ::collect)
//
// return when (referents.size) {
// 0 -> FirErrorNamedReference(
// namedReference.session, namedReference.psi, "Unresolved name: $name"
// ).compose()
// 1 -> FirResolvedCallableReferenceImpl(
// namedReference.session, namedReference.psi,
// name, referents.single()
// ).compose()
// else -> FirErrorNamedReference(
// namedReference.session, namedReference.psi, "Ambiguity: $name, ${referents.map { it.callableId }}"
// ).compose()
// }
//
// }
//
// override fun transformQualifiedAccessExpression(
// qualifiedAccessExpression: FirQualifiedAccessExpression,
// data: Any?
// ): CompositeTransformResult<FirStatement> {
//
//
//
// return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data)
// }
override fun transformBlock(block: FirBlock, data: Any?): CompositeTransformResult<FirStatement> {
block.transformChildren(this, data)
val statement = block.statements.lastOrNull()
val resultExpression = when (statement) {
is FirReturnExpression -> statement.result
is FirExpression -> statement
else -> null
}
resultExpression?.resultType?.let { bindingContext[block] = it }
return super.transformBlock(block, data)
}
private fun commonSuperType(types: List<FirTypeRef>): FirTypeRef {
return types.first()
}
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): CompositeTransformResult<FirStatement> {
val type = commonSuperType(whenExpression.branches.mapNotNull {
it.result.visitNoTransform(this, data)
it.result.resultType
})
bindingContext[whenExpression] = type
return super.transformWhenExpression(whenExpression, data)
}
override fun <T> transformConstExpression(constExpression: FirConstExpression<T>, data: Any?): CompositeTransformResult<FirStatement> {
if (data == null) return constExpression.compose()
val expectedType = data as FirTypeRef
if (expectedType is FirImplicitTypeRef) {
val symbol = when (constExpression.kind) {
IrConstKind.Null -> StandardClassIds.Nothing(symbolProvider)
IrConstKind.Boolean -> StandardClassIds.Boolean(symbolProvider)
IrConstKind.Char -> StandardClassIds.Char(symbolProvider)
IrConstKind.Byte -> StandardClassIds.Byte(symbolProvider)
IrConstKind.Short -> StandardClassIds.Short(symbolProvider)
IrConstKind.Int -> StandardClassIds.Int(symbolProvider)
IrConstKind.Long -> StandardClassIds.Long(symbolProvider)
IrConstKind.String -> StandardClassIds.String(symbolProvider)
IrConstKind.Float -> StandardClassIds.Float(symbolProvider)
IrConstKind.Double -> StandardClassIds.Double(symbolProvider)
}
val type = ConeClassTypeImpl(symbol, emptyArray(), isNullable = constExpression.kind == IrConstKind.Null)
bindingContext[constExpression] = FirResolvedTypeRefImpl(session, null, type, false, emptyList())
} else {
bindingContext[constExpression] = expectedType
}
return super.transformConstExpression(constExpression, data)
}
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
val bindingContext = mutableMapOf<FirExpression, FirTypeRef>()
val FirExpression.resultType: FirTypeRef? get() = bindingContext[this]
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
return withScopeCleanup {
scopes.addIfNotNull(namedFunction.receiverTypeRef?.coneTypeSafe()?.scope(session))
val body = namedFunction.body
if (namedFunction.returnTypeRef is FirImplicitTypeRef && body != null) {
body.visitNoTransform(this, namedFunction.returnTypeRef)
namedFunction.transformReturnTypeRef(this, body.resultType)
}
super.transformNamedFunction(namedFunction, data)
}
}
override fun transformVariable(variable: FirVariable, data: Any?): CompositeTransformResult<FirDeclaration> {
val initializer = variable.initializer
initializer?.visitNoTransform(this, variable.returnTypeRef)
if (variable.returnTypeRef is FirImplicitTypeRef) {
when {
variable.delegate != null -> TODO("!?")
initializer != null -> {
variable.transformReturnTypeRef(this, initializer.resultType)
}
}
}
return super.transformVariable(variable, data)
}
override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult<FirDeclaration> {
return transformVariable(property, data)
}
private fun <D> FirElement.visitNoTransform(transformer: FirTransformer<D>, data: D) {
val result = this.transform(transformer, data)
require(result.single === this)
}
}
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
class FirBodyResolveTransformerAdapter : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return element.compose()
}
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
val transformer = FirBodyResolveTransformer(file.session)
return file.transform(transformer, null)
}
}
@@ -11,10 +11,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirResolvedFunctionTypeRefImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
@@ -59,4 +56,8 @@ class FirSpecificTypeResolverTransformer(
override fun transformResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: Nothing?): CompositeTransformResult<FirTypeRef> {
return resolvedTypeRef.compose()
}
override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Nothing?): CompositeTransformResult<FirTypeRef> {
return implicitTypeRef.compose()
}
}
@@ -15,7 +15,8 @@ class FirTotalResolveTransformer {
FirSupertypeResolverTransformer(),
FirTypeResolveTransformer(),
FirStatusResolveTransformer(),
FirAccessResolveTransformer()
FirAccessResolveTransformer(),
FirBodyResolveTransformerAdapter()
)
fun processFiles(files: List<FirFile>) {
@@ -13,8 +13,11 @@ import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.addImportingScopes
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.compose
open class FirTypeResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority = true) {
private lateinit var session: FirSession
@@ -76,6 +79,11 @@ open class FirTypeResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(
}
}
override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Nothing?): CompositeTransformResult<FirTypeRef> {
if (implicitTypeRef is FirImplicitBuiltinTypeRef) return super.transformImplicitTypeRef(implicitTypeRef, data)
return implicitTypeRef.compose()
}
override fun transformTypeRef(typeRef: FirTypeRef, data: Nothing?): CompositeTransformResult<FirTypeRef> {
return FirSpecificTypeResolverTransformer(towerScope, FirPosition.OTHER, session).transformTypeRef(typeRef, data)
}
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirNamedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
import org.jetbrains.kotlin.fir.expressions.FirVariable
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
import org.jetbrains.kotlin.name.Name
//class FirLocalScope : FirScope {
//
// val properties = mutableMapOf<Name, FirVariable>()
// val functions = mutableMapOf<Name, FirNamedFunction>()
//
// fun storeDeclaration(declaration: FirNamedDeclaration) {
// when (declaration) {
// is FirVariable -> properties[declaration.name] = declaration
// is FirNamedFunction -> functions[declaration.name] = declaration
//
// }
// }
//
// override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
// return super.processFunctionsByName(name, processor)
// }
//
// override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
// val prop = properties[name]
// if (prop != null) {
// return processor()
// }
// return ProcessorAction.NEXT
// }
//}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.fir.symbols
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.name.ClassId
val FirSymbolProvider.Any: ConeClassLikeSymbol get() = this.getClassLikeSymbolByFqName(StandardClassIds.Any)!!
val FirSymbolProvider.Nothing: ConeClassLikeSymbol get() = this.getClassLikeSymbolByFqName(StandardClassIds.Nothing)!!
operator fun ClassId.invoke(symbolProvider: FirSymbolProvider): ConeClassLikeSymbol {
return symbolProvider.getClassLikeSymbolByFqName(this)!!
}
@@ -0,0 +1,6 @@
class Foo {
val x = 1
fun abc() = x
}
@@ -0,0 +1,12 @@
FILE: access.kt
public final class Foo {
public constructor(): super<R|kotlin/Any|>()
public final property x(val): R|kotlin/Int| = Int(1)
public get(): <implicit>
public final function abc(): R|kotlin/Int| {
return@@@abc R|/Foo.x|
}
}
@@ -0,0 +1,9 @@
fun foo() {
val x = 1
}
val bar = ""
val n = null
val g: String? = null
@@ -0,0 +1,10 @@
FILE: simple.kt
public final function foo(): R|kotlin/Unit| {
val x: R|kotlin/Int| = Int(1)
}
public final property bar(val): R|kotlin/String| = String()
public get(): <implicit>
public final property n(val): R|kotlin/Nothing|? = Null(null)
public get(): <implicit>
public final property g(val): R|kotlin/String|? = Null(null)
public get(): R|kotlin/String|?
@@ -0,0 +1 @@
fun foo() = if (true) 1 else 0
@@ -0,0 +1,12 @@
FILE: when.kt
public final function foo(): R|kotlin/Int| {
return@@@foo when () {
Boolean(true) -> {
Int(1)
}
else -> {
Int(0)
}
}
}
@@ -62,8 +62,8 @@ FILE: enums.kt
public final companion object Companion {
public constructor(): super<R|kotlin/Any|>()
public final const property G(val): R|error: Not supported: FirImplicitTypeRefImpl| = Double(6.67E-11)
public get(): R|error: Not supported: FirImplicitTypeRefImpl|
public final const property G(val): R|kotlin/Double| = Double(6.67E-11)
public get(): <implicit>
}
@@ -9,8 +9,8 @@ FILE: simpleClass.kt
public final class SomeClass : R|SomeInterface| {
public constructor(): super<R|kotlin/Any|>()
private final property baz(val): R|error: Not supported: FirImplicitTypeRefImpl| = Int(42)
private get(): R|error: Not supported: FirImplicitTypeRefImpl|
private final property baz(val): R|kotlin/Int| = Int(42)
private get(): <implicit>
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
return@@@foo <Unresolved name: plus>#(<Unresolved name: plus>#(<Unresolved name: y>#, <Unresolved name: x>#), R|/SomeClass.baz|)
@@ -1,7 +1,7 @@
FILE: simple.kt
public final function foo(): R|error: Not supported: FirImplicitTypeRefImpl| {
public final function foo(): R|kotlin/Int| {
return@@@foo Int(1)
}
public final function bar(): R|error: Not supported: FirImplicitTypeRefImpl| {
public final function bar(): <implicit> {
return@@@bar R|/foo|()
}
+2 -2
View File
@@ -9,8 +9,8 @@ FILE: simpleClass.kt
public final class SomeClass : R|SomeInterface| {
public constructor(): super<R|kotlin/Any|>()
private final property baz(val): R|error: Not supported: FirImplicitTypeRefImpl| = Int(42)
private get(): R|error: Not supported: FirImplicitTypeRefImpl|
private final property baz(val): R|kotlin/Int| = Int(42)
private get(): <implicit>
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
return@@@foo <Unresolved name: plus>#(<Unresolved name: plus>#(<Unresolved name: y>#, <Unresolved name: x>#), R|/SomeClass.baz|)
@@ -142,6 +142,34 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/expresssions")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Expresssions extends AbstractFirResolveTestCase {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
@TestMetadata("access.kt")
public void testAccess() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/access.kt");
}
public void testAllFilesPresentInExpresssions() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/expresssions"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/simple.kt");
}
@TestMetadata("when.kt")
public void testWhen() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/when.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/fromBuilder")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -7,11 +7,14 @@ package org.jetbrains.kotlin.fir.declarations
import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.FirVisitor
interface FirTypedDeclaration : FirDeclaration, FirAnnotationContainer {
val returnTypeRef: FirTypeRef
fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D)
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitTypedDeclaration(this, data)
@@ -23,6 +23,10 @@ abstract class FirAbstractCallableMember : FirAbstractMemberDeclaration, FirCall
final override var receiverTypeRef: FirTypeRef?
final override var returnTypeRef: FirTypeRef
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
}
constructor(
session: FirSession,
psi: PsiElement?,
@@ -28,4 +28,8 @@ class FirAnonymousFunctionImpl(
label = label?.transformSingle(transformer, data)
return super<FirAbstractFunction>.transformChildren(transformer, data)
}
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
}
}
@@ -32,6 +32,12 @@ abstract class FirDefaultPropertyAccessor(
final override val annotations: List<FirAnnotationCall>
get() = emptyList()
abstract override var returnTypeRef: FirTypeRef
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
}
}
class FirDefaultPropertyGetter(
@@ -34,6 +34,10 @@ class FirDefaultSetterValueParameter(
return super<FirAbstractNamedAnnotatedDeclaration>.transformChildren(transformer, data)
}
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
}
companion object {
val name = Name.identifier("value")
}
@@ -32,4 +32,8 @@ class FirPropertyAccessorImpl(
return super<FirAbstractFunction>.transformChildren(transformer, data)
}
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
}
}
@@ -31,4 +31,8 @@ open class FirValueParameterImpl(
return super<FirAbstractNamedAnnotatedDeclaration>.transformChildren(transformer, data)
}
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
}
}
@@ -31,4 +31,8 @@ class FirVariableImpl(
return super<FirAbstractNamedAnnotatedDeclaration>.transformChildren(transformer, data)
}
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.fir.FirReference
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.FirVisitor
interface FirQualifiedAccess : FirStatement {
@@ -15,6 +16,8 @@ interface FirQualifiedAccess : FirStatement {
val explicitReceiver: FirExpression? get() = null
fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirQualifiedAccess
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitQualifiedAccess(this, data)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.expressions.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.visitors.FirTransformer
abstract class FirAbstractQualifiedAccess(
@@ -24,4 +25,9 @@ abstract class FirAbstractQualifiedAccess(
explicitReceiver = explicitReceiver?.transformSingle(transformer, data)
return super<FirAbstractStatement>.transformChildren(transformer, data)
}
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirQualifiedAccess {
calleeReference = calleeReference.transformSingle(transformer, data)
return this
}
}
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.visitors.FirTransformer
@@ -29,4 +30,9 @@ class FirFunctionCallImpl(
explicitReceiver = explicitReceiver?.transformSingle(transformer, data)
return super<FirAbstractCall>.transformChildren(transformer, data)
}
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirQualifiedAccess {
calleeReference = calleeReference.transformSingle(transformer, data)
return this
}
}