diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeElement.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeElement.java index d1fb79dd5ca..accb77f452c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeElement.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeElement.java @@ -32,6 +32,7 @@ public interface JetTypeElement extends JetElement { } }; + // may contain null @NotNull List getTypeArgumentsAsTypes(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeBinding.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeBinding.kt new file mode 100644 index 00000000000..64f24243ad5 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeBinding.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2010-2014 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.jet.lang.resolve.typeBinding + +import org.jetbrains.jet.lang.types.JetType +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor +import com.intellij.psi.PsiElement +import org.jetbrains.jet.lang.psi.JetTypeElement +import org.jetbrains.jet.lang.psi.JetCallableDeclaration +import org.jetbrains.jet.lang.resolve.BindingTrace +import org.jetbrains.jet.lang.resolve.BindingContext +import org.jetbrains.jet.lang.psi.JetTypeReference +import java.util.AbstractList +import org.jetbrains.jet.lang.types.TypeProjection +import org.jetbrains.jet.lang.descriptors.CallableDescriptor +import org.jetbrains.jet.lang.types.TypeProjectionImpl + + +trait TypeBinding { + val psiElement: P + val jetType: JetType + fun getArgumentBindings(): List?> +} + +trait TypeArgumentBinding { + val typeProjection: TypeProjection + val typeParameterDescriptor: TypeParameterDescriptor? + val typeBinding: TypeBinding

+} + +fun JetTypeReference.createTypeBinding(trace: BindingContext): TypeBinding? { + val jetType = trace[BindingContext.TYPE, this] + val psiElement = getTypeElement() + if (jetType == null || psiElement == null) { + return null + } + else { + return ExplicitTypeBinding(trace, psiElement, jetType) + } +} + +fun JetCallableDeclaration.createTypeBindingForReturnType(trace: BindingContext): TypeBinding? { + val jetTypeReference = getTypeReference() + if (jetTypeReference != null) return jetTypeReference.createTypeBinding(trace) + + val descriptor = trace[BindingContext.DECLARATION_TO_DESCRIPTOR, this] + if (descriptor !is CallableDescriptor) return null + + return descriptor.getReturnType()?.let { NoTypeElementBinding(trace, this, it) } +} + +private class TypeArgumentBindingImpl( + override val typeProjection: TypeProjection, + override val typeParameterDescriptor: TypeParameterDescriptor?, + override val typeBinding: TypeBinding

+) : TypeArgumentBinding

