KT-602: Array<T> method instead of default constructor parameter
This commit is contained in:
@@ -10,6 +10,7 @@ import org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author max
|
* @author max
|
||||||
@@ -38,6 +39,8 @@ public abstract class CodegenContext {
|
|||||||
public final ObjectOrClosureCodegen closure;
|
public final ObjectOrClosureCodegen closure;
|
||||||
|
|
||||||
HashMap<JetType,Integer> typeInfoConstants;
|
HashMap<JetType,Integer> typeInfoConstants;
|
||||||
|
HashMap<Integer,JetType> reverseTypeInfoConstants;
|
||||||
|
int typeInfoConstantsCount;
|
||||||
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
||||||
|
|
||||||
protected StackValue outerExpression;
|
protected StackValue outerExpression;
|
||||||
@@ -177,13 +180,16 @@ public abstract class CodegenContext {
|
|||||||
if(parentContext != STATIC)
|
if(parentContext != STATIC)
|
||||||
return parentContext.getTypeInfoConstantIndex(type);
|
return parentContext.getTypeInfoConstantIndex(type);
|
||||||
|
|
||||||
if(typeInfoConstants == null)
|
if(typeInfoConstants == null) {
|
||||||
typeInfoConstants = new HashMap<JetType, Integer>();
|
typeInfoConstants = new LinkedHashMap<JetType, Integer>();
|
||||||
|
reverseTypeInfoConstants = new LinkedHashMap<Integer, JetType>();
|
||||||
|
}
|
||||||
|
|
||||||
Integer index = typeInfoConstants.get(type);
|
Integer index = typeInfoConstants.get(type);
|
||||||
if(index == null) {
|
if(index == null) {
|
||||||
index = typeInfoConstants.size();
|
index = typeInfoConstantsCount++;
|
||||||
typeInfoConstants.put(type, index);
|
typeInfoConstants.put(type, index);
|
||||||
|
reverseTypeInfoConstants.put(index, type);
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2068,14 +2068,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateNewArray(JetCallExpression expression, JetType arrayType) {
|
public void generateNewArray(JetCallExpression expression, JetType arrayType) {
|
||||||
List<? extends ValueArgument> args = expression.getValueArguments();
|
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||||
|
|
||||||
boolean isArray = state.getStandardLibrary().getArray().equals(arrayType.getConstructor().getDeclarationDescriptor());
|
boolean isArray = state.getStandardLibrary().getArray().equals(arrayType.getConstructor().getDeclarationDescriptor());
|
||||||
if(isArray) {
|
if(isArray) {
|
||||||
if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) {
|
// if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) {
|
||||||
throw new CompilationException("array constructor of non-nullable type requires two arguments");
|
// throw new CompilationException("array constructor of non-nullable type requires two arguments");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (args.size() != 1) {
|
if (args.size() != 1) {
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ import org.objectweb.asm.Label;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
import sun.jvm.hotspot.debugger.LongHashMap;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -114,11 +116,12 @@ public class NamespaceCodegen {
|
|||||||
private void generateTypeInfoFields(JetNamespace namespace, CodegenContext context) {
|
private void generateTypeInfoFields(JetNamespace namespace, CodegenContext context) {
|
||||||
if(context.typeInfoConstants != null) {
|
if(context.typeInfoConstants != null) {
|
||||||
String jvmClassName = getJVMClassName(namespace.getName());
|
String jvmClassName = getJVMClassName(namespace.getName());
|
||||||
for(Map.Entry<JetType,Integer> e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.<JetType,Integer>emptyMap()).entrySet()) {
|
for(int index = 0; index != context.typeInfoConstantsCount; index++) {
|
||||||
String fieldName = "$typeInfoCache$" + e.getValue();
|
JetType type = context.reverseTypeInfoConstants.get(index);
|
||||||
|
String fieldName = "$typeInfoCache$" + index;
|
||||||
v.newField(null, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, fieldName, "Ljet/typeinfo/TypeInfo;", null, null);
|
v.newField(null, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, fieldName, "Ljet/typeinfo/TypeInfo;", null, null);
|
||||||
|
|
||||||
MethodVisitor mmv = v.newMethod(null, ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "$getCachedTypeInfo$" + e.getValue(), "()Ljet/typeinfo/TypeInfo;", null, null);
|
MethodVisitor mmv = v.newMethod(null, ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "$getCachedTypeInfo$" + index, "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||||
InstructionAdapter v = new InstructionAdapter(mmv);
|
InstructionAdapter v = new InstructionAdapter(mmv);
|
||||||
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
||||||
v.visitInsn(DUP);
|
v.visitInsn(DUP);
|
||||||
@@ -126,7 +129,7 @@ public class NamespaceCodegen {
|
|||||||
v.visitJumpInsn(IFNONNULL, end);
|
v.visitJumpInsn(IFNONNULL, end);
|
||||||
|
|
||||||
v.pop();
|
v.pop();
|
||||||
generateTypeInfo(context, v, e.getKey(), state.getTypeMapper(), e.getKey());
|
generateTypeInfo(context, v, type, state.getTypeMapper(), type);
|
||||||
v.dup();
|
v.dup();
|
||||||
|
|
||||||
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.jetbrains.jet.plugin.JetFileType;
|
import org.jetbrains.jet.plugin.JetFileType;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import sun.tools.tree.NewArrayExpression;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -85,6 +86,7 @@ public class IntrinsicMethods {
|
|||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
|
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
|
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
||||||
|
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
||||||
|
|
||||||
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
||||||
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class NewArray implements IntrinsicMethod {
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||||
|
codegen.generateNewArray((JetCallExpression) element, codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, (JetExpression) element));
|
||||||
|
return StackValue.onStack(expectedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,7 +105,9 @@ trait Iterable<out T> {
|
|||||||
fun iterator() : Iterator<T>
|
fun iterator() : Iterator<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
class Array<T>(val size : Int, init : fun(Int) : T = null ) {
|
fun Array<T>(val size : Int) : Array<T?>
|
||||||
|
|
||||||
|
class Array<T>(val size : Int, init : fun(Int) : T) {
|
||||||
fun get(index : Int) : T
|
fun get(index : Int) : T
|
||||||
fun set(index : Int, value : T) : Unit
|
fun set(index : Int, value : T) : Unit
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
fun box() = if(Array<Int>(10) is Array<java.lang.Integer>) "OK" else "fail"
|
||||||
@@ -276,6 +276,10 @@ public class ArrayGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("regressions/kt503.jet");
|
blackBoxFile("regressions/kt503.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt602() {
|
||||||
|
blackBoxFile("regressions/kt602.jet");
|
||||||
|
}
|
||||||
|
|
||||||
public void testKt594() throws Exception {
|
public void testKt594() throws Exception {
|
||||||
loadFile("regressions/kt594.jet");
|
loadFile("regressions/kt594.jet");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
|
|||||||
Reference in New Issue
Block a user