Support class literals (A::class)
This commit is contained in:
@@ -30,11 +30,11 @@ import kotlin.KotlinPackage;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||
import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
@@ -2610,6 +2610,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return lookupLocalIndex(declarationDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, StackValue data) {
|
||||
JetType type = bindingContext.get(EXPRESSION_TYPE, expression);
|
||||
assert type != null;
|
||||
|
||||
assert state.getReflectionTypes().getkClass().getTypeConstructor().equals(type.getConstructor())
|
||||
: "::class expression should be type checked to a KClass: " + type;
|
||||
|
||||
ClassifierDescriptor typeArgument = KotlinPackage.single(type.getArguments()).getType().getConstructor().getDeclarationDescriptor();
|
||||
assert typeArgument instanceof ClassDescriptor : "KClass argument should be a class: " + typeArgument;
|
||||
|
||||
return generateClassLiteralReference((ClassDescriptor) typeArgument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, StackValue data) {
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression.getCallableReference(), bindingContext);
|
||||
@@ -2690,10 +2704,22 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
v.visitLdcInsn(descriptor.getName().asString());
|
||||
StackValue receiverClass = generateClassLiteralReference(containingClass);
|
||||
receiverClass.put(receiverClass.type, v);
|
||||
v.invokestatic(REFLECTION, factoryMethod.getName(), factoryMethod.getDescriptor(), false);
|
||||
|
||||
Type classAsmType = typeMapper.mapClass(containingClass);
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (containingClass instanceof JavaClassDescriptor) {
|
||||
@NotNull
|
||||
private StackValue generateClassLiteralReference(@NotNull final ClassDescriptor descriptor) {
|
||||
return StackValue.operation(K_CLASS_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
Type classAsmType = typeMapper.mapClass(descriptor);
|
||||
if (descriptor instanceof JavaClassDescriptor) {
|
||||
v.aconst(classAsmType);
|
||||
v.invokestatic(REFLECTION, "foreignKotlinClass", Type.getMethodDescriptor(K_CLASS_TYPE, getType(Class.class)), false);
|
||||
}
|
||||
@@ -2701,8 +2727,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
v.getstatic(classAsmType.getInternalName(), JvmAbi.KOTLIN_CLASS_FIELD_NAME, K_CLASS_TYPE.getDescriptor());
|
||||
}
|
||||
|
||||
v.invokestatic(REFLECTION, factoryMethod.getName(), factoryMethod.getDescriptor(), false);
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -117,6 +117,8 @@ public class GenerationState {
|
||||
@Nullable
|
||||
private List<ScriptDescriptor> earlierScriptsForReplInterpreter;
|
||||
|
||||
private final ReflectionTypes reflectionTypes;
|
||||
|
||||
private final JvmRuntimeTypes runtimeTypes;
|
||||
|
||||
@NotNull
|
||||
@@ -187,7 +189,7 @@ public class GenerationState {
|
||||
this.disableParamAssertions = disableParamAssertions;
|
||||
this.generateClassFilter = generateClassFilter;
|
||||
|
||||
ReflectionTypes reflectionTypes = new ReflectionTypes(module);
|
||||
this.reflectionTypes = new ReflectionTypes(module);
|
||||
this.runtimeTypes = new JvmRuntimeTypes(reflectionTypes);
|
||||
}
|
||||
|
||||
@@ -259,6 +261,11 @@ public class GenerationState {
|
||||
return generateClassFilter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReflectionTypes getReflectionTypes() {
|
||||
return reflectionTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JvmRuntimeTypes getJvmRuntimeTypes() {
|
||||
return runtimeTypes;
|
||||
|
||||
@@ -135,6 +135,7 @@ public interface JetNodeTypes {
|
||||
JetNodeType INDICES = new JetNodeType("INDICES", JetContainerNode.class);
|
||||
IElementType DOT_QUALIFIED_EXPRESSION = JetStubElementTypes.DOT_QUALIFIED_EXPRESSION;
|
||||
JetNodeType CALLABLE_REFERENCE_EXPRESSION = new JetNodeType("CALLABLE_REFERENCE_EXPRESSION", JetCallableReferenceExpression.class);
|
||||
JetNodeType CLASS_LITERAL_EXPRESSION = new JetNodeType("CLASS_LITERAL_EXPRESSION", JetClassLiteralExpression.class);
|
||||
JetNodeType SAFE_ACCESS_EXPRESSION = new JetNodeType("SAFE_ACCESS_EXPRESSION", JetSafeQualifiedExpression.class);
|
||||
|
||||
JetNodeType OBJECT_LITERAL = new JetNodeType("OBJECT_LITERAL", JetObjectLiteralExpression.class);
|
||||
|
||||
@@ -1466,7 +1466,7 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression) {
|
||||
public void visitDoubleColonExpression(@NotNull JetDoubleColonExpression expression) {
|
||||
mark(expression);
|
||||
createNonSyntheticValue(expression, MagicKind.CALLABLE_REFERENCE);
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
* : (userType "?"*)? "::" SimpleName
|
||||
* ;
|
||||
*/
|
||||
private boolean parseCallableReferenceExpression() {
|
||||
private boolean parseDoubleColonExpression() {
|
||||
PsiBuilder.Marker expression = mark();
|
||||
|
||||
if (!at(COLONCOLON)) {
|
||||
@@ -393,8 +393,14 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
advance(); // COLONCOLON
|
||||
|
||||
parseSimpleNameExpression();
|
||||
expression.done(CALLABLE_REFERENCE_EXPRESSION);
|
||||
if (at(CLASS_KEYWORD)) {
|
||||
advance(); // CLASS_KEYWORD
|
||||
expression.done(CLASS_LITERAL_EXPRESSION);
|
||||
}
|
||||
else {
|
||||
parseSimpleNameExpression();
|
||||
expression.done(CALLABLE_REFERENCE_EXPRESSION);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -416,8 +422,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
private void parsePostfixExpression() {
|
||||
PsiBuilder.Marker expression = mark();
|
||||
|
||||
boolean callableReference = parseCallableReferenceExpression();
|
||||
if (!callableReference) {
|
||||
boolean doubleColonExpression = parseDoubleColonExpression();
|
||||
if (!doubleColonExpression) {
|
||||
parseAtomicExpression();
|
||||
}
|
||||
|
||||
@@ -429,7 +435,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
parseArrayAccess();
|
||||
expression.done(ARRAY_ACCESS_EXPRESSION);
|
||||
}
|
||||
else if (!callableReference && parseCallSuffix()) {
|
||||
else if (!doubleColonExpression && parseCallSuffix()) {
|
||||
expression.done(CALL_EXPRESSION);
|
||||
}
|
||||
else if (at(DOT)) {
|
||||
|
||||
@@ -19,26 +19,12 @@ package org.jetbrains.kotlin.psi;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.JetNodeTypes;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
|
||||
public class JetCallableReferenceExpression extends JetExpressionImpl {
|
||||
public class JetCallableReferenceExpression extends JetDoubleColonExpression {
|
||||
public JetCallableReferenceExpression(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetTypeReference getTypeReference() {
|
||||
return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement getDoubleColonTokenReference() {
|
||||
//noinspection ConstantConditions
|
||||
return findChildByType(JetTokens.COLONCOLON);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetSimpleNameExpression getCallableReference() {
|
||||
PsiElement psi = getDoubleColonTokenReference();
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
|
||||
public class JetClassLiteralExpression(node: ASTNode) : JetDoubleColonExpression(node) {
|
||||
override fun <R, D> accept(visitor: JetVisitor<R, D>, data: D): R {
|
||||
return visitor.visitClassLiteralExpression(this, data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.JetNodeTypes
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
|
||||
public abstract class JetDoubleColonExpression(node: ASTNode) : JetExpressionImpl(node) {
|
||||
public fun getTypeReference(): JetTypeReference? = findChildByType(JetNodeTypes.TYPE_REFERENCE)
|
||||
|
||||
public fun getDoubleColonTokenReference(): PsiElement = findChildByType(JetTokens.COLONCOLON)
|
||||
|
||||
override fun <R, D> accept(visitor: JetVisitor<R, D>, data: D): R {
|
||||
return visitor.visitDoubleColonExpression(this, data)
|
||||
}
|
||||
}
|
||||
@@ -258,10 +258,18 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
|
||||
return visitExpression(expression, data);
|
||||
}
|
||||
|
||||
public R visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, D data) {
|
||||
public R visitDoubleColonExpression(@NotNull JetDoubleColonExpression expression, D data) {
|
||||
return visitExpression(expression, data);
|
||||
}
|
||||
|
||||
public R visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, D data) {
|
||||
return visitDoubleColonExpression(expression, data);
|
||||
}
|
||||
|
||||
public R visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, D data) {
|
||||
return visitDoubleColonExpression(expression, data);
|
||||
}
|
||||
|
||||
public R visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression, D data) {
|
||||
return visitQualifiedExpression(expression, data);
|
||||
}
|
||||
|
||||
@@ -253,10 +253,18 @@ public class JetVisitorVoid extends JetVisitor<Void, Void> {
|
||||
super.visitQualifiedExpression(expression, null);
|
||||
}
|
||||
|
||||
public void visitDoubleColonExpression(@NotNull JetDoubleColonExpression expression) {
|
||||
super.visitDoubleColonExpression(expression, null);
|
||||
}
|
||||
|
||||
public void visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression) {
|
||||
super.visitCallableReferenceExpression(expression, null);
|
||||
}
|
||||
|
||||
public void visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression) {
|
||||
super.visitClassLiteralExpression(expression, null);
|
||||
}
|
||||
|
||||
public void visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression) {
|
||||
super.visitDotQualifiedExpression(expression, null);
|
||||
}
|
||||
@@ -758,12 +766,24 @@ public class JetVisitorVoid extends JetVisitor<Void, Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitDoubleColonExpression(@NotNull JetDoubleColonExpression expression, Void data) {
|
||||
visitDoubleColonExpression(expression);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, Void data) {
|
||||
visitCallableReferenceExpression(expression);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, Void data) {
|
||||
visitClassLiteralExpression(expression);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression, Void data) {
|
||||
visitDotQualifiedExpression(expression);
|
||||
|
||||
@@ -254,10 +254,18 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
|
||||
super.visitQualifiedExpression(expression, data);
|
||||
}
|
||||
|
||||
public void visitDoubleColonExpressionVoid(@NotNull JetDoubleColonExpression expression, P data) {
|
||||
super.visitDoubleColonExpression(expression, data);
|
||||
}
|
||||
|
||||
public void visitCallableReferenceExpressionVoid(@NotNull JetCallableReferenceExpression expression, P data) {
|
||||
super.visitCallableReferenceExpression(expression, data);
|
||||
}
|
||||
|
||||
public void visitClassLiteralExpressionVoid(@NotNull JetClassLiteralExpression expression, P data) {
|
||||
super.visitClassLiteralExpression(expression, data);
|
||||
}
|
||||
|
||||
public void visitDotQualifiedExpressionVoid(@NotNull JetDotQualifiedExpression expression, P data) {
|
||||
super.visitDotQualifiedExpression(expression, data);
|
||||
}
|
||||
@@ -755,12 +763,24 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitDoubleColonExpression(@NotNull JetDoubleColonExpression expression, P data) {
|
||||
visitDoubleColonExpressionVoid(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, P data) {
|
||||
visitCallableReferenceExpressionVoid(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, P data) {
|
||||
visitClassLiteralExpressionVoid(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression, P data) {
|
||||
visitDotQualifiedExpressionVoid(expression, data);
|
||||
|
||||
+21
-6
@@ -453,13 +453,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetTypeInfo visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, ExpressionTypingContext context) {
|
||||
JetTypeReference typeReference = expression.getTypeReference();
|
||||
public JetTypeInfo visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, ExpressionTypingContext context) {
|
||||
JetType receiverType = resolveDoubleColonExpressionType(expression, context);
|
||||
// TODO: forbid type parameters & generic classes
|
||||
ClassifierDescriptor classifier = receiverType.getConstructor().getDeclarationDescriptor();
|
||||
return JetTypeInfo.create(
|
||||
components.reflectionTypes.getKClassType(Annotations.EMPTY, (ClassDescriptor) classifier),
|
||||
context.dataFlowInfo
|
||||
);
|
||||
}
|
||||
|
||||
JetType receiverType =
|
||||
typeReference == null
|
||||
? null
|
||||
: components.expressionTypingServices.getTypeResolver().resolveType(context.scope, typeReference, context.trace, false);
|
||||
@Override
|
||||
public JetTypeInfo visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, ExpressionTypingContext context) {
|
||||
JetType receiverType = resolveDoubleColonExpressionType(expression, context);
|
||||
|
||||
JetSimpleNameExpression callableReference = expression.getCallableReference();
|
||||
if (callableReference.getReferencedName().isEmpty()) {
|
||||
@@ -472,6 +478,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return DataFlowUtils.checkType(result, expression, context, context.dataFlowInfo);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType resolveDoubleColonExpressionType(@NotNull JetDoubleColonExpression expression, ExpressionTypingContext context) {
|
||||
JetTypeReference typeReference = expression.getTypeReference();
|
||||
|
||||
return typeReference == null
|
||||
? null
|
||||
: components.expressionTypingServices.getTypeResolver().resolveType(context.scope, typeReference, context.trace, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType getCallableReferenceType(
|
||||
@NotNull JetCallableReferenceExpression expression,
|
||||
|
||||
@@ -16,15 +16,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.types.reflect
|
||||
|
||||
import kotlin.properties.Delegates
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import java.util.ArrayList
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
private val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
|
||||
|
||||
@@ -49,6 +50,7 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
|
||||
public fun getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n")
|
||||
public fun getKMemberFunction(n: Int): ClassDescriptor = find("KMemberFunction$n")
|
||||
|
||||
public val kClass: ClassDescriptor by ClassLookup
|
||||
public val kTopLevelVariable: ClassDescriptor by ClassLookup
|
||||
public val kMutableTopLevelVariable: ClassDescriptor by ClassLookup
|
||||
public val kMemberProperty: ClassDescriptor by ClassLookup
|
||||
@@ -56,6 +58,11 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
|
||||
public val kTopLevelExtensionProperty: ClassDescriptor by ClassLookup
|
||||
public val kMutableTopLevelExtensionProperty: ClassDescriptor by ClassLookup
|
||||
|
||||
public fun getKClassType(annotations: Annotations, classDescriptor: ClassDescriptor): JetType {
|
||||
val arguments = listOf(TypeProjectionImpl(Variance.INVARIANT, classDescriptor.getDefaultType()))
|
||||
return JetTypeImpl(annotations, kClass.getTypeConstructor(), false, arguments, kClass.getMemberScope(arguments))
|
||||
}
|
||||
|
||||
public fun getKFunctionType(
|
||||
annotations: Annotations,
|
||||
receiverType: JetType?,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class A
|
||||
|
||||
fun box(): String {
|
||||
val klass = A::class
|
||||
return if (klass.toString() == "class A") "OK" else "Fail: $klass"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import kotlin.reflect.jvm.*
|
||||
|
||||
class A
|
||||
|
||||
fun box(): String {
|
||||
val a1 = javaClass<A>().kotlin
|
||||
val a2 = A::class
|
||||
|
||||
if (a1 != a2) return "Fail equals"
|
||||
if (a1.hashCode() != a2.hashCode()) return "Fail hashCode"
|
||||
if (a1.toString() != a2.toString()) return "Fail toString"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class A
|
||||
|
||||
val k = A::class
|
||||
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
internal val k: kotlin.reflect.KClass<A>
|
||||
|
||||
internal final class A {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -28,6 +28,11 @@ fun ok() {
|
||||
a??::b
|
||||
a<b>?::c
|
||||
a<b?,c?>?::d
|
||||
|
||||
A::class
|
||||
a<b,c>::class
|
||||
::class
|
||||
a b ::class
|
||||
}
|
||||
|
||||
fun err0() {
|
||||
|
||||
@@ -464,6 +464,51 @@ JetFile: DoubleColon.kt
|
||||
PsiElement(COLONCOLON)('::')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('d')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
CLASS_LITERAL_EXPRESSION
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(COLONCOLON)('::')
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace('\n ')
|
||||
CLASS_LITERAL_EXPRESSION
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
TYPE_ARGUMENT_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PROJECTION
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(COMMA)(',')
|
||||
TYPE_PROJECTION
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('c')
|
||||
PsiElement(GT)('>')
|
||||
PsiElement(COLONCOLON)('::')
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace('\n ')
|
||||
CLASS_LITERAL_EXPRESSION
|
||||
PsiElement(COLONCOLON)('::')
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_LITERAL_EXPRESSION
|
||||
PsiElement(COLONCOLON)('::')
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
|
||||
+16
@@ -33,6 +33,7 @@ import java.util.regex.Pattern;
|
||||
@InnerTestClasses({
|
||||
JetDiagnosticsTestWithStdLibGenerated.Annotations.class,
|
||||
JetDiagnosticsTestWithStdLibGenerated.CallableReference.class,
|
||||
JetDiagnosticsTestWithStdLibGenerated.ClassLiteral.class,
|
||||
JetDiagnosticsTestWithStdLibGenerated.DuplicateJvmSignature.class,
|
||||
JetDiagnosticsTestWithStdLibGenerated.FunctionLiterals.class,
|
||||
JetDiagnosticsTestWithStdLibGenerated.Inference.class,
|
||||
@@ -598,6 +599,21 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/classLiteral")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassLiteral extends AbstractJetDiagnosticsTestWithStdLib {
|
||||
public void testAllFilesPresentInClassLiteral() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/classLiteral"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleClassLiteral.kt")
|
||||
public void testSimpleClassLiteral() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/classLiteral/simpleClassLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/duplicateJvmSignature")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+22
@@ -2524,6 +2524,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({
|
||||
Reflection.ClassLiterals.class,
|
||||
Reflection.Enclosing.class,
|
||||
Reflection.GenericSignature.class,
|
||||
Reflection.Mapping.class,
|
||||
@@ -2536,6 +2537,21 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassLiterals extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInClassLiterals() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleClassLiteral.kt")
|
||||
public void testSimpleClassLiteral() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/simpleClassLiteral.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -2712,6 +2728,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mappedClassIsEqualToClassLiteral.kt")
|
||||
public void testMappedClassIsEqualToClassLiteral() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/mappedClassIsEqualToClassLiteral.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberProperty.kt")
|
||||
public void testMemberProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/memberProperty.kt");
|
||||
|
||||
+5
@@ -178,6 +178,11 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
return newVar(name, initializer).source(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsNode visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, @NotNull TranslationContext context) {
|
||||
throw new UnsupportedOperationException("Class literals are not yet supported: " + expression.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, @NotNull TranslationContext context) {
|
||||
|
||||
Reference in New Issue
Block a user