+ +private class ExplicitTypeBinding( + private val trace: BindingContext, + override val psiElement: JetTypeElement, + override val jetType: JetType +) : TypeBinding { + + override fun getArgumentBindings(): List?> { + val psiTypeArguments = psiElement.getTypeArgumentsAsTypes() + val isErrorBinding = run { + val sizeIsEqual = psiTypeArguments.size == jetType.getArguments().size + && psiTypeArguments.size == jetType.getConstructor().getParameters().size + jetType.isError() || !sizeIsEqual + } + + return psiTypeArguments.indices.map { (index: Int): TypeArgumentBinding? -> + // todo fix for List<*> + val jetTypeReference = psiTypeArguments[index] + val jetTypeElement = jetTypeReference?.getTypeElement() + if (jetTypeElement == null) return@map null; + + if (isErrorBinding) { + val nextJetType = trace[BindingContext.TYPE, jetTypeReference] + if (nextJetType == null) return@map null; + + return@map TypeArgumentBindingImpl( + TypeProjectionImpl(nextJetType), + null, + ExplicitTypeBinding(trace, jetTypeElement, nextJetType) + ) + } + + val typeProjection = jetType.getArguments()[index] + return@map TypeArgumentBindingImpl( + typeProjection, + jetType.getConstructor().getParameters()[index], + ExplicitTypeBinding(trace, jetTypeElement, typeProjection.getType()) + ) + } + } +} + +private class NoTypeElementBinding( + private val trace: BindingContext, + override val psiElement: P, + override val jetType: JetType +): TypeBinding

{ + + override fun getArgumentBindings(): List?> { + val isErrorBinding = jetType.isError() || jetType.getConstructor().getParameters().size != jetType.getArguments().size + return jetType.getArguments().indices.map { + val typeProjection = jetType.getArguments()[it] + TypeArgumentBindingImpl( + typeProjection, + if (isErrorBinding) null else jetType.getConstructor().getParameters()[it], + NoTypeElementBinding(trace, psiElement, typeProjection.getType()) + ) + } + } +} + diff --git a/compiler/testData/type/binding/explicit/conflictingProjection.kt b/compiler/testData/type/binding/explicit/conflictingProjection.kt new file mode 100644 index 00000000000..8e800710b93 --- /dev/null +++ b/compiler/testData/type/binding/explicit/conflictingProjection.kt @@ -0,0 +1,9 @@ +val foo: List = null!! +/* +psi: List +type: List + typeParameter: defined in kotlin.List + typeProjection: in Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/conflictingProjection2.kt b/compiler/testData/type/binding/explicit/conflictingProjection2.kt new file mode 100644 index 00000000000..af1a5efce51 --- /dev/null +++ b/compiler/testData/type/binding/explicit/conflictingProjection2.kt @@ -0,0 +1,13 @@ +val foo: List> = null!! +/* +psi: List> +type: List> + typeParameter: defined in kotlin.List + typeProjection: in List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/errorPair.kt b/compiler/testData/type/binding/explicit/errorPair.kt new file mode 100644 index 00000000000..b4bceb63d14 --- /dev/null +++ b/compiler/testData/type/binding/explicit/errorPair.kt @@ -0,0 +1,22 @@ +val foo: Pair>, String> = null!! +/* +psi: Pair>, String> +type: Pair<[ERROR : Pair>], String> + typeParameter: defined in kotlin.Pair + typeProjection: [ERROR : Pair>] + psi: Pair> + type: [ERROR : Pair>] + typeParameter: null + typeProjection: List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int + + typeParameter: defined in kotlin.Pair + typeProjection: String + psi: String + type: String +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/errorWithProjection.kt b/compiler/testData/type/binding/explicit/errorWithProjection.kt new file mode 100644 index 00000000000..0523feba9a6 --- /dev/null +++ b/compiler/testData/type/binding/explicit/errorWithProjection.kt @@ -0,0 +1,14 @@ +val foo: List = null!! +/* +psi: List +type: [ERROR : List] + typeParameter: null + typeProjection: Int + psi: Int + type: Int + + typeParameter: null + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/functionType.kt b/compiler/testData/type/binding/explicit/functionType.kt new file mode 100644 index 00000000000..413e74c556e --- /dev/null +++ b/compiler/testData/type/binding/explicit/functionType.kt @@ -0,0 +1,31 @@ +val foo: List<(Pair) -> List> = null!! +/* +psi: List<(Pair) -> List> +type: List<(Pair) -> List> + typeParameter: defined in kotlin.List + typeProjection: (Pair) -> List + psi: (Pair) -> List + type: (Pair) -> List + typeParameter: defined in kotlin.Function1 + typeProjection: Pair + psi: Pair + type: Pair + typeParameter: defined in kotlin.Pair + typeProjection: Int + psi: Int + type: Int + + typeParameter: defined in kotlin.Pair + typeProjection: Float + psi: Float + type: Float + + typeParameter: defined in kotlin.Function1 + typeProjection: List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/functionType2.kt b/compiler/testData/type/binding/explicit/functionType2.kt new file mode 100644 index 00000000000..1bc1745b5fa --- /dev/null +++ b/compiler/testData/type/binding/explicit/functionType2.kt @@ -0,0 +1,27 @@ +val foo: (Pair) -> List = null!! +/* +psi: (Pair) -> List +type: (Pair) -> List + typeParameter: defined in kotlin.Function1 + typeProjection: Pair + psi: Pair + type: Pair + typeParameter: defined in kotlin.Pair + typeProjection: Int + psi: Int + type: Int + + typeParameter: defined in kotlin.Pair + typeProjection: Float + psi: Float + type: Float + + typeParameter: defined in kotlin.Function1 + typeProjection: List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/functionType3.kt b/compiler/testData/type/binding/explicit/functionType3.kt new file mode 100644 index 00000000000..d249d3f380c --- /dev/null +++ b/compiler/testData/type/binding/explicit/functionType3.kt @@ -0,0 +1,13 @@ +val foo: () -> List = null!! +/* +psi: () -> List +type: () -> List + typeParameter: defined in kotlin.Function0 + typeProjection: List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/inProjection.kt b/compiler/testData/type/binding/explicit/inProjection.kt new file mode 100644 index 00000000000..57479213acb --- /dev/null +++ b/compiler/testData/type/binding/explicit/inProjection.kt @@ -0,0 +1,22 @@ +trait Inv +trait In +trait Out + + +val foo: Inv>> = null!! +/* +psi: Inv>> +type: Inv>> + typeParameter: defined in Inv + typeProjection: in In> + psi: In> + type: In> + typeParameter: defined in In + typeProjection: in Out + psi: Out + type: Out + typeParameter: defined in Out + typeProjection: in Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/int.kt b/compiler/testData/type/binding/explicit/int.kt new file mode 100644 index 00000000000..9e3324599cf --- /dev/null +++ b/compiler/testData/type/binding/explicit/int.kt @@ -0,0 +1,5 @@ +val fml: Int = 239 +/* +psi: Int +type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/list0.kt b/compiler/testData/type/binding/explicit/list0.kt new file mode 100644 index 00000000000..17615f9d48f --- /dev/null +++ b/compiler/testData/type/binding/explicit/list0.kt @@ -0,0 +1,5 @@ +val foo: List = null!! +/* +psi: List +type: [ERROR : List] +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/list2.kt b/compiler/testData/type/binding/explicit/list2.kt new file mode 100644 index 00000000000..a089c0364a9 --- /dev/null +++ b/compiler/testData/type/binding/explicit/list2.kt @@ -0,0 +1,18 @@ +val foo: List> = null!! +/* +psi: List> +type: [ERROR : List>] + typeParameter: null + typeProjection: String + psi: String + type: String + + typeParameter: null + typeProjection: List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/nullableType.kt b/compiler/testData/type/binding/explicit/nullableType.kt new file mode 100644 index 00000000000..a5448d1ae7e --- /dev/null +++ b/compiler/testData/type/binding/explicit/nullableType.kt @@ -0,0 +1,35 @@ +val foo: Pair, Pair?, List?>> = null!! +/* +psi: Pair, Pair?, List?>> +type: Pair, Pair?, List?>> + typeParameter: defined in kotlin.Pair + typeProjection: List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int? + psi: Int? + type: Int? + + typeParameter: defined in kotlin.Pair + typeProjection: Pair?, List?> + psi: Pair?, List?> + type: Pair?, List?> + typeParameter: defined in kotlin.Pair + typeProjection: List? + psi: List? + type: List? + typeParameter: defined in kotlin.List + typeProjection: Int? + psi: Int? + type: Int? + + typeParameter: defined in kotlin.Pair + typeProjection: List? + psi: List? + type: List? + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/outProjection.kt b/compiler/testData/type/binding/explicit/outProjection.kt new file mode 100644 index 00000000000..ca9daf9b89b --- /dev/null +++ b/compiler/testData/type/binding/explicit/outProjection.kt @@ -0,0 +1,22 @@ +trait Inv +trait In +trait Out + + +val foo: Inv>> = null!! +/* +psi: Inv>> +type: Inv>> + typeParameter: defined in Inv + typeProjection: out In> + psi: In> + type: In> + typeParameter: defined in In + typeProjection: out Out + psi: Out + type: Out + typeParameter: defined in Out + typeProjection: out Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/pair.kt b/compiler/testData/type/binding/explicit/pair.kt new file mode 100644 index 00000000000..7237785ad73 --- /dev/null +++ b/compiler/testData/type/binding/explicit/pair.kt @@ -0,0 +1,20 @@ + + +val foo: Pair, String> = null!! +/* +psi: Pair, String> +type: Pair, String> + typeParameter: defined in kotlin.Pair + typeProjection: List + psi: List + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int + + typeParameter: defined in kotlin.Pair + typeProjection: String + psi: String + type: String +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/simple.kt b/compiler/testData/type/binding/explicit/simple.kt new file mode 100644 index 00000000000..675542dc428 --- /dev/null +++ b/compiler/testData/type/binding/explicit/simple.kt @@ -0,0 +1,10 @@ + +val foo: List = null!! +/* +psi: List +type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/star.kt b/compiler/testData/type/binding/explicit/star.kt new file mode 100644 index 00000000000..67c7919d97a --- /dev/null +++ b/compiler/testData/type/binding/explicit/star.kt @@ -0,0 +1,6 @@ +val foo: List<*> = null!! +/* +psi: List<*> +type: List + null +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/typeWithBracket.kt b/compiler/testData/type/binding/explicit/typeWithBracket.kt new file mode 100644 index 00000000000..ad36e6d6ae6 --- /dev/null +++ b/compiler/testData/type/binding/explicit/typeWithBracket.kt @@ -0,0 +1,15 @@ +trait Inv + +val foo: Inv)?)> = null!! +/* +psi: Inv)?)> +type: Inv?> + typeParameter: defined in Inv + typeProjection: out Inv? + psi: (Inv)? + type: Inv? + typeParameter: defined in Inv + typeProjection: Int + psi: Int + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/explicit/unresolvedType.kt b/compiler/testData/type/binding/explicit/unresolvedType.kt new file mode 100644 index 00000000000..8019165a15d --- /dev/null +++ b/compiler/testData/type/binding/explicit/unresolvedType.kt @@ -0,0 +1,17 @@ +val foo: List>> = null!! +/* +psi: List>> +type: List<[ERROR : adad>]> + typeParameter: defined in kotlin.List + typeProjection: [ERROR : adad>] + psi: adad> + type: [ERROR : adad>] + typeParameter: null + typeProjection: List<[ERROR : dd]> + psi: List

+ type: List<[ERROR : dd]> + typeParameter: defined in kotlin.List + typeProjection: [ERROR : dd] + psi: dd + type: [ERROR : dd] +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/conflictingProjection.kt b/compiler/testData/type/binding/implicit/conflictingProjection.kt new file mode 100644 index 00000000000..2183c8d21f7 --- /dev/null +++ b/compiler/testData/type/binding/implicit/conflictingProjection.kt @@ -0,0 +1,11 @@ +fun getT(): T = null!! + +val foo = getT>() +/* +psi: val foo = getT>() +type: List + typeParameter: defined in kotlin.List + typeProjection: in Int + psi: val foo = getT>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/conflictingProjection2.kt b/compiler/testData/type/binding/implicit/conflictingProjection2.kt new file mode 100644 index 00000000000..d1c454b0025 --- /dev/null +++ b/compiler/testData/type/binding/implicit/conflictingProjection2.kt @@ -0,0 +1,15 @@ +fun getT(): T = null!! + +val foo = getT>>() +/* +psi: val foo = getT>>() +type: List> + typeParameter: defined in kotlin.List + typeProjection: in List + psi: val foo = getT>>() + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: val foo = getT>>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/errorPair.kt b/compiler/testData/type/binding/implicit/errorPair.kt new file mode 100644 index 00000000000..ba4b886d2df --- /dev/null +++ b/compiler/testData/type/binding/implicit/errorPair.kt @@ -0,0 +1,16 @@ +fun getT(): T = null!! + +val foo = getT>, String>>() +/* +psi: val foo = getT>, String>>() +type: Pair<[ERROR : Pair>], String> + typeParameter: defined in kotlin.Pair + typeProjection: [ERROR : Pair>] + psi: val foo = getT>, String>>() + type: [ERROR : Pair>] + + typeParameter: defined in kotlin.Pair + typeProjection: String + psi: val foo = getT>, String>>() + type: String +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/errorWithProjection.kt b/compiler/testData/type/binding/implicit/errorWithProjection.kt new file mode 100644 index 00000000000..23eb5fe3931 --- /dev/null +++ b/compiler/testData/type/binding/implicit/errorWithProjection.kt @@ -0,0 +1,7 @@ +fun getT(): T = null!! + +val foo = getT>() +/* +psi: val foo = getT>() +type: [ERROR : List] +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/functionType.kt b/compiler/testData/type/binding/implicit/functionType.kt new file mode 100644 index 00000000000..64894784e4b --- /dev/null +++ b/compiler/testData/type/binding/implicit/functionType.kt @@ -0,0 +1,33 @@ +fun getT(): T = null!! + +val foo = getT) -> List>>() +/* +psi: val foo = getT) -> List>>() +type: List<(Pair) -> List> + typeParameter: defined in kotlin.List + typeProjection: (Pair) -> List + psi: val foo = getT) -> List>>() + type: (Pair) -> List + typeParameter: defined in kotlin.Function1 + typeProjection: Pair + psi: val foo = getT) -> List>>() + type: Pair + typeParameter: defined in kotlin.Pair + typeProjection: Int + psi: val foo = getT) -> List>>() + type: Int + + typeParameter: defined in kotlin.Pair + typeProjection: Float + psi: val foo = getT) -> List>>() + type: Float + + typeParameter: defined in kotlin.Function1 + typeProjection: List + psi: val foo = getT) -> List>>() + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: val foo = getT) -> List>>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/functionType2.kt b/compiler/testData/type/binding/implicit/functionType2.kt new file mode 100644 index 00000000000..8cfdedb4727 --- /dev/null +++ b/compiler/testData/type/binding/implicit/functionType2.kt @@ -0,0 +1,29 @@ +fun getT(): T = null!! + +val foo = getT<(Pair) -> List>() +/* +psi: val foo = getT<(Pair) -> List>() +type: (Pair) -> List + typeParameter: defined in kotlin.Function1 + typeProjection: Pair + psi: val foo = getT<(Pair) -> List>() + type: Pair + typeParameter: defined in kotlin.Pair + typeProjection: Int + psi: val foo = getT<(Pair) -> List>() + type: Int + + typeParameter: defined in kotlin.Pair + typeProjection: Float + psi: val foo = getT<(Pair) -> List>() + type: Float + + typeParameter: defined in kotlin.Function1 + typeProjection: List + psi: val foo = getT<(Pair) -> List>() + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: val foo = getT<(Pair) -> List>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/functionType3.kt b/compiler/testData/type/binding/implicit/functionType3.kt new file mode 100644 index 00000000000..3054cba2585 --- /dev/null +++ b/compiler/testData/type/binding/implicit/functionType3.kt @@ -0,0 +1,15 @@ +fun getT(): T = null!! + +val foo = getT<() -> List>() +/* +psi: val foo = getT<() -> List>() +type: () -> List + typeParameter: defined in kotlin.Function0 + typeProjection: List + psi: val foo = getT<() -> List>() + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: val foo = getT<() -> List>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/inProjection.kt b/compiler/testData/type/binding/implicit/inProjection.kt new file mode 100644 index 00000000000..0a0df0499aa --- /dev/null +++ b/compiler/testData/type/binding/implicit/inProjection.kt @@ -0,0 +1,24 @@ +trait Inv +trait In +trait Out + + +fun getT(): T = null!! + +val foo = getT>>>() +/* +psi: val foo = getT>>>() +type: Inv>> + typeParameter: defined in Inv + typeProjection: in In> + psi: val foo = getT>>>() + type: In> + typeParameter: defined in In + typeProjection: in Out + psi: val foo = getT>>>() + type: Out + typeParameter: defined in Out + typeProjection: in Int + psi: val foo = getT>>>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/int.kt b/compiler/testData/type/binding/implicit/int.kt new file mode 100644 index 00000000000..70290d27d0e --- /dev/null +++ b/compiler/testData/type/binding/implicit/int.kt @@ -0,0 +1,7 @@ +fun getT(): T = null!! + +val fml = getT() +/* +psi: val fml = getT() +type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/list0.kt b/compiler/testData/type/binding/implicit/list0.kt new file mode 100644 index 00000000000..b737c67d08d --- /dev/null +++ b/compiler/testData/type/binding/implicit/list0.kt @@ -0,0 +1,7 @@ +fun getT(): T = null!! + +val foo = getT() +/* +psi: val foo = getT() +type: [ERROR : List] +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/list2.kt b/compiler/testData/type/binding/implicit/list2.kt new file mode 100644 index 00000000000..1a0a29739b8 --- /dev/null +++ b/compiler/testData/type/binding/implicit/list2.kt @@ -0,0 +1,7 @@ +fun getT(): T = null!! + +val foo = getT>>() +/* +psi: val foo = getT>>() +type: [ERROR : List>] +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/nullableType.kt b/compiler/testData/type/binding/implicit/nullableType.kt new file mode 100644 index 00000000000..92319a380d8 --- /dev/null +++ b/compiler/testData/type/binding/implicit/nullableType.kt @@ -0,0 +1,37 @@ +fun getT(): T = null!! + +val foo = getT, Pair?, List?>>>() +/* +psi: val foo = getT, Pair?, List?>>>() +type: Pair, Pair?, List?>> + typeParameter: defined in kotlin.Pair + typeProjection: List + psi: val foo = getT, Pair?, List?>>>() + type: List + typeParameter: defined in kotlin.List + typeProjection: Int? + psi: val foo = getT, Pair?, List?>>>() + type: Int? + + typeParameter: defined in kotlin.Pair + typeProjection: Pair?, List?> + psi: val foo = getT, Pair?, List?>>>() + type: Pair?, List?> + typeParameter: defined in kotlin.Pair + typeProjection: List? + psi: val foo = getT, Pair?, List?>>>() + type: List? + typeParameter: defined in kotlin.List + typeProjection: Int? + psi: val foo = getT, Pair?, List?>>>() + type: Int? + + typeParameter: defined in kotlin.Pair + typeProjection: List? + psi: val foo = getT, Pair?, List?>>>() + type: List? + typeParameter: defined in kotlin.List + typeProjection: Int + psi: val foo = getT, Pair?, List?>>>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/outProjection.kt b/compiler/testData/type/binding/implicit/outProjection.kt new file mode 100644 index 00000000000..52c5398eea7 --- /dev/null +++ b/compiler/testData/type/binding/implicit/outProjection.kt @@ -0,0 +1,24 @@ +trait Inv +trait In +trait Out + + +fun getT(): T = null!! + +val foo = getT>>>() +/* +psi: val foo = getT>>>() +type: Inv>> + typeParameter: defined in Inv + typeProjection: out In> + psi: val foo = getT>>>() + type: In> + typeParameter: defined in In + typeProjection: out Out + psi: val foo = getT>>>() + type: Out + typeParameter: defined in Out + typeProjection: out Int + psi: val foo = getT>>>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/pair.kt b/compiler/testData/type/binding/implicit/pair.kt new file mode 100644 index 00000000000..802979e5174 --- /dev/null +++ b/compiler/testData/type/binding/implicit/pair.kt @@ -0,0 +1,20 @@ +fun getT(): T = null!! + +val foo = getT, String>>() +/* +psi: val foo = getT, String>>() +type: Pair, String> + typeParameter: defined in kotlin.Pair + typeProjection: List + psi: val foo = getT, String>>() + type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: val foo = getT, String>>() + type: Int + + typeParameter: defined in kotlin.Pair + typeProjection: String + psi: val foo = getT, String>>() + type: String +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/simple.kt b/compiler/testData/type/binding/implicit/simple.kt new file mode 100644 index 00000000000..93e8fd89370 --- /dev/null +++ b/compiler/testData/type/binding/implicit/simple.kt @@ -0,0 +1,11 @@ +fun getT(): T = null!! + +val foo = getT>() +/* +psi: val foo = getT>() +type: List + typeParameter: defined in kotlin.List + typeProjection: Int + psi: val foo = getT>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/star.kt b/compiler/testData/type/binding/implicit/star.kt new file mode 100644 index 00000000000..f08298a7e09 --- /dev/null +++ b/compiler/testData/type/binding/implicit/star.kt @@ -0,0 +1,11 @@ +fun getT(): T = null!! + +val foo = getT>() +/* +psi: val foo = getT>() +type: List + typeParameter: defined in kotlin.List + typeProjection: Any? + psi: val foo = getT>() + type: Any? +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/typeWithBracket.kt b/compiler/testData/type/binding/implicit/typeWithBracket.kt new file mode 100644 index 00000000000..ed633a9e502 --- /dev/null +++ b/compiler/testData/type/binding/implicit/typeWithBracket.kt @@ -0,0 +1,17 @@ +trait Inv + +fun getT(): T = null!! + +val foo = getT)?)>>() +/* +psi: val foo = getT)?)>>() +type: Inv?> + typeParameter: defined in Inv + typeProjection: out Inv? + psi: val foo = getT)?)>>() + type: Inv? + typeParameter: defined in Inv + typeProjection: Int + psi: val foo = getT)?)>>() + type: Int +*/ \ No newline at end of file diff --git a/compiler/testData/type/binding/implicit/unresolvedType.kt b/compiler/testData/type/binding/implicit/unresolvedType.kt new file mode 100644 index 00000000000..be2cb48fed8 --- /dev/null +++ b/compiler/testData/type/binding/implicit/unresolvedType.kt @@ -0,0 +1,7 @@ +fun getT(): T = null!! + +val foo = getT>>() +/* +psi: val foo = getT>>() +type: [ERROR : Type for getT>>()] +*/ \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/types/AbstractJetTypeBindingTest.kt b/compiler/tests/org/jetbrains/jet/types/AbstractJetTypeBindingTest.kt new file mode 100644 index 00000000000..4c307dc1cc9 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/types/AbstractJetTypeBindingTest.kt @@ -0,0 +1,124 @@ +/* + * Copyright 2010-2014 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.jet.types + +import org.jetbrains.jet.JetLiteFixture +import org.jetbrains.jet.ConfigurationKind +import org.jetbrains.jet.JetTestUtils +import java.io.File +import org.junit.Assert.* +import org.jetbrains.jet.lang.resolve.BindingTraceContext +import org.jetbrains.jet.lang.resolve.typeBinding.* +import org.jetbrains.jet.lang.types.JetType +import org.jetbrains.jet.renderer.DescriptorRenderer +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor +import org.jetbrains.jet.lang.resolve.lazy.JvmResolveUtil +import org.jetbrains.jet.lang.psi.JetCallableDeclaration +import org.jetbrains.jet.utils.Printer +import org.jetbrains.jet.test.util.trimIndent +import org.jetbrains.jet.lang.psi.JetFile +import org.jetbrains.jet.JetTestUtils.* +import org.jetbrains.jet.lang.psi.JetVariableDeclaration + +abstract class AbstractJetTypeBindingTest : JetLiteFixture() { + override fun createEnvironment() = createEnvironmentWithMockJdk(ConfigurationKind.ALL) + + protected fun doTest(path: String) { + val testFile = File(path) + val testKtFile = JetTestUtils.loadJetFile(getProject(), testFile) + + val analyzeResult = JvmResolveUtil.analyzeFilesWithJavaIntegration(getProject(), listOf(testKtFile), { true }) + + val testDeclaration = testKtFile.getDeclarations().last!! as JetCallableDeclaration + + val typeBinding = testDeclaration.createTypeBindingForReturnType(analyzeResult.bindingContext) + + JetTestUtils.assertEqualsToFile( + testFile, + StringBuilder { + append(removeLastComment(testKtFile)) + append("/*\n") + + MyPrinter(this).print(typeBinding) + + append("*/") + }.toString() + ) + } + + private fun removeLastComment(file: JetFile): String { + val fileText = file.getText() + val lastIndex = fileText.indexOf("/*") + return if (lastIndex > 0) { + fileText.substring(0, lastIndex) + } + else fileText + } + + private class MyPrinter(out: StringBuilder) : Printer(out) { + private fun JetType.render() = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(this) + private fun TypeParameterDescriptor?.render() = if (this == null) "null" else DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(this) + + fun print(argument: TypeArgumentBinding<*>?): MyPrinter { + if (argument == null) { + println("null") + return this + } + println("typeParameter: ${argument.typeParameterDescriptor.render()}") + + val projection = argument.typeProjection.getProjectionKind().toString().let { + if (it.isNotEmpty()) + "$it " + else + "" + } + + println("typeProjection: ${projection}${argument.typeProjection.getType().render()}") + print(argument.typeBinding) + return this + } + + fun print(binding: TypeBinding<*>?): MyPrinter { + if (binding == null) { + println("null") + return this + } + + println("psi: ${binding.psiElement.getText()}") + println("type: ${binding.jetType.render()}") + + printCollection(binding.getArgumentBindings()) { + print(it) + } + return this + } + + private fun printCollection(list: Iterable, f: MyPrinter.(T) -> Unit) { + pushIndent() + var first = true + for (element in list) { + if (first) first = false + else println() + + f(element) + } + popIndent() + } + + override fun toString(): String = out.toString() + } +} diff --git a/compiler/tests/org/jetbrains/jet/types/JetTypeBindingTestGenerated.java b/compiler/tests/org/jetbrains/jet/types/JetTypeBindingTestGenerated.java new file mode 100644 index 00000000000..ccfcf54f083 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/types/JetTypeBindingTestGenerated.java @@ -0,0 +1,273 @@ +/* + * Copyright 2010-2014 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.jet.types; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.jet.JUnit3RunnerWithInners; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/type/binding") +@TestDataPath("$PROJECT_ROOT") +@InnerTestClasses({JetTypeBindingTestGenerated.Explicit.class, JetTypeBindingTestGenerated.Implicit.class}) +@RunWith(JUnit3RunnerWithInners.class) +public class JetTypeBindingTestGenerated extends AbstractJetTypeBindingTest { + public void testAllFilesPresentInBinding() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/type/binding"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("compiler/testData/type/binding/explicit") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Explicit extends AbstractJetTypeBindingTest { + public void testAllFilesPresentInExplicit() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/type/binding/explicit"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("conflictingProjection.kt") + public void testConflictingProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/conflictingProjection.kt"); + doTest(fileName); + } + + @TestMetadata("conflictingProjection2.kt") + public void testConflictingProjection2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/conflictingProjection2.kt"); + doTest(fileName); + } + + @TestMetadata("errorPair.kt") + public void testErrorPair() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/errorPair.kt"); + doTest(fileName); + } + + @TestMetadata("errorWithProjection.kt") + public void testErrorWithProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/errorWithProjection.kt"); + doTest(fileName); + } + + @TestMetadata("functionType.kt") + public void testFunctionType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/functionType.kt"); + doTest(fileName); + } + + @TestMetadata("functionType2.kt") + public void testFunctionType2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/functionType2.kt"); + doTest(fileName); + } + + @TestMetadata("functionType3.kt") + public void testFunctionType3() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/functionType3.kt"); + doTest(fileName); + } + + @TestMetadata("inProjection.kt") + public void testInProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/inProjection.kt"); + doTest(fileName); + } + + @TestMetadata("int.kt") + public void testInt() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/int.kt"); + doTest(fileName); + } + + @TestMetadata("list0.kt") + public void testList0() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/list0.kt"); + doTest(fileName); + } + + @TestMetadata("list2.kt") + public void testList2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/list2.kt"); + doTest(fileName); + } + + @TestMetadata("nullableType.kt") + public void testNullableType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/nullableType.kt"); + doTest(fileName); + } + + @TestMetadata("outProjection.kt") + public void testOutProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/outProjection.kt"); + doTest(fileName); + } + + @TestMetadata("pair.kt") + public void testPair() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/pair.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/simple.kt"); + doTest(fileName); + } + + @TestMetadata("star.kt") + public void testStar() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/star.kt"); + doTest(fileName); + } + + @TestMetadata("typeWithBracket.kt") + public void testTypeWithBracket() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/typeWithBracket.kt"); + doTest(fileName); + } + + @TestMetadata("unresolvedType.kt") + public void testUnresolvedType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/explicit/unresolvedType.kt"); + doTest(fileName); + } + } + + @TestMetadata("compiler/testData/type/binding/implicit") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Implicit extends AbstractJetTypeBindingTest { + public void testAllFilesPresentInImplicit() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/type/binding/implicit"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("conflictingProjection.kt") + public void testConflictingProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/conflictingProjection.kt"); + doTest(fileName); + } + + @TestMetadata("conflictingProjection2.kt") + public void testConflictingProjection2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/conflictingProjection2.kt"); + doTest(fileName); + } + + @TestMetadata("errorPair.kt") + public void testErrorPair() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/errorPair.kt"); + doTest(fileName); + } + + @TestMetadata("errorWithProjection.kt") + public void testErrorWithProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/errorWithProjection.kt"); + doTest(fileName); + } + + @TestMetadata("functionType.kt") + public void testFunctionType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/functionType.kt"); + doTest(fileName); + } + + @TestMetadata("functionType2.kt") + public void testFunctionType2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/functionType2.kt"); + doTest(fileName); + } + + @TestMetadata("functionType3.kt") + public void testFunctionType3() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/functionType3.kt"); + doTest(fileName); + } + + @TestMetadata("inProjection.kt") + public void testInProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/inProjection.kt"); + doTest(fileName); + } + + @TestMetadata("int.kt") + public void testInt() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/int.kt"); + doTest(fileName); + } + + @TestMetadata("list0.kt") + public void testList0() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/list0.kt"); + doTest(fileName); + } + + @TestMetadata("list2.kt") + public void testList2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/list2.kt"); + doTest(fileName); + } + + @TestMetadata("nullableType.kt") + public void testNullableType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/nullableType.kt"); + doTest(fileName); + } + + @TestMetadata("outProjection.kt") + public void testOutProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/outProjection.kt"); + doTest(fileName); + } + + @TestMetadata("pair.kt") + public void testPair() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/pair.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/simple.kt"); + doTest(fileName); + } + + @TestMetadata("star.kt") + public void testStar() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/star.kt"); + doTest(fileName); + } + + @TestMetadata("typeWithBracket.kt") + public void testTypeWithBracket() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/typeWithBracket.kt"); + doTest(fileName); + } + + @TestMetadata("unresolvedType.kt") + public void testUnresolvedType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/type/binding/implicit/unresolvedType.kt"); + doTest(fileName); + } + } +} diff --git a/core/util.runtime/src/org/jetbrains/jet/utils/Printer.java b/core/util.runtime/src/org/jetbrains/jet/utils/Printer.java index 18b50735fa1..8e0dfef337f 100644 --- a/core/util.runtime/src/org/jetbrains/jet/utils/Printer.java +++ b/core/util.runtime/src/org/jetbrains/jet/utils/Printer.java @@ -26,7 +26,7 @@ public class Printer { private static final String INDENTATION_UNIT = " "; private static final String LINE_SEPARATOR = System.getProperty("line.separator"); - private final Appendable out; + protected final Appendable out; private final int maxBlankLines; private String indent = ""; diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index b33b22889a6..20118c15062 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -133,6 +133,7 @@ import org.jetbrains.jet.completion.AbstractMultiFileSmartCompletionTest import org.jetbrains.jet.completion.handlers.AbstractCompletionCharFilterTest import org.jetbrains.jet.resolve.AbstractPartialBodyResolveTest import org.jetbrains.jet.checkers.AbstractJetDiagnosticsTestWithJsStdLib +import org.jetbrains.jet.types.AbstractJetTypeBindingTest fun main(args: Array) { System.setProperty("java.awt.headless", "true") @@ -300,6 +301,10 @@ fun main(args: Array) { testClass(javaClass()) { model("asJava/lightClasses") } + + testClass(javaClass()) { + model("type/binding") + } } testGroup("idea/tests", "idea/testData") {