Supporting Unit.VALUE, to replace #()

#KT-2358 In Progress
This commit is contained in:
Andrey Breslav
2012-09-18 12:20:23 +04:00
parent 83bc835343
commit dee5152f9b
16 changed files with 206 additions and 47 deletions
@@ -3367,7 +3367,7 @@ The "returned" value of try expression with no finally is either the last expres
throw new UnsupportedOperationException("tuple too large");
}
if (entries.size() == 0) {
v.visitFieldInsn(GETSTATIC, "jet/Tuple0", "INSTANCE", "Ljet/Tuple0;");
v.visitFieldInsn(GETSTATIC, "jet/Tuple0", "VALUE", "Ljet/Tuple0;");
return StackValue.onStack(JET_TUPLE0_TYPE);
}
@@ -310,7 +310,7 @@ public abstract class StackValue {
}
public static void putTuple0Instance(InstructionAdapter v) {
v.visitFieldInsn(GETSTATIC, "jet/Tuple0", "INSTANCE", "Ljet/Tuple0;");
v.visitFieldInsn(GETSTATIC, "jet/Tuple0", "VALUE", "Ljet/Tuple0;");
}
protected void putAsBoolean(InstructionAdapter v) {
@@ -148,16 +148,25 @@ public class IntrinsicMethods {
declareIntrinsicProperty(Name.identifier("CharSequence"), Name.identifier("length"), new StringLength());
declareIntrinsicProperty(Name.identifier("String"), Name.identifier("length"), new StringLength());
Name tuple0Name = JetStandardClasses.getTuple(0).getName();
intrinsicsMap.registerIntrinsic(
getClassObjectFqName(tuple0Name),
Name.identifier("VALUE"), -1, new UnitValue());
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
intrinsicsMap.registerIntrinsic(
JetStandardClasses.STANDARD_CLASSES_FQNAME.child(type.getRangeTypeName()).toUnsafe().child(
getClassObjectName(type.getRangeTypeName())),
getClassObjectFqName(type.getRangeTypeName()),
Name.identifier("EMPTY"), -1, new EmptyRange(type));
}
declareArrayMethods();
}
@NotNull
private static FqNameUnsafe getClassObjectFqName(@NotNull Name builtinClassName) {
return JetStandardClasses.STANDARD_CLASSES_FQNAME.child(builtinClassName).toUnsafe().child(getClassObjectName(builtinClassName));
}
private void declareArrayMethods() {
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2012 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.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.lang.psi.JetExpression;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JET_TUPLE0_TYPE;
/**
* @author abreslav
*/
public class UnitValue implements IntrinsicMethod {
@Override
public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
v.getstatic(JET_TUPLE0_TYPE.getInternalName(), "VALUE", JET_TUPLE0_TYPE.getDescriptor());
return StackValue.onStack(expectedType);
}
}
@@ -22,11 +22,10 @@ import java.io.PrintStream;
* @author abreslav
*/
public class TuplesAndFunctionsGenerator {
private static int TUPLE_COUNT = 23;
private static final int TUPLE_COUNT = 23;
private static void generateTuples(PrintStream out, int count) {
generated(out);
out.println("public class Tuple0() {}");
for (int i = 1; i < count; i++) {
out.print("public class Tuple" + i);
out.print("<");
-1
View File
@@ -3,7 +3,6 @@
package jet
public class Tuple0() {}
public class Tuple1<out T1>(public val _1: T1) {}
public class Tuple2<out T1, out T2>(public val _1: T1, public val _2: T2) {}
public class Tuple3<out T1, out T2, out T3>(public val _1: T1, public val _2: T2, public val _3: T3) {}
+7
View File
@@ -0,0 +1,7 @@
package jet
public class Tuple0 private () {
public class object {
public val VALUE: Tuple0
}
}
@@ -25,9 +25,11 @@ import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author abreslav
@@ -40,54 +42,54 @@ public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implem
private ConstructorDescriptor primaryConstructor;
private ReceiverDescriptor implicitReceiver;
private final Modality modality;
private ClassDescriptor classObjectDescriptor;
private final ClassKind kind;
public ClassDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
@NotNull Modality modality,
@NotNull Name name
) {
this(containingDeclaration, ClassKind.CLASS, annotations, modality, name);
}
public ClassDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull ClassKind kind,
@NotNull List<AnnotationDescriptor> annotations,
@NotNull Modality modality,
@NotNull Name name) {
super(containingDeclaration, annotations, name);
this.kind = kind;
this.modality = modality;
}
public final ClassDescriptorImpl initialize(boolean sealed,
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull Collection<JetType> supertypes,
@NotNull JetScope memberDeclarations,
@NotNull Set<ConstructorDescriptor> constructors,
@Nullable ConstructorDescriptor primaryConstructor) {
return initialize(sealed, typeParameters, supertypes, memberDeclarations, constructors, primaryConstructor, getClassType(supertypes));
}
public final ClassDescriptorImpl initialize(boolean sealed,
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull Collection<JetType> supertypes,
@NotNull JetScope memberDeclarations,
@NotNull Set<ConstructorDescriptor> constructors,
@Nullable ConstructorDescriptor primaryConstructor,
@Nullable JetType superclassType) {
public final ClassDescriptorImpl initialize(
boolean sealed,
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull Collection<JetType> supertypes,
@NotNull JetScope memberDeclarations,
@NotNull Set<ConstructorDescriptor> constructors,
@Nullable ConstructorDescriptor primaryConstructor
) {
this.typeConstructor = new TypeConstructorImpl(this, getAnnotations(), sealed, getName().getName(), typeParameters, supertypes);
this.memberDeclarations = memberDeclarations;
this.constructors = constructors;
this.primaryConstructor = primaryConstructor;
this.classObjectDescriptor = classObjectDescriptor;
return this;
}
@NotNull
private JetType getClassType(@NotNull Collection<JetType> types) {
for (JetType type : types) {
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(type);
if (classDescriptor != null) {
return type;
}
}
return JetStandardClasses.getAnyType();
}
public void setPrimaryConstructor(@NotNull ConstructorDescriptor primaryConstructor) {
this.primaryConstructor = primaryConstructor;
}
public void setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) {
this.classObjectDescriptor = classObjectDescriptor;
}
@Override
@NotNull
public TypeConstructor getTypeConstructor() {
@@ -126,18 +128,18 @@ public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implem
@Override
public JetType getClassObjectType() {
return null;
return getClassObjectDescriptor().getDefaultType();
}
@Override
public ClassDescriptor getClassObjectDescriptor() {
return null;
return classObjectDescriptor;
}
@NotNull
@Override
public ClassKind getKind() {
return ClassKind.CLASS;
return kind;
}
@Override
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
@@ -91,7 +92,6 @@ public class JetStandardClasses {
},
JetScope.EMPTY,
Collections.<ConstructorDescriptor>singleton(constructorDescriptor),
null,
null
);
NOTHING_TYPE = new JetTypeImpl(getNothing());
@@ -125,7 +125,6 @@ public class JetStandardClasses {
Collections.<JetType>emptySet(),
JetScope.EMPTY,
Collections.<ConstructorDescriptor>singleton(constructorDescriptor),
null,
null
);
ANY_TYPE = new JetTypeImpl(ANY.getTypeConstructor(), new JetScopeImpl() {
@@ -201,14 +200,84 @@ public class JetStandardClasses {
writableScope,
Collections.<ConstructorDescriptor>singleton(constructorDescriptor),
null);
if (i == 0) {
// Unit.VALUE
classDescriptor.setClassObjectDescriptor(createClassObjectForUnit(classDescriptor));
}
TUPLE_CONSTRUCTORS.add(TUPLE[i].getTypeConstructor());
constructorDescriptor.initialize(classDescriptor.getTypeConstructor().getParameters(), constructorValueParameters, Visibilities.PUBLIC);
constructorDescriptor.initialize(classDescriptor.getTypeConstructor().getParameters(), constructorValueParameters, i == 0 ? Visibilities.PRIVATE : Visibilities.PUBLIC);
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
private static ClassDescriptor createClassObjectForUnit(@NotNull ClassDescriptorImpl unitClass) {
ClassDescriptorImpl classObjectDescriptor = new ClassDescriptorImpl(
unitClass,
ClassKind.CLASS_OBJECT,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
DescriptorUtils.getClassObjectName(unitClass.getName())
);
WritableScopeImpl classObjectMemberScope = new WritableScopeImpl(
JetScope.EMPTY,
classObjectDescriptor,
RedeclarationHandler.DO_NOTHING,
"Unit class object members"
);
PropertyDescriptor valueProperty = createUnitValueProperty(unitClass, classObjectDescriptor);
classObjectMemberScope.addPropertyDescriptor(valueProperty);
classObjectMemberScope.changeLockLevel(WritableScope.LockLevel.READING);
ConstructorDescriptorImpl classObjectConstructorDescriptor = new ConstructorDescriptorImpl(classObjectDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
classObjectConstructorDescriptor.initialize(
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<ValueParameterDescriptor>emptyList(),
Visibilities.PRIVATE
);
classObjectDescriptor.initialize(
/*sealed = */ true,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.singleton(getAnyType()),
classObjectMemberScope,
Collections.<ConstructorDescriptor>singleton(classObjectConstructorDescriptor),
classObjectConstructorDescriptor
);
classObjectConstructorDescriptor.setReturnType(classObjectDescriptor.getDefaultType());
return classObjectDescriptor;
}
@NotNull
private static PropertyDescriptor createUnitValueProperty(
@NotNull ClassDescriptorImpl unitClass,
@NotNull ClassDescriptorImpl unitClassObject
) {
PropertyDescriptor valueProperty = new PropertyDescriptor(
unitClassObject,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Visibilities.PUBLIC,
/*isVar = */ false,
Name.identifier("VALUE"),
CallableMemberDescriptor.Kind.DECLARATION);
valueProperty.setType(
unitClass.getDefaultType(),
Collections.<TypeParameterDescriptor>emptyList(),
unitClassObject.getImplicitReceiver(),
ReceiverDescriptor.NO_RECEIVER);
PropertyGetterDescriptor getter = DescriptorResolver.createDefaultGetter(valueProperty);
getter.initialize(unitClass.getDefaultType());
valueProperty.initialize(getter, null);
return valueProperty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static final int MAX_FUNCTION_ORDER = 22;
+5 -1
View File
@@ -1123,7 +1123,11 @@ public open class jet.Throwable : jet.Any {
public final fun printStackTrace(): jet.Tuple0
}
public final class jet.Tuple0 : jet.Any {
public final /*constructor*/ fun <init>(): jet.Tuple0
private final /*constructor*/ fun <init>(): jet.Tuple0
public final class object jet.Tuple0.<class-object-for-Tuple0> : jet.Any {
private final /*constructor*/ fun <init>(): jet.Tuple0.<class-object-for-Tuple0>
public final val VALUE: jet.Tuple0
}
}
public final class jet.Tuple1</*0*/ out T1 : jet.Any?> : jet.Any {
public final /*constructor*/ fun </*0*/ out T1 : jet.Any?><init>(/*0*/ _1: T1): jet.Tuple1<T1>
@@ -0,0 +1,5 @@
fun foo() {}
fun box(): String {
return if (foo() == Unit.VALUE) "OK" else "Fail"
}
@@ -0,0 +1,3 @@
fun test() {
return Unit.VALUE : Unit
}
@@ -3278,6 +3278,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/tuples/BasicTuples.kt");
}
@TestMetadata("UnitValue.kt")
public void testUnitValue() throws Exception {
doTest("compiler/testData/diagnostics/tests/tuples/UnitValue.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/varargs")
@@ -22,6 +22,12 @@ public class TupleGenTest extends CodegenTestCase {
public void testBasic() {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("/tuples/basic.jet");
// System.out.println(generateToText());
}
public void testUnitValue() {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("/tuples/UnitValue.kt");
// System.out.println(generateToText());
}
}
+1 -1
View File
@@ -58,7 +58,7 @@ public class StringTemplate {
@Override
public Tuple0 invoke(Object o) {
builder.append(o);
return Tuple0.INSTANCE;
return Tuple0.VALUE;
}
});
return builder.toString();
+3 -3
View File
@@ -23,19 +23,19 @@ import org.jetbrains.jet.rt.annotation.AssertInvisibleInResolver;
*/
@AssertInvisibleInResolver
public class Tuple0 extends Tuple {
public static final Tuple0 INSTANCE = new Tuple0();
public static final Tuple0 VALUE = new Tuple0();
private Tuple0() {
}
@Override
public String toString() {
return "()";
return "Unit.VALUE";
}
@Override
public boolean equals(Object o) {
return o == INSTANCE;
return o == VALUE;
}
@Override