Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -8,3 +8,4 @@ out
|
|||||||
.idea/codeStyleSettings.xml
|
.idea/codeStyleSettings.xml
|
||||||
.idea/workspace.xml
|
.idea/workspace.xml
|
||||||
tmp
|
tmp
|
||||||
|
*TestMy.java
|
||||||
|
|||||||
Generated
+1
@@ -12,6 +12,7 @@
|
|||||||
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" />
|
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" />
|
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
|
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/testlib/testlib.iml" filepath="$PROJECT_DIR$/testlib/testlib.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -126,9 +126,7 @@ public abstract class ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(v, "static initializer", myClass);
|
||||||
|
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,8 +147,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
|
|
||||||
mv.visitLabel(ret);
|
mv.visitLabel(ret);
|
||||||
mv.visitInsn(ARETURN);
|
mv.visitInsn(ARETURN);
|
||||||
mv.visitMaxs(0,0);
|
FunctionCodegen.endVisit(mv, "$getInstance", fun);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,8 +204,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
|
|
||||||
iv.areturn(JetTypeMapper.TYPE_OBJECT);
|
iv.areturn(JetTypeMapper.TYPE_OBJECT);
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(mv, "bridge", fun);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,8 +284,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
|
|
||||||
iv.visitInsn(RETURN);
|
iv.visitInsn(RETURN);
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(iv, "constructor", fun);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
return constructor;
|
return constructor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class CompilationException extends RuntimeException {
|
||||||
|
private PsiElement element;
|
||||||
|
|
||||||
|
CompilationException(String message, Throwable cause, PsiElement element) {
|
||||||
|
super(message, cause);
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PsiElement getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -130,7 +130,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
public StackValue genQualified(StackValue receiver, JetElement selector) {
|
public StackValue genQualified(StackValue receiver, JetElement selector) {
|
||||||
markLineNumber(selector);
|
markLineNumber(selector);
|
||||||
return selector.accept(this, receiver);
|
try {
|
||||||
|
return selector.accept(this, receiver);
|
||||||
|
}
|
||||||
|
catch(CompilationException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch (Throwable error) {
|
||||||
|
throw new CompilationException(error.getMessage(), error, selector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public StackValue gen(JetElement expr) {
|
public StackValue gen(JetElement expr) {
|
||||||
@@ -204,7 +212,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
JetExpression elseExpression = expression.getElse();
|
JetExpression elseExpression = expression.getElse();
|
||||||
|
|
||||||
if (thenExpression == null && elseExpression == null) {
|
if (thenExpression == null && elseExpression == null) {
|
||||||
throw new CompilationException();
|
throw new CompilationException("Both brunches of if/else are null", null, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEmptyExpression(thenExpression)) {
|
if (isEmptyExpression(thenExpression)) {
|
||||||
@@ -225,6 +233,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
condition.condJump(elseLabel, true, v); // == 0, i.e. false
|
condition.condJump(elseLabel, true, v); // == 0, i.e. false
|
||||||
|
|
||||||
Label end = continueLabel == null ? new Label() : continueLabel;
|
Label end = continueLabel == null ? new Label() : continueLabel;
|
||||||
|
|
||||||
|
if(continueLabel != null)
|
||||||
|
asmType = Type.VOID_TYPE;
|
||||||
|
|
||||||
gen(thenExpression, asmType);
|
gen(thenExpression, asmType);
|
||||||
|
|
||||||
@@ -1126,7 +1137,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, callee);
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, callee);
|
||||||
if(resolvedCall == null) {
|
if(resolvedCall == null) {
|
||||||
throw new CompilationException("Cannot resolve: " + callee.getText());
|
throw new CompilationException("Cannot resolve: " + callee.getText(), null, expression);
|
||||||
}
|
}
|
||||||
receiver = StackValue.receiver(resolvedCall, receiver, this, null);
|
receiver = StackValue.receiver(resolvedCall, receiver, this, null);
|
||||||
|
|
||||||
@@ -1403,7 +1414,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
public int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
||||||
if(resolvedCall != null) {
|
if(resolvedCall != null) {
|
||||||
return pushMethodArguments(resolvedCall, valueParameterTypes);
|
return pushMethodArguments(resolvedCall, valueParameterTypes);
|
||||||
@@ -2074,7 +2085,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, callee);
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, callee);
|
||||||
if(resolvedCall == null) {
|
if(resolvedCall == null) {
|
||||||
assert callee != null;
|
assert callee != null;
|
||||||
throw new CompilationException("Cannot resolve: " + callee.getText());
|
throw new CompilationException("Cannot resolve: " + callee.getText(), null, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||||
@@ -2098,7 +2109,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (args.size() != 1) {
|
if (args.size() != 1) {
|
||||||
throw new CompilationException("primitive array constructor requires one argument");
|
throw new CompilationException("primitive array constructor requires one argument", null, expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2784,15 +2795,6 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
v.athrow();
|
v.athrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CompilationException extends RuntimeException {
|
|
||||||
private CompilationException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompilationException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return context.getContextDescriptor().toString();
|
return context.getContextDescriptor().toString();
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ public class FunctionCodegen {
|
|||||||
if(receiverParameter.getType().isNullable()) {
|
if(receiverParameter.getType().isNullable()) {
|
||||||
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
||||||
}
|
}
|
||||||
|
av.visit(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
|
||||||
av.visitEnd();
|
av.visitEnd();
|
||||||
}
|
}
|
||||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||||
@@ -223,7 +224,7 @@ public class FunctionCodegen {
|
|||||||
k += type.getSize();
|
k += type.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
endVisit(mv, null, fun);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
|
|
||||||
generateBridgeIfNeeded(owner, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind);
|
generateBridgeIfNeeded(owner, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind);
|
||||||
@@ -233,6 +234,16 @@ public class FunctionCodegen {
|
|||||||
generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind);
|
generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void endVisit(MethodVisitor mv, String description, PsiElement method) {
|
||||||
|
try {
|
||||||
|
mv.visitMaxs(0, 0);
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
throw new CompilationException("wrong code generated" + (description != null ? " for " + description : "") + t.getClass().getName() + " " + t.getMessage(), t, method);
|
||||||
|
}
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
static void generateBridgeIfNeeded(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
static void generateBridgeIfNeeded(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||||
Set<? extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenDescriptors();
|
Set<? extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenDescriptors();
|
||||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||||
@@ -390,7 +401,7 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
iv.areturn(jvmSignature.getReturnType());
|
iv.areturn(jvmSignature.getReturnType());
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
endVisit(mv, "default method", state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, functionDescriptor));
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -426,7 +437,7 @@ public class FunctionCodegen {
|
|||||||
if(jvmSignature.getReturnType() == Type.VOID_TYPE)
|
if(jvmSignature.getReturnType() == Type.VOID_TYPE)
|
||||||
iv.aconst(null);
|
iv.aconst(null);
|
||||||
iv.areturn(overriden.getReturnType());
|
iv.areturn(overriden.getReturnType());
|
||||||
mv.visitMaxs(0, 0);
|
endVisit(mv, "bridge method", state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, functionDescriptor));
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,8 +198,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
||||||
|
|
||||||
iv.areturn(method.getReturnType());
|
iv.areturn(method.getReturnType());
|
||||||
mv.visitMaxs(0,0);
|
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(entry.getValue() instanceof PropertyDescriptor) {
|
else if(entry.getValue() instanceof PropertyDescriptor) {
|
||||||
@@ -222,8 +221,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
||||||
|
|
||||||
iv.areturn(method.getReturnType());
|
iv.areturn(method.getReturnType());
|
||||||
mv.visitMaxs(0,0);
|
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getAsmMethod();
|
method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getAsmMethod();
|
||||||
@@ -248,8 +246,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
|
||||||
|
|
||||||
iv.areturn(method.getReturnType());
|
iv.areturn(method.getReturnType());
|
||||||
mv.visitMaxs(0,0);
|
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -465,8 +462,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
outer.visitVarInsn(Opcodes.ALOAD, 0);
|
outer.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
outer.visitFieldInsn(Opcodes.GETFIELD, classname, "this$0", outerType.getDescriptor());
|
outer.visitFieldInsn(Opcodes.GETFIELD, classname, "this$0", outerType.getDescriptor());
|
||||||
outer.visitInsn(Opcodes.ARETURN);
|
outer.visitInsn(Opcodes.ARETURN);
|
||||||
outer.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(outer, "getOuterObject", myClass);
|
||||||
outer.visitEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
|
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
|
||||||
@@ -518,8 +514,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
generateTraitMethods(codegen);
|
generateTraitMethods(codegen);
|
||||||
|
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(mv, "constructor", myClass);
|
||||||
mv.visitEnd();
|
|
||||||
|
|
||||||
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod, constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod, constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
}
|
}
|
||||||
@@ -572,8 +567,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.checkcast(function.getReturnType());
|
iv.checkcast(function.getReturnType());
|
||||||
}
|
}
|
||||||
iv.areturn(function.getReturnType());
|
iv.areturn(function.getReturnType());
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(iv, "trait method", bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, fun));
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCodegen.generateBridgeIfNeeded(context, state, v, function, fun, kind);
|
FunctionCodegen.generateBridgeIfNeeded(context, state, v, function, fun, kind);
|
||||||
@@ -708,8 +702,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(mv, "constructor", null);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,8 +814,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
iv.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
iv.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(iv, "getTypeInfo", myClass);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null);
|
mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null);
|
||||||
@@ -834,8 +826,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.putfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
iv.putfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(iv, "$setTypeInfo", myClass);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -853,8 +844,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||||
v.getstatic(owner, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
v.getstatic(owner, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(v, "getTypeInfo", myClass);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ public class JetTypeMapper {
|
|||||||
private final HashMap<JetType,String> knowTypeNames = new HashMap<JetType, String>();
|
private final HashMap<JetType,String> knowTypeNames = new HashMap<JetType, String>();
|
||||||
private final HashMap<JetType,Type> knowTypes = new HashMap<JetType, Type>();
|
private final HashMap<JetType,Type> knowTypes = new HashMap<JetType, Type>();
|
||||||
|
|
||||||
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
|
||||||
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
|
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
|
||||||
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
|
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
|
||||||
public static final Type TYPE_SHARED_VAR = Type.getObjectType("jet/runtime/SharedVar$Object");
|
public static final Type TYPE_SHARED_VAR = Type.getObjectType("jet/runtime/SharedVar$Object");
|
||||||
@@ -86,6 +85,8 @@ public class JetTypeMapper {
|
|||||||
public static final Type TYPE_LONG_ITERATOR = Type.getObjectType("jet/LongIterator");
|
public static final Type TYPE_LONG_ITERATOR = Type.getObjectType("jet/LongIterator");
|
||||||
public static final Type TYPE_FLOAT_ITERATOR = Type.getObjectType("jet/FloatIterator");
|
public static final Type TYPE_FLOAT_ITERATOR = Type.getObjectType("jet/FloatIterator");
|
||||||
public static final Type TYPE_DOUBLE_ITERATOR = Type.getObjectType("jet/DoubleIterator");
|
public static final Type TYPE_DOUBLE_ITERATOR = Type.getObjectType("jet/DoubleIterator");
|
||||||
|
public static final Type TYPE_FUNCTION0 = Type.getObjectType("jet/Function0");
|
||||||
|
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
||||||
|
|
||||||
public JetStandardLibrary getStandardLibrary() {
|
public JetStandardLibrary getStandardLibrary() {
|
||||||
return standardLibrary;
|
return standardLibrary;
|
||||||
@@ -557,7 +558,10 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "extends Object" seems to be not optional according to ClassFileFormat-Java5.pdf
|
// "extends Object" is optional according to ClassFileFormat-Java5.pdf
|
||||||
|
// but javac complaints to signature:
|
||||||
|
// <P:>Ljava/lang/Object;
|
||||||
|
// TODO: avoid writing java/lang/Object if interface list is not empty
|
||||||
}
|
}
|
||||||
signatureVisitor.writeClassBoundEnd();
|
signatureVisitor.writeClassBoundEnd();
|
||||||
|
|
||||||
|
|||||||
@@ -62,8 +62,11 @@ public class NamespaceCodegen {
|
|||||||
else if (declaration instanceof JetNamedFunction) {
|
else if (declaration instanceof JetNamedFunction) {
|
||||||
try {
|
try {
|
||||||
functionCodegen.gen((JetNamedFunction) declaration);
|
functionCodegen.gen((JetNamedFunction) declaration);
|
||||||
} catch (Exception e) {
|
} catch (CompilationException e) {
|
||||||
throw new RuntimeException("Failed to generate function " + declaration.getName(), e);
|
throw e;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new CompilationException("Failed to generate function " + declaration.getName(), e, declaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetClassOrObject) {
|
else if (declaration instanceof JetClassOrObject) {
|
||||||
@@ -107,7 +110,7 @@ public class NamespaceCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(mv, "static initializer for namespace", namespace);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,8 +137,7 @@ public class NamespaceCodegen {
|
|||||||
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
||||||
v.visitLabel(end);
|
v.visitLabel(end);
|
||||||
v.visitInsn(ARETURN);
|
v.visitInsn(ARETURN);
|
||||||
v.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(v, "type info method", namespace);
|
||||||
v.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,8 +154,7 @@ public class PropertyCodegen {
|
|||||||
type.getDescriptor());
|
type.getDescriptor());
|
||||||
}
|
}
|
||||||
iv.areturn(type);
|
iv.areturn(type);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(mv, "getter", origin);
|
||||||
mv.visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +206,7 @@ public class PropertyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
iv.visitInsn(Opcodes.RETURN);
|
iv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
FunctionCodegen.endVisit(mv, "setter", origin);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public class IntrinsicMethods {
|
public class IntrinsicMethods {
|
||||||
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
||||||
@@ -89,6 +90,7 @@ public class IntrinsicMethods {
|
|||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure());
|
||||||
|
declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 1, new StupidSync());
|
||||||
|
|
||||||
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,26 @@
|
|||||||
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
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.objectweb.asm.Label;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StupidSync implements IntrinsicMethod {
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver) {
|
||||||
|
receiver.put(receiver.type, v);
|
||||||
|
codegen.pushMethodArguments((JetCallExpression)element, Arrays.asList(JetTypeMapper.TYPE_FUNCTION0));
|
||||||
|
v.invokestatic("jet/runtime/Intrinsics", "stupidSync", "(Ljava/lang/Object;Ljet/Function0;)Ljava/lang/Object;");
|
||||||
|
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v);
|
||||||
|
return StackValue.onStack(expectedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
+267
-123
@@ -9,6 +9,7 @@ import com.intellij.psi.*;
|
|||||||
import com.intellij.psi.search.DelegatingGlobalSearchScope;
|
import com.intellij.psi.search.DelegatingGlobalSearchScope;
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
import jet.typeinfo.TypeInfoVariance;
|
import jet.typeinfo.TypeInfoVariance;
|
||||||
|
import org.eclipse.jdt.internal.core.JavaModelManager;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
@@ -56,9 +57,38 @@ public class JavaDescriptorResolver {
|
|||||||
return visitor.visitDeclarationDescriptor(this, data);
|
return visitor.visitDeclarationDescriptor(this, data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private enum TypeParameterDescriptorOrigin {
|
||||||
|
JAVA,
|
||||||
|
KOTLIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TypeParameterDescriptorInitialization {
|
||||||
|
private final TypeParameterDescriptorOrigin origin;
|
||||||
|
private final TypeParameterDescriptor descriptor;
|
||||||
|
@Nullable
|
||||||
|
private final List<JetType> upperBoundsForKotlin;
|
||||||
|
@Nullable
|
||||||
|
private final List<JetType> lowerBoundsForKotlin;
|
||||||
|
|
||||||
|
private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor) {
|
||||||
|
this.origin = TypeParameterDescriptorOrigin.JAVA;
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
this.upperBoundsForKotlin = null;
|
||||||
|
this.lowerBoundsForKotlin = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor,
|
||||||
|
List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
|
||||||
|
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
this.upperBoundsForKotlin = upperBoundsForKotlin;
|
||||||
|
this.lowerBoundsForKotlin = lowerBoundsForKotlin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected final Map<String, ClassDescriptor> classDescriptorCache = Maps.newHashMap();
|
protected final Map<String, ClassDescriptor> classDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
|
protected final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
|
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
|
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<PsiElement, NamespaceDescriptor> namespaceDescriptorCache = Maps.newHashMap();
|
protected final Map<PsiElement, NamespaceDescriptor> namespaceDescriptorCache = Maps.newHashMap();
|
||||||
@@ -145,11 +175,8 @@ public class JavaDescriptorResolver {
|
|||||||
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
|
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
|
||||||
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
|
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
|
||||||
|
|
||||||
// TODO: initialize
|
// UGLY HACK (Andrey Breslav is not sure what did he mean)
|
||||||
if (psiClass.getModifierList().findAnnotation(StdlibNames.JET_CLASS.getFqName()) == null) {
|
initializeTypeParameters(psiClass);
|
||||||
// UGLY HACK (Andrey Breslav is not sure what did he mean)
|
|
||||||
initializeTypeParameters(psiClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
supertypes.addAll(getSupertypes(psiClass));
|
supertypes.addAll(getSupertypes(psiClass));
|
||||||
if (psiClass.isInterface()) {
|
if (psiClass.isInterface()) {
|
||||||
@@ -188,7 +215,11 @@ public class JavaDescriptorResolver {
|
|||||||
classDescriptor,
|
classDescriptor,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
false);
|
false);
|
||||||
constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), Modality.FINAL,
|
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters());
|
||||||
|
if (valueParameterDescriptors.receiverType != null) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors, Modality.FINAL,
|
||||||
resolveVisibilityFromPsiModifiers(constructor));
|
resolveVisibilityFromPsiModifiers(constructor));
|
||||||
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
|
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
|
||||||
classDescriptor.addConstructor(constructorDescriptor);
|
classDescriptor.addConstructor(constructorDescriptor);
|
||||||
@@ -208,7 +239,7 @@ public class JavaDescriptorResolver {
|
|||||||
if (attributeValue != null) {
|
if (attributeValue != null) {
|
||||||
String typeParametersString = (String) attributeValue.getValue();
|
String typeParametersString = (String) attributeValue.getValue();
|
||||||
if (typeParametersString != null) {
|
if (typeParametersString != null) {
|
||||||
return resolveClassTypeParametersFromJetSignature(typeParametersString, classDescriptor);
|
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,49 +247,107 @@ public class JavaDescriptorResolver {
|
|||||||
return makeUninitializedTypeParameters(classDescriptor, psiClass.getTypeParameters());
|
return makeUninitializedTypeParameters(classDescriptor, psiClass.getTypeParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) {
|
||||||
|
for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) {
|
||||||
|
if (typeParameter.getName().equals(name)) {
|
||||||
|
return typeParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// cache
|
||||||
|
protected ClassDescriptor javaLangObject;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private ClassDescriptor getJavaLangObject() {
|
||||||
|
if (javaLangObject == null) {
|
||||||
|
javaLangObject = resolveClass("java.lang.Object");
|
||||||
|
}
|
||||||
|
return javaLangObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isJavaLangObject(JetType type) {
|
||||||
|
return type.getConstructor().getDeclarationDescriptor() == getJavaLangObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter {
|
||||||
|
|
||||||
|
private final DeclarationDescriptor containingDeclaration;
|
||||||
|
private final PsiTypeParameterListOwner psiOwner;
|
||||||
|
private final String name;
|
||||||
|
private final TypeInfoVariance variance;
|
||||||
|
|
||||||
|
protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner,
|
||||||
|
String name, TypeInfoVariance variance)
|
||||||
|
{
|
||||||
|
this.containingDeclaration = containingDeclaration;
|
||||||
|
this.psiOwner = psiOwner;
|
||||||
|
this.name = name;
|
||||||
|
this.variance = variance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
List<JetType> upperBounds = new ArrayList<JetType>();
|
||||||
|
List<JetType> lowerBounds = new ArrayList<JetType>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetSignatureVisitor visitClassBound() {
|
||||||
|
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
||||||
|
@Override
|
||||||
|
protected void done(@NotNull JetType jetType) {
|
||||||
|
if (isJavaLangObject(jetType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
upperBounds.add(jetType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetSignatureVisitor visitInterfaceBound() {
|
||||||
|
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
||||||
|
@Override
|
||||||
|
protected void done(@NotNull JetType jetType) {
|
||||||
|
upperBounds.add(jetType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFormalTypeParameterEnd() {
|
||||||
|
TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification(
|
||||||
|
containingDeclaration,
|
||||||
|
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
|
||||||
|
true, // TODO: wrong
|
||||||
|
JetSignatureUtils.translateVariance(variance),
|
||||||
|
name,
|
||||||
|
++index);
|
||||||
|
PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name);
|
||||||
|
typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameter, upperBounds, lowerBounds));
|
||||||
|
done(typeParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void done(TypeParameterDescriptor typeParameterDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor)
|
* @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor)
|
||||||
*/
|
*/
|
||||||
private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final JavaClassDescriptor classDescriptor) {
|
private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, final JavaClassDescriptor classDescriptor) {
|
||||||
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
||||||
new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
|
new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
||||||
return new JetSignatureExceptionsAdapter() {
|
return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance) {
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitClassBound() {
|
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
r.add(typeParameterDescriptor);
|
||||||
@Override
|
|
||||||
protected void done(@NotNull JetType jetType) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetSignatureVisitor visitInterfaceBound() {
|
|
||||||
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
|
||||||
@Override
|
|
||||||
protected void done(@NotNull JetType jetType) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitFormalTypeParameterEnd() {
|
|
||||||
TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification(
|
|
||||||
classDescriptor,
|
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
|
|
||||||
true, // TODO: wrong
|
|
||||||
JetSignatureUtils.translateVariance(variance),
|
|
||||||
name,
|
|
||||||
++index);
|
|
||||||
r.add(typeParameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,34 +397,49 @@ public class JavaDescriptorResolver {
|
|||||||
psiTypeParameter.getName(),
|
psiTypeParameter.getName(),
|
||||||
psiTypeParameter.getIndex()
|
psiTypeParameter.getIndex()
|
||||||
);
|
);
|
||||||
typeParameterDescriptorCache.put(psiTypeParameter, typeParameterDescriptor);
|
typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameterDescriptor));
|
||||||
return typeParameterDescriptor;
|
return typeParameterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptor typeParameterDescriptor) {
|
private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) {
|
||||||
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
|
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor;
|
||||||
if (referencedTypes.length == 0){
|
if (typeParameterDescriptorInitialization.origin == TypeParameterDescriptorOrigin.KOTLIN) {
|
||||||
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
List<?> upperBounds = typeParameterDescriptorInitialization.upperBoundsForKotlin;
|
||||||
}
|
if (upperBounds.size() == 0){
|
||||||
else if (referencedTypes.length == 1) {
|
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
||||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0]));
|
} else {
|
||||||
}
|
for (JetType upperBound : typeParameterDescriptorInitialization.upperBoundsForKotlin) {
|
||||||
else {
|
typeParameterDescriptor.addUpperBound(upperBound);
|
||||||
for (PsiClassType referencedType : referencedTypes) {
|
}
|
||||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType));
|
}
|
||||||
|
|
||||||
|
// TODO: lower bounds
|
||||||
|
} else {
|
||||||
|
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
|
||||||
|
if (referencedTypes.length == 0){
|
||||||
|
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
||||||
|
}
|
||||||
|
else if (referencedTypes.length == 1) {
|
||||||
|
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (PsiClassType referencedType : referencedTypes) {
|
||||||
|
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
typeParameterDescriptor.setInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTypeParameters(PsiTypeParameterListOwner typeParameterListOwner) {
|
private void initializeTypeParameters(PsiTypeParameterListOwner typeParameterListOwner) {
|
||||||
for (PsiTypeParameter psiTypeParameter : typeParameterListOwner.getTypeParameters()) {
|
for (PsiTypeParameter psiTypeParameter : typeParameterListOwner.getTypeParameters()) {
|
||||||
initializeTypeParameter(psiTypeParameter, resolveTypeParameter(psiTypeParameter));
|
initializeTypeParameter(psiTypeParameter, resolveTypeParameterInitialization(psiTypeParameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private TypeParameterDescriptor resolveTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
|
private TypeParameterDescriptorInitialization resolveTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
|
TypeParameterDescriptorInitialization typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
|
||||||
assert typeParameterDescriptor != null : psiTypeParameter.getText();
|
assert typeParameterDescriptor != null : psiTypeParameter.getText();
|
||||||
return typeParameterDescriptor;
|
return typeParameterDescriptor;
|
||||||
}
|
}
|
||||||
@@ -423,21 +527,71 @@ public class JavaDescriptorResolver {
|
|||||||
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceDescriptor);
|
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceDescriptor);
|
||||||
return namespaceDescriptor;
|
return namespaceDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ValueParameterDescriptors {
|
||||||
|
private final JetType receiverType;
|
||||||
|
private final List<ValueParameterDescriptor> descriptors;
|
||||||
|
|
||||||
public List<ValueParameterDescriptor> resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) {
|
private ValueParameterDescriptors(@Nullable JetType receiverType, List<ValueParameterDescriptor> descriptors) {
|
||||||
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
|
this.receiverType = receiverType;
|
||||||
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
|
this.descriptors = descriptors;
|
||||||
PsiParameter parameter = parameters[i];
|
|
||||||
ValueParameterDescriptor valueParameterDescriptor = resolveParameterDescriptor(containingDeclaration, i, parameter);
|
|
||||||
if (valueParameterDescriptor != null) {
|
|
||||||
result.add(valueParameterDescriptor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) {
|
||||||
private ValueParameterDescriptor resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) {
|
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
|
||||||
|
JetType receiverType = null;
|
||||||
|
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
|
||||||
|
PsiParameter parameter = parameters[i];
|
||||||
|
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter);
|
||||||
|
if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
|
||||||
|
// TODO
|
||||||
|
} else if (meaning.kind == JvmMethodParameterKind.REGULAR) {
|
||||||
|
result.add(meaning.valueParameterDescriptor);
|
||||||
|
} else if (meaning.kind == JvmMethodParameterKind.RECEIVER) {
|
||||||
|
if (receiverType != null) {
|
||||||
|
throw new IllegalStateException("more then one receiver");
|
||||||
|
}
|
||||||
|
receiverType = meaning.receiverType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ValueParameterDescriptors(receiverType, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum JvmMethodParameterKind {
|
||||||
|
REGULAR,
|
||||||
|
RECEIVER,
|
||||||
|
TYPE_INFO,
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class JvmMethodParameterMeaning {
|
||||||
|
private final JvmMethodParameterKind kind;
|
||||||
|
private final JetType receiverType;
|
||||||
|
private final ValueParameterDescriptor valueParameterDescriptor;
|
||||||
|
private final Object typeInfo;
|
||||||
|
|
||||||
|
private JvmMethodParameterMeaning(JvmMethodParameterKind kind, JetType receiverType, ValueParameterDescriptor valueParameterDescriptor, Object typeInfo) {
|
||||||
|
this.kind = kind;
|
||||||
|
this.receiverType = receiverType;
|
||||||
|
this.valueParameterDescriptor = valueParameterDescriptor;
|
||||||
|
this.typeInfo = typeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JvmMethodParameterMeaning receiver(@NotNull JetType receiverType) {
|
||||||
|
return new JvmMethodParameterMeaning(JvmMethodParameterKind.RECEIVER, receiverType, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JvmMethodParameterMeaning regular(@NotNull ValueParameterDescriptor valueParameterDescriptor) {
|
||||||
|
return new JvmMethodParameterMeaning(JvmMethodParameterKind.REGULAR, null, valueParameterDescriptor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JvmMethodParameterMeaning typeInfo(@NotNull Object typeInfo) {
|
||||||
|
return new JvmMethodParameterMeaning(JvmMethodParameterKind.TYPE_INFO, null, null, typeInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) {
|
||||||
PsiType psiType = parameter.getType();
|
PsiType psiType = parameter.getType();
|
||||||
|
|
||||||
JetType varargElementType;
|
JetType varargElementType;
|
||||||
@@ -453,13 +607,11 @@ public class JavaDescriptorResolver {
|
|||||||
boolean nullable = true;
|
boolean nullable = true;
|
||||||
String typeFromAnnotation = null;
|
String typeFromAnnotation = null;
|
||||||
|
|
||||||
|
boolean receiver = false;
|
||||||
|
|
||||||
// TODO: must be very slow, make it lazy?
|
// TODO: must be very slow, make it lazy?
|
||||||
String name = parameter.getName() != null ? parameter.getName() : "p" + i;
|
String name = parameter.getName() != null ? parameter.getName() : "p" + i;
|
||||||
for (PsiAnnotation annotation : parameter.getModifierList().getAnnotations()) {
|
for (PsiAnnotation annotation : parameter.getModifierList().getAnnotations()) {
|
||||||
// TODO: softcode annotation name
|
|
||||||
|
|
||||||
PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
|
|
||||||
attributes.toString();
|
|
||||||
|
|
||||||
if (annotation.getQualifiedName().equals(StdlibNames.JET_VALUE_PARAMETER.getFqName())) {
|
if (annotation.getQualifiedName().equals(StdlibNames.JET_VALUE_PARAMETER.getFqName())) {
|
||||||
PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD);
|
PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD);
|
||||||
@@ -480,8 +632,16 @@ public class JavaDescriptorResolver {
|
|||||||
if (signatureExpression != null) {
|
if (signatureExpression != null) {
|
||||||
typeFromAnnotation = (String) signatureExpression.getValue();
|
typeFromAnnotation = (String) signatureExpression.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD);
|
||||||
|
if (receiverExpression != null) {
|
||||||
|
receiver = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER.getFqName())) {
|
} else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER.getFqName())) {
|
||||||
return null;
|
return JvmMethodParameterMeaning.typeInfo(new Object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,16 +651,20 @@ public class JavaDescriptorResolver {
|
|||||||
} else {
|
} else {
|
||||||
outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
||||||
}
|
}
|
||||||
return new ValueParameterDescriptorImpl(
|
if (receiver) {
|
||||||
containingDeclaration,
|
return JvmMethodParameterMeaning.receiver(outType);
|
||||||
i,
|
} else {
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl(
|
||||||
name,
|
containingDeclaration,
|
||||||
null, // TODO : review
|
i,
|
||||||
changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType,
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
false,
|
name,
|
||||||
varargElementType
|
null, // TODO : review
|
||||||
);
|
changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType,
|
||||||
|
false,
|
||||||
|
varargElementType
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
|
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
|
||||||
@@ -592,12 +756,13 @@ public class JavaDescriptorResolver {
|
|||||||
);
|
);
|
||||||
methodDescriptorCache.put(method, functionDescriptorImpl);
|
methodDescriptorCache.put(method, functionDescriptorImpl);
|
||||||
List<TypeParameterDescriptor> typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl);
|
List<TypeParameterDescriptor> typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl);
|
||||||
|
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters);
|
||||||
functionDescriptorImpl.initialize(
|
functionDescriptorImpl.initialize(
|
||||||
null,
|
valueParameterDescriptors.receiverType,
|
||||||
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
|
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
|
||||||
typeParameters,
|
typeParameters,
|
||||||
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
|
valueParameterDescriptors.descriptors,
|
||||||
semanticServices.getDescriptorResolver().makeReturnType(returnType, method),
|
makeReturnType(returnType, method),
|
||||||
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
|
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
|
||||||
resolveVisibilityFromPsiModifiers(method)
|
resolveVisibilityFromPsiModifiers(method)
|
||||||
);
|
);
|
||||||
@@ -616,7 +781,9 @@ public class JavaDescriptorResolver {
|
|||||||
if (attributeValue != null) {
|
if (attributeValue != null) {
|
||||||
String typeParametersString = (String) attributeValue.getValue();
|
String typeParametersString = (String) attributeValue.getValue();
|
||||||
if (typeParametersString != null) {
|
if (typeParametersString != null) {
|
||||||
return resolveMethodTypeParametersFromJetSignature(typeParametersString, functionDescriptorImpl);
|
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl);
|
||||||
|
initializeTypeParameters(method);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -628,49 +795,21 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #resolveClassTypeParametersFromJetSignature(String, JavaClassDescriptor)
|
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, JavaClassDescriptor)
|
||||||
*/
|
*/
|
||||||
private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final FunctionDescriptor functionDescriptor) {
|
private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, final FunctionDescriptor functionDescriptor) {
|
||||||
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
|
||||||
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
|
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
|
||||||
|
|
||||||
return new JetSignatureExceptionsAdapter() {
|
return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance) {
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitClassBound() {
|
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
r.add(typeParameterDescriptor);
|
||||||
@Override
|
|
||||||
protected void done(@NotNull JetType jetType) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetSignatureVisitor visitInterfaceBound() {
|
|
||||||
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
|
|
||||||
@Override
|
|
||||||
protected void done(@NotNull JetType jetType) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitFormalTypeParameterEnd() {
|
|
||||||
TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification(
|
|
||||||
functionDescriptor,
|
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
|
|
||||||
true, // TODO: wrong
|
|
||||||
JetSignatureUtils.translateVariance(variance),
|
|
||||||
name,
|
|
||||||
++index);
|
|
||||||
r.add(typeParameter);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return r;
|
return r;
|
||||||
@@ -719,7 +858,8 @@ public class JavaDescriptorResolver {
|
|||||||
(modifierListOwner.hasModifierProperty(PsiModifier.PROTECTED) ? Visibility.PROTECTED : Visibility.INTERNAL));
|
(modifierListOwner.hasModifierProperty(PsiModifier.PROTECTED) ? Visibility.PROTECTED : Visibility.INTERNAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeParameterDescriptor resolveTypeParameter(PsiTypeParameter typeParameter) {
|
@NotNull
|
||||||
|
private TypeParameterDescriptorInitialization resolveTypeParameterInitialization(PsiTypeParameter typeParameter) {
|
||||||
PsiTypeParameterListOwner owner = typeParameter.getOwner();
|
PsiTypeParameterListOwner owner = typeParameter.getOwner();
|
||||||
if (owner instanceof PsiClass) {
|
if (owner instanceof PsiClass) {
|
||||||
PsiClass psiClass = (PsiClass) owner;
|
PsiClass psiClass = (PsiClass) owner;
|
||||||
@@ -744,4 +884,8 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
throw new IllegalStateException("Unknown parent type: " + owner);
|
throw new IllegalStateException("Unknown parent type: " + owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeParameterDescriptor resolveTypeParameter(PsiTypeParameter typeParameter) {
|
||||||
|
return resolveTypeParameterInitialization(typeParameter).descriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class StdlibNames {
|
|||||||
public static final String JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD = "hasDefaultValue";
|
public static final String JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD = "hasDefaultValue";
|
||||||
public static final String JET_VALUE_PARAMETER_NULLABLE_FIELD = "nullable";
|
public static final String JET_VALUE_PARAMETER_NULLABLE_FIELD = "nullable";
|
||||||
public static final String JET_VALUE_PARAMETER_TYPE_FIELD = "type";
|
public static final String JET_VALUE_PARAMETER_TYPE_FIELD = "type";
|
||||||
|
public static final String JET_VALUE_PARAMETER_RECEIVER_FIELD = "receiver";
|
||||||
|
|
||||||
|
|
||||||
public static final JvmClassName JET_TYPE_PARAMETER = new JvmClassName("jet.typeinfo.JetTypeParameter");
|
public static final JvmClassName JET_TYPE_PARAMETER = new JvmClassName("jet.typeinfo.JetTypeParameter");
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ namespace io {
|
|||||||
fun readLine() : String?
|
fun readLine() : String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <R> Any.synchronized(block : fun() : R) : R
|
||||||
|
|
||||||
fun Any?.identityEquals(other : Any?) : Boolean // = this === other
|
fun Any?.identityEquals(other : Any?) : Boolean // = this === other
|
||||||
|
|
||||||
// Can't write a body due to a bootstrapping problem (see JET-74)
|
// Can't write a body due to a bootstrapping problem (see JET-74)
|
||||||
@@ -103,6 +105,38 @@ trait Iterable<out T> {
|
|||||||
fun iterator() : Iterator<T>
|
fun iterator() : Iterator<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait ByteIterable : Iterable<Byte> {
|
||||||
|
override fun iterator() : ByteIterator
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ShortIterable : Iterable<Short> {
|
||||||
|
override fun iterator() : ShortIterator
|
||||||
|
}
|
||||||
|
|
||||||
|
trait IntIterable : Iterable<Int> {
|
||||||
|
override fun iterator() : IntIterator
|
||||||
|
}
|
||||||
|
|
||||||
|
trait LongIterable : Iterable<Long> {
|
||||||
|
override fun iterator() : LongIterator
|
||||||
|
}
|
||||||
|
|
||||||
|
trait FloatIterable : Iterable<Float> {
|
||||||
|
override fun iterator() : FloatIterator
|
||||||
|
}
|
||||||
|
|
||||||
|
trait DoubleIterable : Iterable<Double> {
|
||||||
|
override fun iterator() : DoubleIterator
|
||||||
|
}
|
||||||
|
|
||||||
|
trait BooleanIterable : Iterable<Boolean> {
|
||||||
|
override fun iterator() : BooleanIterator
|
||||||
|
}
|
||||||
|
|
||||||
|
trait CharIterable : Iterable<Char> {
|
||||||
|
override fun iterator() : CharIterator
|
||||||
|
}
|
||||||
|
|
||||||
fun Array<T>(val size : Int) : Array<T?>
|
fun Array<T>(val size : Int) : Array<T?>
|
||||||
|
|
||||||
class Array<T>(val size : Int, init : fun(Int) : T) {
|
class Array<T>(val size : Int, init : fun(Int) : T) {
|
||||||
@@ -230,7 +264,7 @@ trait Range<in T : Comparable<T>> {
|
|||||||
fun contains(item : T) : Boolean
|
fun contains(item : T) : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class IntRange(val start : Int, size : Int, reversed : Boolean = false) : Range<Int>, Iterable<Int> {
|
class IntRange(val start : Int, size : Int, reversed : Boolean = false) : Range<Int>, IntIterable {
|
||||||
fun iterator () : Iterator<Int>
|
fun iterator () : Iterator<Int>
|
||||||
|
|
||||||
fun contains (elem: Int) : Boolean
|
fun contains (elem: Int) : Boolean
|
||||||
|
|||||||
+50
-1
@@ -28,6 +28,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
int index) {
|
int index) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index);
|
TypeParameterDescriptor typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index);
|
||||||
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound());
|
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound());
|
||||||
|
typeParameterDescriptor.setInitialized();
|
||||||
return typeParameterDescriptor;
|
return typeParameterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +53,8 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
|
|
||||||
private final boolean reified;
|
private final boolean reified;
|
||||||
|
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
private TypeParameterDescriptor(
|
private TypeParameterDescriptor(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@NotNull List<AnnotationDescriptor> annotations,
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
@@ -74,25 +77,61 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
upperBounds);
|
upperBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setInitialized() {
|
||||||
|
if (initialized) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkInitialized() {
|
||||||
|
if (!initialized) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkUninitialized() {
|
||||||
|
if (initialized) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isReified() {
|
public boolean isReified() {
|
||||||
|
checkInitialized();
|
||||||
return reified;
|
return reified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Variance getVariance() {
|
public Variance getVariance() {
|
||||||
|
checkInitialized();
|
||||||
return variance;
|
return variance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUpperBound(@NotNull JetType bound) {
|
public void addUpperBound(@NotNull JetType bound) {
|
||||||
|
checkUninitialized();
|
||||||
|
doAddUpperBound(bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doAddUpperBound(JetType bound) {
|
||||||
upperBounds.add(bound); // TODO : Duplicates?
|
upperBounds.add(bound); // TODO : Duplicates?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addDefaultUpperBound() {
|
||||||
|
checkUninitialized();
|
||||||
|
|
||||||
|
if (upperBounds.isEmpty()) {
|
||||||
|
doAddUpperBound(JetStandardClasses.getDefaultBound());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<JetType> getUpperBounds() {
|
public Set<JetType> getUpperBounds() {
|
||||||
|
checkInitialized();
|
||||||
return upperBounds;
|
return upperBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType getUpperBoundsAsType() {
|
public JetType getUpperBoundsAsType() {
|
||||||
|
checkInitialized();
|
||||||
if (upperBoundsAsType == null) {
|
if (upperBoundsAsType == null) {
|
||||||
assert upperBounds != null : "Upper bound list is null in " + getName();
|
assert upperBounds != null : "Upper bound list is null in " + getName();
|
||||||
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
|
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
|
||||||
@@ -106,11 +145,13 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<JetType> getLowerBounds() {
|
public Set<JetType> getLowerBounds() {
|
||||||
|
//checkInitialized();
|
||||||
return Collections.singleton(JetStandardClasses.getNothingType());
|
return Collections.singleton(JetStandardClasses.getNothingType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType getLowerBoundsAsType() {
|
public JetType getLowerBoundsAsType() {
|
||||||
|
checkInitialized();
|
||||||
return JetStandardClasses.getNothingType();
|
return JetStandardClasses.getNothingType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +159,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public TypeConstructor getTypeConstructor() {
|
public TypeConstructor getTypeConstructor() {
|
||||||
|
//checkInitialized();
|
||||||
return typeConstructor;
|
return typeConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,12 +177,14 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||||
|
checkInitialized();
|
||||||
return visitor.visitTypeParameterDescriptor(this, data);
|
return visitor.visitTypeParameterDescriptor(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JetType getDefaultType() {
|
public JetType getDefaultType() {
|
||||||
|
//checkInitialized();
|
||||||
if (defaultType == null) {
|
if (defaultType == null) {
|
||||||
defaultType = new JetTypeImpl(
|
defaultType = new JetTypeImpl(
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
@@ -159,6 +203,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetType getClassObjectType() {
|
public JetType getClassObjectType() {
|
||||||
|
checkInitialized();
|
||||||
if (classObjectUpperBounds.isEmpty()) return null;
|
if (classObjectUpperBounds.isEmpty()) return null;
|
||||||
|
|
||||||
if (classObjectBoundsAsType == null) {
|
if (classObjectBoundsAsType == null) {
|
||||||
@@ -176,15 +221,19 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addClassObjectBound(@NotNull JetType bound) {
|
public void addClassObjectBound(@NotNull JetType bound) {
|
||||||
|
checkUninitialized();
|
||||||
classObjectUpperBounds.add(bound); // TODO : Duplicates?
|
classObjectUpperBounds.add(bound); // TODO : Duplicates?
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndex() {
|
public int getIndex() {
|
||||||
|
checkInitialized();
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) {
|
public TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) {
|
||||||
return new TypeParameterDescriptor(newOwner, Lists.newArrayList(getAnnotations()), reified, variance, getName(), index);
|
TypeParameterDescriptor copy = new TypeParameterDescriptor(newOwner, Lists.newArrayList(getAnnotations()), reified, variance, getName(), index);
|
||||||
|
copy.initialized = this.initialized;
|
||||||
|
return copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -381,9 +381,9 @@ public class DescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (TypeParameterDescriptor parameter : parameters) {
|
for (TypeParameterDescriptor parameter : parameters) {
|
||||||
if (parameter.getUpperBounds().isEmpty()) {
|
parameter.addDefaultUpperBound();
|
||||||
parameter.addUpperBound(JetStandardClasses.getDefaultBound());
|
|
||||||
}
|
parameter.setInitialized();
|
||||||
|
|
||||||
if (JetStandardClasses.isNothing(parameter.getUpperBoundsAsType())) {
|
if (JetStandardClasses.isNothing(parameter.getUpperBoundsAsType())) {
|
||||||
PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier();
|
PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
|||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||||
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -348,7 +349,7 @@ public class CallResolver {
|
|||||||
if (callElement instanceof JetBinaryExpression) {
|
if (callElement instanceof JetBinaryExpression) {
|
||||||
JetBinaryExpression binaryExpression = (JetBinaryExpression) callElement;
|
JetBinaryExpression binaryExpression = (JetBinaryExpression) callElement;
|
||||||
JetSimpleNameExpression operationReference = binaryExpression.getOperationReference();
|
JetSimpleNameExpression operationReference = binaryExpression.getOperationReference();
|
||||||
String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ? operationReference.getText() : OperatorConventions.getNameForOperationSymbol(operationReference.getReferencedNameElementType());
|
String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ? operationReference.getText() : OperatorConventions.getNameForOperationSymbol((JetToken) operationReference.getReferencedNameElementType());
|
||||||
JetExpression right = binaryExpression.getRight();
|
JetExpression right = binaryExpression.getRight();
|
||||||
if (right != null) {
|
if (right != null) {
|
||||||
trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, right.getText()));
|
trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, right.getText()));
|
||||||
@@ -510,15 +511,6 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tracing.typeInferenceFailed(temporaryTrace, solution.getStatus());
|
tracing.typeInferenceFailed(temporaryTrace, solution.getStatus());
|
||||||
// // Substitute DONT_CARE types to make further type checking as tolerant as possible
|
|
||||||
// D candidateWithDontCares = (D) candidate.substitute(TypeSubstitutor.makeConstantSubstitutor(candidate.getTypeParameters(), DONT_CARE));
|
|
||||||
// if (candidateWithDontCares == null) {
|
|
||||||
// candidateWithDontCares = (D) candidate.substitute(TypeSubstitutor.makeConstantSubstitutor(candidate.getTypeParameters(), Variance.INVARIANT, DONT_CARE));
|
|
||||||
// }
|
|
||||||
// if (!ErrorUtils.isErrorType(candidateWithDontCares.getReturnType())) {
|
|
||||||
// // Returning an error type provokes overload resolution ambiguities that mask errors
|
|
||||||
// candidateCall.setResultingDescriptor(candidateWithDontCares);
|
|
||||||
// }
|
|
||||||
candidateCall.setStatus(OTHER_ERROR.combine(checkAllValueArguments(scope, tracing, task, candidateCall)));
|
candidateCall.setStatus(OTHER_ERROR.combine(checkAllValueArguments(scope, tracing, task, candidateCall)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -259,7 +259,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
|
|||||||
|
|
||||||
assert constraintQueue.isEmpty() || unsolvedUnknowns.isEmpty() : constraintQueue + " " + unsolvedUnknowns;
|
assert constraintQueue.isEmpty() || unsolvedUnknowns.isEmpty() : constraintQueue + " " + unsolvedUnknowns;
|
||||||
|
|
||||||
for (TypeValue unknown : unsolvedUnknowns) {
|
for (TypeValue unknown : Sets.newLinkedHashSet(unsolvedUnknowns)) {
|
||||||
if (!computeValueFor(unknown)) {
|
if (!computeValueFor(unknown)) {
|
||||||
listener.error("Not enough data to compute value for ", unknown);
|
listener.error("Not enough data to compute value for ", unknown);
|
||||||
solution.registerError("Not enough data to compute value for " + unknown + ". Please, specify type arguments explicitly");
|
solution.registerError("Not enough data to compute value for " + unknown + ". Please, specify type arguments explicitly");
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public class DescriptorSubstitutor {
|
|||||||
descriptor.getVariance(),
|
descriptor.getVariance(),
|
||||||
descriptor.getName(),
|
descriptor.getName(),
|
||||||
descriptor.getIndex());
|
descriptor.getIndex());
|
||||||
|
substituted.setInitialized();
|
||||||
|
|
||||||
mutableSubstitution.put(descriptor.getTypeConstructor(), new TypeProjection(substituted.getDefaultType()));
|
mutableSubstitution.put(descriptor.getTypeConstructor(), new TypeProjection(substituted.getDefaultType()));
|
||||||
|
|
||||||
|
|||||||
+29
-14
@@ -1,10 +1,11 @@
|
|||||||
package org.jetbrains.jet.lang.types.expressions;
|
package org.jetbrains.jet.lang.types.expressions;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableBiMap;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.intellij.psi.tree.IElementType;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,6 +13,10 @@ import org.jetbrains.jet.lexer.JetTokens;
|
|||||||
*/
|
*/
|
||||||
public class OperatorConventions {
|
public class OperatorConventions {
|
||||||
|
|
||||||
|
public static final String EQUALS = "equals";
|
||||||
|
public static final String COMPARE_TO = "compareTo";
|
||||||
|
public static final String CONTAINS = "contains";
|
||||||
|
|
||||||
private OperatorConventions() {}
|
private OperatorConventions() {}
|
||||||
|
|
||||||
public static final ImmutableSet<String> NUMBER_CONVERSIONS = ImmutableSet.of(
|
public static final ImmutableSet<String> NUMBER_CONVERSIONS = ImmutableSet.of(
|
||||||
@@ -23,7 +28,7 @@ public class OperatorConventions {
|
|||||||
"int"
|
"int"
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final ImmutableMap<IElementType, String> UNARY_OPERATION_NAMES = ImmutableMap.<IElementType, String>builder()
|
public static final ImmutableBiMap<JetToken, String> UNARY_OPERATION_NAMES = ImmutableBiMap.<JetToken, String>builder()
|
||||||
.put(JetTokens.PLUSPLUS, "inc")
|
.put(JetTokens.PLUSPLUS, "inc")
|
||||||
.put(JetTokens.MINUSMINUS, "dec")
|
.put(JetTokens.MINUSMINUS, "dec")
|
||||||
.put(JetTokens.PLUS, "plus")
|
.put(JetTokens.PLUS, "plus")
|
||||||
@@ -31,7 +36,7 @@ public class OperatorConventions {
|
|||||||
.put(JetTokens.EXCL, "not")
|
.put(JetTokens.EXCL, "not")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static final ImmutableMap<IElementType, String> BINARY_OPERATION_NAMES = ImmutableMap.<IElementType, String>builder()
|
public static final ImmutableBiMap<JetToken, String> BINARY_OPERATION_NAMES = ImmutableBiMap.<JetToken, String>builder()
|
||||||
.put(JetTokens.MUL, "times")
|
.put(JetTokens.MUL, "times")
|
||||||
.put(JetTokens.PLUS, "plus")
|
.put(JetTokens.PLUS, "plus")
|
||||||
.put(JetTokens.MINUS, "minus")
|
.put(JetTokens.MINUS, "minus")
|
||||||
@@ -41,11 +46,22 @@ public class OperatorConventions {
|
|||||||
.put(JetTokens.RANGE, "rangeTo")
|
.put(JetTokens.RANGE, "rangeTo")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static final ImmutableSet<IElementType> COMPARISON_OPERATIONS = ImmutableSet.<IElementType>of(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ);
|
public static final ImmutableSet<JetToken> NOT_OVERLOADABLE =
|
||||||
public static final ImmutableSet<IElementType> EQUALS_OPERATIONS = ImmutableSet.<IElementType>of(JetTokens.EQEQ, JetTokens.EXCLEQ);
|
ImmutableSet.<JetToken>of(JetTokens.ANDAND, JetTokens.OROR, JetTokens.ELVIS);
|
||||||
|
|
||||||
|
public static final ImmutableSet<JetToken> INCREMENT_OPERATIONS =
|
||||||
|
ImmutableSet.<JetToken>of(JetTokens.PLUSPLUS, JetTokens.MINUSMINUS);
|
||||||
|
|
||||||
public static final ImmutableSet<IElementType> IN_OPERATIONS = ImmutableSet.<IElementType>of(JetTokens.IN_KEYWORD, JetTokens.NOT_IN);
|
public static final ImmutableSet<JetToken> COMPARISON_OPERATIONS =
|
||||||
public static final ImmutableMap<IElementType, String> ASSIGNMENT_OPERATIONS = ImmutableMap.<IElementType, String>builder()
|
ImmutableSet.<JetToken>of(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ);
|
||||||
|
|
||||||
|
public static final ImmutableSet<JetToken> EQUALS_OPERATIONS =
|
||||||
|
ImmutableSet.<JetToken>of(JetTokens.EQEQ, JetTokens.EXCLEQ);
|
||||||
|
|
||||||
|
public static final ImmutableSet<JetToken> IN_OPERATIONS =
|
||||||
|
ImmutableSet.<JetToken>of(JetTokens.IN_KEYWORD, JetTokens.NOT_IN);
|
||||||
|
|
||||||
|
public static final ImmutableBiMap<JetToken, String> ASSIGNMENT_OPERATIONS = ImmutableBiMap.<JetToken, String>builder()
|
||||||
.put(JetTokens.MULTEQ, "timesAssign")
|
.put(JetTokens.MULTEQ, "timesAssign")
|
||||||
.put(JetTokens.DIVEQ, "divAssign")
|
.put(JetTokens.DIVEQ, "divAssign")
|
||||||
.put(JetTokens.PERCEQ, "modAssign")
|
.put(JetTokens.PERCEQ, "modAssign")
|
||||||
@@ -53,7 +69,7 @@ public class OperatorConventions {
|
|||||||
.put(JetTokens.MINUSEQ, "minusAssign")
|
.put(JetTokens.MINUSEQ, "minusAssign")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static final ImmutableMap<IElementType, IElementType> ASSIGNMENT_OPERATION_COUNTERPARTS = ImmutableMap.<IElementType, IElementType>builder()
|
public static final ImmutableMap<JetToken, JetToken> ASSIGNMENT_OPERATION_COUNTERPARTS = ImmutableMap.<JetToken, JetToken>builder()
|
||||||
.put(JetTokens.MULTEQ, JetTokens.MUL)
|
.put(JetTokens.MULTEQ, JetTokens.MUL)
|
||||||
.put(JetTokens.DIVEQ, JetTokens.DIV)
|
.put(JetTokens.DIVEQ, JetTokens.DIV)
|
||||||
.put(JetTokens.PERCEQ, JetTokens.PERC)
|
.put(JetTokens.PERCEQ, JetTokens.PERC)
|
||||||
@@ -62,17 +78,16 @@ public class OperatorConventions {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getNameForOperationSymbol(@NotNull IElementType token) {
|
public static String getNameForOperationSymbol(@NotNull JetToken token) {
|
||||||
String name = UNARY_OPERATION_NAMES.get(token);
|
String name = UNARY_OPERATION_NAMES.get(token);
|
||||||
if (name != null) return name;
|
if (name != null) return name;
|
||||||
name = BINARY_OPERATION_NAMES.get(token);
|
name = BINARY_OPERATION_NAMES.get(token);
|
||||||
if (name != null) return name;
|
if (name != null) return name;
|
||||||
name = ASSIGNMENT_OPERATIONS.get(token);
|
name = ASSIGNMENT_OPERATIONS.get(token);
|
||||||
if (name != null) return name;
|
if (name != null) return name;
|
||||||
if (COMPARISON_OPERATIONS.contains(token)) return "compareTo";
|
if (COMPARISON_OPERATIONS.contains(token)) return COMPARE_TO;
|
||||||
if (EQUALS_OPERATIONS.contains(token)) return "equals";
|
if (EQUALS_OPERATIONS.contains(token)) return EQUALS;
|
||||||
if (IN_OPERATIONS.contains(token)) return "contains";
|
if (IN_OPERATIONS.contains(token)) return CONTAINS;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import java.lang.Runtime
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val processors = Runtime.getRuntime().sure().availableProcessors()
|
||||||
|
var threadNum = 1
|
||||||
|
while(threadNum <= 1024) {
|
||||||
|
System.out?.println(threadNum)
|
||||||
|
if(threadNum < 2 * processors)
|
||||||
|
threadNum += 1
|
||||||
|
else
|
||||||
|
threadNum *= 2
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import java.util.concurrent.*
|
||||||
|
import java.util.concurrent.atomic.*
|
||||||
|
|
||||||
|
fun thread(block: fun():Unit ) {
|
||||||
|
val thread = object: Thread() {
|
||||||
|
override fun run() {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thread.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val ref = AtomicInteger()
|
||||||
|
val cdl = CountDownLatch(11)
|
||||||
|
for(i in 0..10) {
|
||||||
|
thread {
|
||||||
|
var current = 0
|
||||||
|
do {
|
||||||
|
current = ref.synchronized {
|
||||||
|
val v = ref.get() + 1
|
||||||
|
if(v < 100)
|
||||||
|
ref.set(v+1)
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(current < 100)
|
||||||
|
cdl.countDown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cdl.await()
|
||||||
|
return if(ref.get() == 100) "OK" else ref.get().toString()
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
namespace one_extends_base
|
||||||
|
|
||||||
|
open class Base<T>(name : T?) {
|
||||||
|
var myName : T?
|
||||||
|
{
|
||||||
|
$myName = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open class One<T, K>(name : T?, second : K?) : Base<T?>(name) {
|
||||||
|
var mySecond : K?
|
||||||
|
{
|
||||||
|
$mySecond = second
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = if(One<String, Int>("ola", 0).myName == "ola") "OK" else "fail"
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace demo2
|
||||||
|
|
||||||
|
fun print(o : Any?) {}
|
||||||
|
|
||||||
|
fun test(i : Int) {
|
||||||
|
var monthString : String? = "<empty>"
|
||||||
|
when (i) {
|
||||||
|
1 => {
|
||||||
|
print(1)
|
||||||
|
print(2)
|
||||||
|
print(3)
|
||||||
|
print(4)
|
||||||
|
print(5)
|
||||||
|
}
|
||||||
|
else => {
|
||||||
|
monthString = "Invalid month"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(monthString)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
for (i in 1..12) test(i)
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
val <T> Array<T>.length : Int get() = this.size
|
||||||
|
|
||||||
|
fun box() = if(Array(10, {1}).length == 10) "OK" else "fail"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// KT-860 ConcurrentModificationException in frontend
|
||||||
|
// +JDK
|
||||||
|
|
||||||
|
namespace std.util
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun <T, U: Collection<in T>> Iterator<T>.to(container: U) : U {
|
||||||
|
while(hasNext)
|
||||||
|
container.add(next())
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> Iterator<T>.toArrayList() = to(ArrayList<T>())
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
class Clock<A : java.lang.Number>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
class Clock<A> where A : java.lang.Number, A : java.lang.CharSequence
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
class Clock<A : java.lang.CharSequence>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
class Clock<A> where A : java.lang.CharSequence, A : java.lang.Number
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
trait Trtrtr
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
fun Int.shuffle() = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
fun <A : java.lang.Number> uno() = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
fun <A> tres() where A : java.lang.Number, A : java.lang.CharSequence = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
fun <A : java.lang.CharSequence> dos() = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
fun <A> cuatro() where A : java.lang.CharSequence, A : java.lang.Number = 1
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
package org.jetbrains.jet;
|
package org.jetbrains.jet;
|
||||||
|
|
||||||
import com.intellij.lang.LanguageASTFactory;
|
|
||||||
import com.intellij.lang.java.JavaLanguage;
|
|
||||||
import com.intellij.openapi.util.Disposer;
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||||
import com.intellij.psi.PsiFileFactory;
|
import com.intellij.psi.PsiFileFactory;
|
||||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||||
import com.intellij.psi.impl.source.tree.JavaASTFactory;
|
|
||||||
import com.intellij.testFramework.LightVirtualFile;
|
import com.intellij.testFramework.LightVirtualFile;
|
||||||
import com.intellij.testFramework.UsefulTestCase;
|
import com.intellij.testFramework.UsefulTestCase;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
@@ -70,8 +67,6 @@ public class CompileJavaAgainstKotlinTest extends UsefulTestCase {
|
|||||||
protected void runTest() throws Throwable {
|
protected void runTest() throws Throwable {
|
||||||
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
||||||
|
|
||||||
LanguageASTFactory.INSTANCE.addExplicitExtension(JavaLanguage.INSTANCE, new JavaASTFactory());
|
|
||||||
|
|
||||||
|
|
||||||
String text = FileUtil.loadFile(ktFile);
|
String text = FileUtil.loadFile(ktFile);
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package org.jetbrains.jet;
|
package org.jetbrains.jet;
|
||||||
|
|
||||||
import com.intellij.lang.LanguageASTFactory;
|
|
||||||
import com.intellij.lang.java.JavaLanguage;
|
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
import com.intellij.openapi.util.Disposer;
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||||
import com.intellij.psi.PsiFileFactory;
|
import com.intellij.psi.PsiFileFactory;
|
||||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||||
import com.intellij.psi.impl.source.tree.JavaASTFactory;
|
|
||||||
import com.intellij.testFramework.LightVirtualFile;
|
import com.intellij.testFramework.LightVirtualFile;
|
||||||
import com.intellij.testFramework.UsefulTestCase;
|
import com.intellij.testFramework.UsefulTestCase;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
@@ -18,15 +15,7 @@ import org.jetbrains.jet.codegen.ClassFileFactory;
|
|||||||
import org.jetbrains.jet.codegen.GenerationState;
|
import org.jetbrains.jet.codegen.GenerationState;
|
||||||
import org.jetbrains.jet.compiler.CompileEnvironment;
|
import org.jetbrains.jet.compiler.CompileEnvironment;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
@@ -34,8 +23,8 @@ import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
|
||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.jetbrains.jet.lang.types.Variance;
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
import org.jetbrains.jet.plugin.JetLanguage;
|
import org.jetbrains.jet.plugin.JetLanguage;
|
||||||
@@ -44,6 +33,7 @@ import org.junit.Assert;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -92,9 +82,6 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
public void runTest() throws Exception {
|
public void runTest() throws Exception {
|
||||||
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
||||||
|
|
||||||
LanguageASTFactory.INSTANCE.addExplicitExtension(JavaLanguage.INSTANCE, new JavaASTFactory());
|
|
||||||
|
|
||||||
|
|
||||||
String text = FileUtil.loadFile(testFile);
|
String text = FileUtil.loadFile(testFile);
|
||||||
|
|
||||||
LightVirtualFile virtualFile = new LightVirtualFile(testFile.getName(), JetLanguage.INSTANCE, text);
|
LightVirtualFile virtualFile = new LightVirtualFile(testFile.getName(), JetLanguage.INSTANCE, text);
|
||||||
@@ -159,7 +146,8 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
private String serializeContent(ClassDescriptor klass) {
|
private String serializeContent(ClassDescriptor klass) {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("class ");
|
serialize(klass.getKind(), sb);
|
||||||
|
sb.append(" ");
|
||||||
|
|
||||||
serialize(klass, sb);
|
serialize(klass, sb);
|
||||||
|
|
||||||
@@ -174,9 +162,6 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
|
|
||||||
sb.append(" {\n");
|
sb.append(" {\n");
|
||||||
|
|
||||||
if (false) {
|
|
||||||
// TODO: for some reason I don't understand scope of ClassDescriptor came from source is empty
|
|
||||||
|
|
||||||
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>();
|
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>();
|
||||||
for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) {
|
for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) {
|
||||||
typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType()));
|
typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType()));
|
||||||
@@ -184,15 +169,37 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
|
|
||||||
JetScope memberScope = klass.getMemberScope(typeArguments);
|
JetScope memberScope = klass.getMemberScope(typeArguments);
|
||||||
for (DeclarationDescriptor member : memberScope.getAllDescriptors()) {
|
for (DeclarationDescriptor member : memberScope.getAllDescriptors()) {
|
||||||
|
// TODO
|
||||||
|
if (member.getName().equals("equals") || member.getName().equals("hashCode")
|
||||||
|
|| member.getName().equals("wait") || member.getName().equals("notify") || member.getName().equals("notifyAll")
|
||||||
|
|| member.getName().equals("toString") || member.getName().equals("getClass")
|
||||||
|
|| member.getName().equals("clone") || member.getName().equals("finalize")
|
||||||
|
|| member.getName().equals("getTypeInfo") || member.getName().equals("$setTypeInfo") || member.getName().equals("$typeInfo")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sb.append(" ");
|
||||||
serialize(member, sb);
|
serialize(member, sb);
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("}\n");
|
sb.append("}\n");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void serialize(ClassKind kind, StringBuilder sb) {
|
||||||
|
switch (kind) {
|
||||||
|
case CLASS:
|
||||||
|
sb.append("class");
|
||||||
|
break;
|
||||||
|
case TRAIT:
|
||||||
|
sb.append("trait");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void compareFunctions(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {
|
private void compareFunctions(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {
|
||||||
@@ -220,6 +227,12 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
serializeCommaSeparated(fun.getTypeParameters(), sb);
|
serializeCommaSeparated(fun.getTypeParameters(), sb);
|
||||||
sb.append(">");
|
sb.append(">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fun.getReceiverParameter().exists()) {
|
||||||
|
serialize(fun.getReceiverParameter(), sb);
|
||||||
|
sb.append(".");
|
||||||
|
}
|
||||||
|
|
||||||
sb.append(fun.getName());
|
sb.append(fun.getName());
|
||||||
sb.append("(");
|
sb.append("(");
|
||||||
serializeCommaSeparated(fun.getValueParameters(), sb);
|
serializeCommaSeparated(fun.getValueParameters(), sb);
|
||||||
@@ -227,6 +240,21 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
serialize(fun.getReturnType(), sb);
|
serialize(fun.getReturnType(), sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void serialize(ExtensionReceiver extensionReceiver, StringBuilder sb) {
|
||||||
|
serialize(extensionReceiver.getType(), sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serialize(PropertyDescriptor prop, StringBuilder sb) {
|
||||||
|
if (prop.isVar()) {
|
||||||
|
sb.append("var ");
|
||||||
|
} else {
|
||||||
|
sb.append("val ");
|
||||||
|
}
|
||||||
|
sb.append(prop.getName());
|
||||||
|
sb.append(": ");
|
||||||
|
serialize(prop.getOutType(), sb);
|
||||||
|
}
|
||||||
|
|
||||||
private void serialize(ValueParameterDescriptor valueParameter, StringBuilder sb) {
|
private void serialize(ValueParameterDescriptor valueParameter, StringBuilder sb) {
|
||||||
sb.append(valueParameter.getName());
|
sb.append(valueParameter.getName());
|
||||||
sb.append(": ");
|
sb.append(": ");
|
||||||
@@ -274,16 +302,20 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void serializeCommaSeparated(List<?> list, StringBuilder sb) {
|
private void serializeCommaSeparated(List<?> list, StringBuilder sb) {
|
||||||
|
serializeSeparated(list, sb, ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serializeSeparated(List<?> list, StringBuilder sb, String sep) {
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (Object o : list) {
|
for (Object o : list) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
sb.append(", ");
|
sb.append(sep);
|
||||||
}
|
}
|
||||||
serialize(o, sb);
|
serialize(o, sb);
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method getMethodToSerialize(Object o) {
|
private Method getMethodToSerialize(Object o) {
|
||||||
// TODO: cache
|
// TODO: cache
|
||||||
for (Method method : ReadClassDataTest.class.getDeclaredMethods()) {
|
for (Method method : ReadClassDataTest.class.getDeclaredMethods()) {
|
||||||
@@ -311,6 +343,10 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
Method method = getMethodToSerialize(o);
|
Method method = getMethodToSerialize(o);
|
||||||
invoke(method, this, o, sb);
|
invoke(method, this, o, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void serialize(String s, StringBuilder sb) {
|
||||||
|
sb.append(s);
|
||||||
|
}
|
||||||
|
|
||||||
private void serialize(ModuleDescriptor module, StringBuilder sb) {
|
private void serialize(ModuleDescriptor module, StringBuilder sb) {
|
||||||
// nop
|
// nop
|
||||||
@@ -331,11 +367,20 @@ public class ReadClassDataTest extends UsefulTestCase {
|
|||||||
sb.append(".");
|
sb.append(".");
|
||||||
sb.append(ns.getName());
|
sb.append(ns.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void serialize(TypeParameterDescriptor param, StringBuilder sb) {
|
private void serialize(TypeParameterDescriptor param, StringBuilder sb) {
|
||||||
serialize(param.getVariance(), sb);
|
serialize(param.getVariance(), sb);
|
||||||
sb.append(param.getName());
|
sb.append(param.getName());
|
||||||
// TODO: serialize bounds
|
if (!param.getUpperBounds().isEmpty()) {
|
||||||
|
sb.append(" : ");
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
for (JetType upper : param.getUpperBounds()) {
|
||||||
|
list.add(serialize(upper));
|
||||||
|
}
|
||||||
|
Collections.sort(list);
|
||||||
|
serializeSeparated(list, sb, " & "); // TODO: use where
|
||||||
|
}
|
||||||
|
// TODO: lower bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ public class ArrayGenTest extends CodegenTestCase {
|
|||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt779 () throws Exception {
|
||||||
|
blackBoxFile("regressions/kt779.jet");
|
||||||
|
// System.out.println(generateToText());
|
||||||
|
}
|
||||||
|
|
||||||
public void testCreateMultiInt () throws Exception {
|
public void testCreateMultiInt () throws Exception {
|
||||||
loadText("fun foo() = Array<Array<Int>> (5, { Array<Int>(it, {239}) })");
|
loadText("fun foo() = Array<Array<Int>> (5, { Array<Int>(it, {239}) })");
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
|
|||||||
@@ -231,8 +231,25 @@ public class ControlStructuresTest extends CodegenTestCase {
|
|||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt772() throws Exception {
|
||||||
|
blackBoxFile("regressions/kt772.jet");
|
||||||
|
// System.out.println(generateToText());
|
||||||
|
}
|
||||||
|
|
||||||
public void testQuicksort() throws Exception {
|
public void testQuicksort() throws Exception {
|
||||||
blackBoxFile("controlStructures/quicksort.jet");
|
blackBoxFile("controlStructures/quicksort.jet");
|
||||||
|
// System.out.println(generateToText());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSynchronized() throws Exception {
|
||||||
|
createEnvironmentWithFullJdk();
|
||||||
|
blackBoxFile("controlStructures/sync.jet");
|
||||||
|
// System.out.println(generateToText());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIfInWhile() throws Exception {
|
||||||
|
createEnvironmentWithFullJdk();
|
||||||
|
blackBoxFile("controlStructures/ifInWhile.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,6 +138,11 @@ public class TypeInfoTest extends CodegenTestCase {
|
|||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt511() throws Exception {
|
||||||
|
blackBoxFile("regressions/kt511.jet");
|
||||||
|
// System.out.println(generateToText());
|
||||||
|
}
|
||||||
|
|
||||||
public void testInner() throws Exception {
|
public void testInner() throws Exception {
|
||||||
blackBoxFile("typeInfo/inner.jet");
|
blackBoxFile("typeInfo/inner.jet");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
namespace lockperformance
|
namespace lockperformance
|
||||||
|
|
||||||
|
import std.io.*
|
||||||
|
import std.util.*
|
||||||
|
import std.concurrent.*
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
fun thread(f: fun ()) {
|
|
||||||
val thread = Thread(
|
|
||||||
object: Runnable {
|
|
||||||
override fun run() {
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
thread.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> Int.latch(op: fun CountDownLatch.() : T) : T {
|
fun <T> Int.latch(op: fun CountDownLatch.() : T) : T {
|
||||||
val cdl = CountDownLatch(this)
|
val cdl = CountDownLatch(this)
|
||||||
val res = cdl.op()
|
val res = cdl.op()
|
||||||
@@ -22,41 +15,37 @@ fun <T> Int.latch(op: fun CountDownLatch.() : T) : T {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Int.times(action: fun Int.()) {
|
|
||||||
for(i in 0..this-1)
|
|
||||||
action()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val processors = Runtime.getRuntime().sure().availableProcessors()
|
val processors = Runtime.getRuntime().sure().availableProcessors()
|
||||||
var threadNum = 1
|
var threadNum = 1
|
||||||
while(threadNum <= 1024) {
|
while(threadNum <= 1024) {
|
||||||
val counter = AtomicInteger()
|
val counter = AtomicInteger()
|
||||||
|
|
||||||
val start = System.currentTimeMillis()
|
val duration = measureTimeMillis {
|
||||||
threadNum.latch{
|
threadNum.latch{
|
||||||
val lock = ReentrantLock()
|
val lock = ReentrantLock()
|
||||||
threadNum.times {
|
for(i in 0..threadNum-1) {
|
||||||
thread {
|
thread {
|
||||||
while(true) {
|
while(true) {
|
||||||
lock.lock()
|
lock.lock()
|
||||||
try {
|
try {
|
||||||
if (counter.get() == 100000000) {
|
if (counter.get() == 100000000) {
|
||||||
countDown();
|
countDown();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
counter.incrementAndGet();
|
counter.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
lock.unlock()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
finally {
|
|
||||||
lock.unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out?.println(threadNum.toString() + " " + (System.currentTimeMillis() - start));
|
println(threadNum.toString() + " " + duration)
|
||||||
|
|
||||||
if(threadNum < 2 * processors)
|
if(threadNum < 2 * processors)
|
||||||
threadNum = threadNum + 1
|
threadNum = threadNum + 1
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ import com.intellij.psi.PsiFile;
|
|||||||
import com.intellij.psi.PsiManager;
|
import com.intellij.psi.PsiManager;
|
||||||
import com.intellij.util.Chunk;
|
import com.intellij.util.Chunk;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
import org.jetbrains.jet.codegen.*;
|
||||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
|
||||||
import org.jetbrains.jet.codegen.CompilationErrorHandler;
|
|
||||||
import org.jetbrains.jet.codegen.GenerationState;
|
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
@@ -102,7 +99,12 @@ public class JetCompiler implements TranslatingCompiler {
|
|||||||
generationState.compileCorrectNamespaces(bindingContext, namespaces, new CompilationErrorHandler() {
|
generationState.compileCorrectNamespaces(bindingContext, namespaces, new CompilationErrorHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void reportException(Throwable exception, String fileUrl) {
|
public void reportException(Throwable exception, String fileUrl) {
|
||||||
compileContext.addMessage(CompilerMessageCategory.WARNING, exception.getClass().getCanonicalName() + ": " + exception.getMessage(), fileUrl, 0, 0);
|
if(exception instanceof CompilationException) {
|
||||||
|
report((CompilationException) exception, compileContext);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compileContext.addMessage(CompilerMessageCategory.ERROR, exception.getClass().getCanonicalName() + ": " + exception.getMessage(), fileUrl, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
///////////
|
///////////
|
||||||
@@ -175,6 +177,29 @@ public class JetCompiler implements TranslatingCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void report(CompilationException diagnostic, CompileContext compileContext) {
|
||||||
|
PsiFile psiFile = diagnostic.getElement().getContainingFile();
|
||||||
|
TextRange textRange = diagnostic.getElement().getTextRange();
|
||||||
|
Document document = psiFile.getViewProvider().getDocument();
|
||||||
|
int line;
|
||||||
|
int col;
|
||||||
|
if (document != null) {
|
||||||
|
line = document.getLineNumber(textRange.getStartOffset());
|
||||||
|
col = textRange.getStartOffset() - document.getLineStartOffset(line) + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
line = -1;
|
||||||
|
col = -1;
|
||||||
|
}
|
||||||
|
VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||||
|
if (virtualFile == null) {
|
||||||
|
compileContext.addMessage(ERROR, "[Internal Error] No virtual file for PsiFile. Diagnostic: " + diagnostic.getMessage(), "", -1, -1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compileContext.addMessage(ERROR, diagnostic.getMessage(), virtualFile.getUrl(), line + 1, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// private static class ModuleCompileState {
|
// private static class ModuleCompileState {
|
||||||
// private final GenerationState state;
|
// private final GenerationState state;
|
||||||
// private final CompileContext compileContext;
|
// private final CompileContext compileContext;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.jetbrains.jet.plugin.compiler;
|
package org.jetbrains.jet.plugin.compiler;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
|
||||||
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
|
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
|
||||||
import com.intellij.openapi.fileTypes.FileType;
|
import com.intellij.openapi.fileTypes.FileType;
|
||||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||||
@@ -41,7 +40,7 @@ public final class WholeProjectAnalyzerFacade {
|
|||||||
final Set<JetDeclaration> namespaces = Sets.newLinkedHashSet();
|
final Set<JetDeclaration> namespaces = Sets.newLinkedHashSet();
|
||||||
final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
|
final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
|
||||||
|
|
||||||
if (rootManager != null && !ApplicationManager.getApplication().isUnitTestMode()) {
|
if (rootManager != null /* && !ApplicationManager.getApplication().isUnitTestMode() */) {
|
||||||
VirtualFile[] contentRoots = rootManager.getContentRoots();
|
VirtualFile[] contentRoots = rootManager.getContentRoots();
|
||||||
|
|
||||||
CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() {
|
CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() {
|
||||||
@@ -57,7 +56,6 @@ public final class WholeProjectAnalyzerFacade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaces.add(rootFile.getRootNamespace());
|
namespaces.add(rootFile.getRootNamespace());
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// "Import Class" "true"
|
||||||
|
|
||||||
|
import TestData.TestSample
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = TestSample
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace TestData
|
||||||
|
|
||||||
|
class TestSample() {}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// "Import Class" "true"
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = <caret>TestSample
|
||||||
|
}
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
package org.jetbrains.jet.plugin.quickfix;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Collections2;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
|
||||||
|
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||||
|
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
|
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
|
||||||
|
import com.intellij.openapi.command.CommandProcessor;
|
||||||
|
import com.intellij.openapi.projectRoots.Sdk;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
|
import com.intellij.rt.execution.junit.FileComparisonFailure;
|
||||||
|
import com.intellij.util.ui.UIUtil;
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public class JetPsiCheckerMultifileTest extends DaemonAnalyzerTestCase {
|
||||||
|
|
||||||
|
public final static String MAIN_SUBSTRING = ".Main";
|
||||||
|
public final static String DATA_SUBSTRING = ".Data";
|
||||||
|
|
||||||
|
private final String dataPath;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public JetPsiCheckerMultifileTest(String dataPath, String name) {
|
||||||
|
this.dataPath = dataPath;
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
|
setName("testRun");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean shouldBeAvailableAfterExecution() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRun() throws Exception {
|
||||||
|
configureByFiles(null, getFileNames(getTestFiles()).toArray(new String[1]));
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doTest() {
|
||||||
|
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
final Pair<String, Boolean> pair = LightQuickFixTestCase.parseActionHint(getFile(), loadFile(getFile().getName()));
|
||||||
|
final String text = pair.getFirst();
|
||||||
|
|
||||||
|
final boolean actionShouldBeAvailable = pair.getSecond();
|
||||||
|
|
||||||
|
doAction(text, actionShouldBeAvailable, getTestDataPath());
|
||||||
|
}
|
||||||
|
catch (FileComparisonFailure e){
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail(getTestName(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||||
|
public void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath)
|
||||||
|
throws Exception {
|
||||||
|
IntentionAction action = LightQuickFixTestCase.findActionWithText(getAvailableActions(), text);
|
||||||
|
if (action == null) {
|
||||||
|
if (actionShouldBeAvailable) {
|
||||||
|
List<IntentionAction> actions = getAvailableActions();
|
||||||
|
List<String> texts = new ArrayList<String>();
|
||||||
|
for (IntentionAction intentionAction : actions) {
|
||||||
|
texts.add(intentionAction.getText());
|
||||||
|
}
|
||||||
|
Collection<HighlightInfo> infos = doHighlighting();
|
||||||
|
fail("Action with text '" + text + "' is not available in test " + testFullPath + "\n" +
|
||||||
|
"Available actions (" + texts.size() + "): " + texts + "\n" +
|
||||||
|
actions + "\n" +
|
||||||
|
"Infos:" + infos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!actionShouldBeAvailable) {
|
||||||
|
fail("Action '" + text + "' is available (but must not) in test " + testFullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
|
||||||
|
|
||||||
|
UIUtil.dispatchAllInvocationEvents();
|
||||||
|
|
||||||
|
if (!shouldBeAvailableAfterExecution()) {
|
||||||
|
final IntentionAction afterAction = LightQuickFixTestCase.findActionWithText(getAvailableActions(), text);
|
||||||
|
|
||||||
|
if (afterAction != null) {
|
||||||
|
fail("Action '" + text + "' is still available after its invocation in test " + testFullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkResultByFile(name.replace("before", "after").replace(MAIN_SUBSTRING, "") + ".kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<File> getTestFiles() {
|
||||||
|
File dir = new File(getTestDataPath());
|
||||||
|
|
||||||
|
assertTrue("Main file should contain .Main. substring", name.contains(MAIN_SUBSTRING));
|
||||||
|
final String testPrefix = name.replace(MAIN_SUBSTRING, "");
|
||||||
|
|
||||||
|
// Files of single test
|
||||||
|
FilenameFilter resultFilter = new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file, String s) {
|
||||||
|
return s.contains(testPrefix) && !s.contains("after");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
List<File> allTestFiles = Arrays.asList(dir.listFiles(resultFilter));
|
||||||
|
|
||||||
|
final Collection<File> mainFiles = Collections2.filter(allTestFiles, new Predicate<File>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(@Nullable File file) {
|
||||||
|
return file != null && file.getName().contains(MAIN_SUBSTRING);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assertTrue("No main file for test", mainFiles.size() > 0);
|
||||||
|
assertTrue("Too many main files for the test", mainFiles.size() <= 1);
|
||||||
|
|
||||||
|
final Collection<File> dataFiles = Collections2.filter(allTestFiles, new Predicate<File>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(@Nullable File file) {
|
||||||
|
return file != null && file.getName().contains(DATA_SUBSTRING);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final ArrayList<File> fileResult = new ArrayList<File>(allTestFiles);
|
||||||
|
fileResult.addAll(dataFiles);
|
||||||
|
|
||||||
|
return fileResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static List<String> getFileNames(List<File> files) {
|
||||||
|
return Lists.newArrayList(Collections2.transform(files, new Function<File, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(File file) {
|
||||||
|
return file.getName();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<IntentionAction> getAvailableActions() {
|
||||||
|
doHighlighting();
|
||||||
|
return LightQuickFixTestCase.getAvailableActions(getEditor(), getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "test" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return PluginTestCaseBase.getTestDataPathBase() + "/quickfix/" + dataPath + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Sdk getTestProjectJdk() {
|
||||||
|
return PluginTestCaseBase.jdkFromIdeaHome();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMultiFileName(String fileName) {
|
||||||
|
return fileName.contains(MAIN_SUBSTRING) || fileName.contains(DATA_SUBSTRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMainFile(String fileName) {
|
||||||
|
return fileName.contains(MAIN_SUBSTRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
TestSuite suite = new TestSuite();
|
||||||
|
|
||||||
|
FilenameFilter multifileFileNameFilter = new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file, String s) {
|
||||||
|
return s.startsWith("before") && JetPsiCheckerMultifileTest.isMainFile(s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
JetTestCaseBuilder.NamedTestFactory multiFileNamedTestFactory = new JetTestCaseBuilder.NamedTestFactory() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||||
|
return new JetPsiCheckerMultifileTest(dataPath, name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
File dir = new File(getTestDataPathBase());
|
||||||
|
List<String> subDirs = Arrays.asList(dir.list());
|
||||||
|
Collections.sort(subDirs);
|
||||||
|
for (String subDirName : subDirs) {
|
||||||
|
final TestSuite multiFileTestSuite = JetTestCaseBuilder.suiteForDirectory(getTestDataPathBase(), subDirName, true, multifileFileNameFilter, multiFileNamedTestFactory);
|
||||||
|
if (multiFileTestSuite.countTestCases() != 0) {
|
||||||
|
suite.addTest(multiFileTestSuite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTestDataPathBase() {
|
||||||
|
return JetTestCaseBuilder.getHomeDirectory() + "/idea/testData/quickfix/";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,26 +43,30 @@ public class JetQuickFixTest extends LightQuickFixTestCase {
|
|||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
//setFilter(); //to launch only part of tests
|
//setFilter(); //to launch only part of tests
|
||||||
TestSuite suite = new TestSuite();
|
TestSuite suite = new TestSuite();
|
||||||
FilenameFilter fileNameFilter = new FilenameFilter() {
|
|
||||||
|
FilenameFilter singleFileNameFilter = new FilenameFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File file, String s) {
|
public boolean accept(File file, String s) {
|
||||||
if (s.startsWith("before")) return true;
|
return s.startsWith("before") && !JetPsiCheckerMultifileTest.isMultiFileName(s);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
JetTestCaseBuilder.NamedTestFactory namedTestFactory = new JetTestCaseBuilder.NamedTestFactory() {
|
|
||||||
|
JetTestCaseBuilder.NamedTestFactory singleFileNamedTestFactory = new JetTestCaseBuilder.NamedTestFactory() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||||
return new JetQuickFixTest(dataPath, name);
|
return new JetQuickFixTest(dataPath, name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
File dir = new File(getTestDataPathBase());
|
File dir = new File(getTestDataPathBase());
|
||||||
List<String> subDirs = Arrays.asList(quickFixTestsFilter != null ? dir.list(quickFixTestsFilter) : dir.list());
|
List<String> subDirs = Arrays.asList(quickFixTestsFilter != null ? dir.list(quickFixTestsFilter) : dir.list());
|
||||||
Collections.sort(subDirs);
|
Collections.sort(subDirs);
|
||||||
for (String subDirName : subDirs) {
|
for (String subDirName : subDirs) {
|
||||||
suite.addTest(JetTestCaseBuilder.suiteForDirectory(getTestDataPathBase(), subDirName, true, fileNameFilter, namedTestFactory));
|
final TestSuite singleFileTestSuite = JetTestCaseBuilder.suiteForDirectory(getTestDataPathBase(), subDirName, true, singleFileNameFilter, singleFileNamedTestFactory);
|
||||||
|
if (singleFileTestSuite.countTestCases() != 0) {
|
||||||
|
suite.addTest(singleFileTestSuite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AntConfiguration">
|
||||||
|
<defaultAnt bundledAnt="true" />
|
||||||
|
</component>
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
|
<resourceExtensions />
|
||||||
|
<wildcardResourcePatterns>
|
||||||
|
<entry name="?*.properties" />
|
||||||
|
<entry name="?*.xml" />
|
||||||
|
<entry name="?*.gif" />
|
||||||
|
<entry name="?*.png" />
|
||||||
|
<entry name="?*.jpeg" />
|
||||||
|
<entry name="?*.jpg" />
|
||||||
|
<entry name="?*.html" />
|
||||||
|
<entry name="?*.dtd" />
|
||||||
|
<entry name="?*.tld" />
|
||||||
|
<entry name="?*.ftl" />
|
||||||
|
</wildcardResourcePatterns>
|
||||||
|
<annotationProcessing enabled="false" useClasspath="true" />
|
||||||
|
</component>
|
||||||
|
<component name="CopyrightManager" default="">
|
||||||
|
<module2copyright />
|
||||||
|
</component>
|
||||||
|
<component name="DependencyValidationManager">
|
||||||
|
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||||
|
</component>
|
||||||
|
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||||
|
<component name="IdProvider" IDEtalkID="89F322227D19AFBE9B68C2A85DBC4124" />
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profiles>
|
||||||
|
<profile version="1.0" is_locked="false">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<option name="myLocal" value="false" />
|
||||||
|
<inspection_tool class="EjbErrorInspection" level="ERROR" enabled="false" />
|
||||||
|
<inspection_tool class="EjbWarningInspection" level="WARNING" enabled="false" />
|
||||||
|
<inspection_tool class="JpaModelErrorInspection" level="ERROR" enabled="false" />
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</component>
|
||||||
|
<component name="JavadocGenerationManager">
|
||||||
|
<option name="OUTPUT_DIRECTORY" />
|
||||||
|
<option name="OPTION_SCOPE" value="protected" />
|
||||||
|
<option name="OPTION_HIERARCHY" value="true" />
|
||||||
|
<option name="OPTION_NAVIGATOR" value="true" />
|
||||||
|
<option name="OPTION_INDEX" value="true" />
|
||||||
|
<option name="OPTION_SEPARATE_INDEX" value="true" />
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_USE" value="false" />
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
|
||||||
|
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
|
||||||
|
<option name="OPTION_DEPRECATED_LIST" value="true" />
|
||||||
|
<option name="OTHER_OPTIONS" value="" />
|
||||||
|
<option name="HEAP_SIZE" />
|
||||||
|
<option name="LOCALE" />
|
||||||
|
<option name="OPEN_IN_BROWSER" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="ModuleEditorState">
|
||||||
|
<option name="LAST_EDITED_MODULE_NAME" />
|
||||||
|
<option name="LAST_EDITED_TAB_NAME" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/testlib/testlib.iml" filepath="$PROJECT_DIR$/testlib/testlib.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectResources">
|
||||||
|
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
namespace std
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
import java.lang.Iterable
|
||||||
|
|
||||||
|
/*
|
||||||
|
Filters given iterator
|
||||||
|
*/
|
||||||
|
inline fun <T> java.util.Iterator<T>.filter(f: fun(T): Boolean) : java.util.Iterator<T> = FilterIterator<T>(this, f)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Adds filtered elements in to given container
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
inline fun <T,U : Collection<in T>> java.lang.Iterable<T>.filterTo(var container: U, filter: fun(T): Boolean) : U {
|
||||||
|
for(element in this) {
|
||||||
|
if(filter(element))
|
||||||
|
container.add(element)
|
||||||
|
}
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create iterator filtering given java.lang.Iterable
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
inline fun <T> java.lang.Iterable<T>.filter(f: fun(T): Boolean) : java.util.Iterator<T> = (iterator() as java.util.Iterator<T>).filter(f)
|
||||||
|
*/
|
||||||
|
|
||||||
|
private class FilterIterator<T>(val original: java.util.Iterator<T>, val filter: fun(T): Boolean) : java.util.Iterator<T> {
|
||||||
|
var state = 0
|
||||||
|
var nextElement: T? = null
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean =
|
||||||
|
when(state) {
|
||||||
|
1 => true // checked and next present
|
||||||
|
2 => false // checked and next not present
|
||||||
|
else => {
|
||||||
|
while(original.hasNext()) {
|
||||||
|
val candidate = original.next()
|
||||||
|
if((filter)(candidate)) {
|
||||||
|
nextElement = candidate
|
||||||
|
state = 1
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = 2
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): T =
|
||||||
|
if(state != 1)
|
||||||
|
throw java.util.NoSuchElementException()
|
||||||
|
else {
|
||||||
|
val res = nextElement as T
|
||||||
|
nextElement = null
|
||||||
|
state = 0
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
throw java.lang.UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
namespace std.util
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
import java.util.Iterator
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add iterated elements to given container
|
||||||
|
*/
|
||||||
|
fun <T,U: Collection<in T>> java.util.Iterator<T>.to(container: U) : U {
|
||||||
|
while(hasNext())
|
||||||
|
container.add(next())
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add iterated elements to java.util.ArrayList
|
||||||
|
*/
|
||||||
|
inline fun <T> java.util.Iterator<T>.toArrayList() = to(ArrayList<T>())
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add iterated elements to java.util.LinkedList
|
||||||
|
*/
|
||||||
|
inline fun <T> java.util.Iterator<T>.toLinkedList() = to(LinkedList<T>())
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add iterated elements to java.util.HashSet
|
||||||
|
*/
|
||||||
|
inline fun <T> java.util.Iterator<T>.toHashSet() = to(HashSet<T>())
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add iterated elements to java.util.LinkedHashSet
|
||||||
|
*/
|
||||||
|
inline fun <T> java.util.Iterator<T>.toLinkedHashSet() = to(LinkedHashSet<T>())
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add iterated elements to java.util.TreeSet
|
||||||
|
*/
|
||||||
|
inline fun <T> java.util.Iterator<T>.toTreeSet() = to(TreeSet<T>())
|
||||||
@@ -2,8 +2,212 @@ namespace std.util
|
|||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
/** Returns the size of the collection */
|
||||||
val Collection<*>.size : Int
|
val Collection<*>.size : Int
|
||||||
get() = size()
|
get() = size()
|
||||||
|
|
||||||
|
/** Returns true if this collection is empty */
|
||||||
val Collection<*>.empty : Boolean
|
val Collection<*>.empty : Boolean
|
||||||
get() = isEmpty()
|
get() = isEmpty()
|
||||||
|
|
||||||
|
/** Returns a new ArrayList with a variable number of initial elements */
|
||||||
|
inline fun arrayList<T>(vararg values: T) : ArrayList<T> {
|
||||||
|
val answer = ArrayList<T>()
|
||||||
|
for (v in values)
|
||||||
|
answer.add(v)
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a new LinkedList with a variable number of initial elements */
|
||||||
|
inline fun linkedList<T>(vararg values: T) : LinkedList<T> {
|
||||||
|
val answer = LinkedList<T>()
|
||||||
|
for (v in values)
|
||||||
|
answer.add(v)
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a new HashSet with a variable number of initial elements */
|
||||||
|
inline fun hashSet<T>(vararg values: T) : HashSet<T> {
|
||||||
|
val answer = HashSet<T>()
|
||||||
|
for (v in values)
|
||||||
|
answer.add(v)
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns true if any elements in the collection match the given predicate */
|
||||||
|
inline fun <T> java.lang.Iterable<T>.any(predicate: fun(T): Boolean) : Boolean {
|
||||||
|
for (elem in this) {
|
||||||
|
if (predicate(elem)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns true if all elements in the collection match the given predicate */
|
||||||
|
inline fun <T> java.lang.Iterable<T>.all(predicate: fun(T): Boolean) : Boolean {
|
||||||
|
for (elem in this) {
|
||||||
|
if (!predicate(elem)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the first item in the collection which matches the given predicate or null if none matched */
|
||||||
|
inline fun <T> java.lang.Iterable<T>.find(predicate: fun(T): Boolean) : T? {
|
||||||
|
for (elem in this) {
|
||||||
|
if (predicate(elem))
|
||||||
|
return elem
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a new collection containing all elements in this collection which match the given predicate */
|
||||||
|
inline fun <T> java.lang.Iterable<T>.filter(result: Collection<T> = ArrayList<T>(), predicate: fun(T): Boolean) : Collection<T> {
|
||||||
|
for (elem in this) {
|
||||||
|
if (predicate(elem))
|
||||||
|
result.add(elem)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the result of transforming each item in the collection to a one or more values which
|
||||||
|
* are concatenated together into a single collection
|
||||||
|
*/
|
||||||
|
inline fun <T, out R> java.lang.Iterable<T>.flatMap(result: Collection<R> = ArrayList<R>(), transform: fun(T): Collection<R>) : Collection<R> {
|
||||||
|
for (elem in this) {
|
||||||
|
val coll = transform(elem)
|
||||||
|
if (coll != null) {
|
||||||
|
for (r in coll) {
|
||||||
|
result.add(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Performs the given operation on each element inside the collection */
|
||||||
|
inline fun <T> java.lang.Iterable<T>.foreach(operation: fun(element: T) : Unit) {
|
||||||
|
for (elem in this)
|
||||||
|
operation(elem)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */
|
||||||
|
inline fun <T> java.lang.Iterable<T>.join(separator: String, prefix: String = "", postfix: String = "") : String {
|
||||||
|
val buffer = StringBuilder(prefix)
|
||||||
|
var first = true
|
||||||
|
for (elem in this) {
|
||||||
|
if (first)
|
||||||
|
first = false
|
||||||
|
else
|
||||||
|
buffer.append(separator)
|
||||||
|
buffer.append(elem)
|
||||||
|
}
|
||||||
|
buffer.append(postfix)
|
||||||
|
return buffer.toString().sure()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a new collection containing the results of applying the given function to each element in this collection */
|
||||||
|
inline fun <T, R> java.lang.Iterable<T>.map(result: Collection<R> = ArrayList<R>(), transform : fun(T) : R) : Collection<R> {
|
||||||
|
for (item in this)
|
||||||
|
result.add(transform(item))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a new collection containing the results of applying the given function to each element in this collection */
|
||||||
|
inline fun <T, R> java.util.Collection<T>.map(result: Collection<R> = ArrayList<R>(this.size), transform : fun(T) : R) : Collection<R> {
|
||||||
|
for (item in this)
|
||||||
|
result.add(transform(item))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList() : List<T> {
|
||||||
|
val answer = this.toList()
|
||||||
|
answer.sort()
|
||||||
|
return answer
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList(comparator: java.util.Comparator<T>) : List<T> {
|
||||||
|
val answer = this.toList()
|
||||||
|
answer.sort(comparator)
|
||||||
|
return answer
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
TODO figure out necessary variance/generics ninja stuff... :)
|
||||||
|
inline fun <in T> java.lang.Iterable<T>.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||||
|
val answer = this.toList()
|
||||||
|
answer.sort(transform)
|
||||||
|
return answer
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline fun <T> java.lang.Iterable<T>.toList() : List<T> {
|
||||||
|
if (this is List<T>)
|
||||||
|
return this
|
||||||
|
else {
|
||||||
|
val list = ArrayList<T>()
|
||||||
|
for (elem in this)
|
||||||
|
list.add(elem)
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> java.util.Collection<T>.toArray() : Array<T> {
|
||||||
|
if (this is Array<T>)
|
||||||
|
return this
|
||||||
|
else {
|
||||||
|
val answer = Array<T>(this.size)
|
||||||
|
var idx = 0
|
||||||
|
for (elem in this)
|
||||||
|
answer[idx++] = elem
|
||||||
|
return answer as Array<T>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// List APIs
|
||||||
|
|
||||||
|
inline fun <in T: java.lang.Comparable<T>> List<T>.sort() : Unit {
|
||||||
|
Collections.sort(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <in T: java.lang.Comparable<T>> List<T>.sort(comparator: java.util.Comparator<T>) : Unit {
|
||||||
|
Collections.sort(this, comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
TODO figure out necessary variance/generics ninja stuff... :)
|
||||||
|
inline fun <in T> List<T>.sort(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||||
|
val comparator = java.util.Comparator<T>() {
|
||||||
|
fun compare(o1: T, o2: T): Int {
|
||||||
|
val v1 = transform(o1)
|
||||||
|
val v2 = transform(o2)
|
||||||
|
if (v1 == v2) {
|
||||||
|
return 0
|
||||||
|
} else {
|
||||||
|
return v1.compareTo(v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
answer.sort(comparator)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
val <T> List<T>.head : T?
|
||||||
|
get() = this.get(0)
|
||||||
|
|
||||||
|
val <T> List<T>.first : T?
|
||||||
|
get() = this.head
|
||||||
|
|
||||||
|
val <T> List<T>.tail : T?
|
||||||
|
get() {
|
||||||
|
val s = this.size
|
||||||
|
return if (s > 0) this.get(s - 1) else null
|
||||||
|
|
||||||
|
}
|
||||||
|
val <T> List<T>.last : T?
|
||||||
|
get() = this.tail
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
namespace std.util
|
||||||
|
|
||||||
|
/**
|
||||||
|
Executes current block and returns elapsed time in milliseconds
|
||||||
|
*/
|
||||||
|
fun measureTimeMillis(block: fun() : Unit) : Long {
|
||||||
|
val start = System.currentTimeMillis()
|
||||||
|
block()
|
||||||
|
return System.currentTimeMillis() - start
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Executes current block and returns elapsed time in milliseconds
|
||||||
|
*/
|
||||||
|
fun measureTimeNano(block: fun() : Unit) : Long {
|
||||||
|
val start = System.nanoTime()
|
||||||
|
block()
|
||||||
|
return System.nanoTime() - start
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
namespace std.concurrent
|
||||||
|
|
||||||
|
import java.lang.*
|
||||||
|
|
||||||
|
inline var Thread.name : String
|
||||||
|
get() = getName().sure()
|
||||||
|
set(name: String) { setName(name) }
|
||||||
|
|
||||||
|
inline var Thread.daemon : Boolean
|
||||||
|
get() = isDaemon()
|
||||||
|
set(on: Boolean) { setDaemon(on) }
|
||||||
|
|
||||||
|
inline val Thread.alive : Boolean
|
||||||
|
get() = isAlive()
|
||||||
|
|
||||||
|
inline var Thread.priority : Int
|
||||||
|
get() = getPriority()
|
||||||
|
set(prio: Int) { setPriority(prio) }
|
||||||
|
|
||||||
|
inline var Thread.contextClassLoader : ClassLoader?
|
||||||
|
get() = getContextClassLoader()
|
||||||
|
set(loader: ClassLoader?) { setContextClassLoader(loader) }
|
||||||
|
|
||||||
|
fun thread(start: Boolean = true, daemon: Boolean = false, contextClassLoader: ClassLoader? = null, name: String? = null, priority: Int = -1, block: fun():Unit) : Thread {
|
||||||
|
val thread = object: Thread() {
|
||||||
|
override fun run() {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(daemon)
|
||||||
|
thread.setDaemon(true)
|
||||||
|
if(priority > 0)
|
||||||
|
thread.setPriority(priority)
|
||||||
|
if(name != null)
|
||||||
|
thread.setName(name)
|
||||||
|
if(contextClassLoader != null)
|
||||||
|
thread.setContextClassLoader(contextClassLoader)
|
||||||
|
if(start)
|
||||||
|
thread.start()
|
||||||
|
return thread
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface BooleanIterable extends Iterable<Boolean> {
|
||||||
|
@Override
|
||||||
|
BooleanIterator iterator();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface ByteIterable extends Iterable<Byte> {
|
||||||
|
@Override
|
||||||
|
ByteIterator iterator();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface CharIterable extends Iterable<Character> {
|
||||||
|
@Override
|
||||||
|
CharIterator iterator();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface DoubleIterable extends Iterable<Double> {
|
||||||
|
@Override
|
||||||
|
DoubleIterator iterator();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface FloatIterable extends Iterable<Float> {
|
||||||
|
@Override
|
||||||
|
FloatIterator iterator();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface IntIterable extends Iterable<Integer> {
|
||||||
|
@Override
|
||||||
|
IntIterator iterator();
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package jet;
|
|||||||
|
|
||||||
import jet.typeinfo.TypeInfo;
|
import jet.typeinfo.TypeInfo;
|
||||||
|
|
||||||
public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObject {
|
public final class IntRange implements Range<Integer>, IntIterable, JetObject {
|
||||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
|
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
|
||||||
|
|
||||||
private final int start;
|
private final int start;
|
||||||
@@ -39,7 +39,7 @@ public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObj
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Integer> iterator() {
|
public IntIterator iterator() {
|
||||||
return new MyIterator(start, count);
|
return new MyIterator(start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObj
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyIterator implements Iterator<Integer> {
|
private static class MyIterator extends IntIterator {
|
||||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
|
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
|
||||||
|
|
||||||
private int cur;
|
private int cur;
|
||||||
@@ -86,7 +86,7 @@ public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObj
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer next() {
|
public int nextInt() {
|
||||||
count--;
|
count--;
|
||||||
if(reversed) {
|
if(reversed) {
|
||||||
return cur--;
|
return cur--;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface LongIterable extends Iterable<Long> {
|
||||||
|
@Override
|
||||||
|
LongIterator iterator();
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package jet;
|
|||||||
|
|
||||||
import jet.typeinfo.TypeInfo;
|
import jet.typeinfo.TypeInfo;
|
||||||
|
|
||||||
public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
|
public final class LongRange implements Range<Long>, LongIterable, JetObject {
|
||||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
|
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
|
||||||
|
|
||||||
private final long start;
|
private final long start;
|
||||||
@@ -39,7 +39,7 @@ public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Long> iterator() {
|
public LongIterator iterator() {
|
||||||
return new MyIterator(start, count);
|
return new MyIterator(start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyIterator implements Iterator<Long> {
|
private static class MyIterator extends LongIterator {
|
||||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
|
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
|
||||||
|
|
||||||
private long cur;
|
private long cur;
|
||||||
@@ -86,7 +86,7 @@ public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long next() {
|
public long nextLong() {
|
||||||
count--;
|
count--;
|
||||||
if(reversed) {
|
if(reversed) {
|
||||||
return cur--;
|
return cur--;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package jet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public interface ShortIterable extends Iterable<Short> {
|
||||||
|
@Override
|
||||||
|
ShortIterator iterator();
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package jet.runtime;
|
package jet.runtime;
|
||||||
|
|
||||||
|
import jet.Function0;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,6 +31,12 @@ public class Intrinsics {
|
|||||||
return (thisVal == anotherVal ? 0 : (anotherVal ? 1 : -1));
|
return (thisVal == anotherVal ? 0 : (anotherVal ? 1 : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <R> R stupidSync(Object lock, Function0<R> block) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return block.invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Throwable sanitizeStackTrace(Throwable throwable) {
|
private static Throwable sanitizeStackTrace(Throwable throwable) {
|
||||||
StackTraceElement[] stackTrace = throwable.getStackTrace();
|
StackTraceElement[] stackTrace = throwable.getStackTrace();
|
||||||
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
|
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ public @interface JetValueParameter {
|
|||||||
*/
|
*/
|
||||||
boolean hasDefaultValue () default false;
|
boolean hasDefaultValue () default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return if this parameter is receiver
|
||||||
|
*/
|
||||||
|
boolean receiver() default false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return type unless Java type is correct Kotlin type.
|
* @return type unless Java type is correct Kotlin type.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,69 @@
|
|||||||
|
namespace std.test
|
||||||
|
|
||||||
|
import std.io.*
|
||||||
|
import std.util.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
import org.junit.*
|
||||||
|
import org.junit.runner.*
|
||||||
|
import org.junit.runner.notification.*
|
||||||
|
import junit.framework.*
|
||||||
|
|
||||||
|
fun assert(message: String, block: fun() : Boolean) {
|
||||||
|
val actual = block()
|
||||||
|
Assert.assertTrue(message, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assert(block: fun() : Boolean) = assert(block.toString(), block)
|
||||||
|
|
||||||
|
fun assertNot(message: String, block: fun() : Boolean) {
|
||||||
|
assert(message){ !block() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assertNot(block: fun() : Boolean) = assertNot(block.toString(), block)
|
||||||
|
|
||||||
|
fun assert(actual: Boolean, message: String) {
|
||||||
|
println("Answer: ${actual} for ${message}")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assertEquals(expected: Any, actual: Any?, message: String = "") {
|
||||||
|
Assert.assertEquals(message, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assertNull(actual: Any?, message: String = "") {
|
||||||
|
Assert.assertNull(message, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fails(block: fun() : Any) {
|
||||||
|
try {
|
||||||
|
block()
|
||||||
|
Assert.fail("Expected an exception to be thrown")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun todo(block: fun(): Any) {
|
||||||
|
println("TODO at " + Exception().getStackTrace()?.get(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO we could maybe create our own test runner for JUnit
|
||||||
|
to avoid a runtime dependency on JUnit for running tests?
|
||||||
|
|
||||||
|
class KotlinTestRunner() : Runner() {
|
||||||
|
|
||||||
|
override fun getDescription(): Description? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run(notifier: RunNotifier?) {
|
||||||
|
println("About to run a test case on ${this}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO no annotations yet?
|
||||||
|
//@RunWith(KotlinTestRunner)
|
||||||
|
abstract class TestSupport() : TestCase() {
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
namespace test.apicheck
|
||||||
|
|
||||||
|
import std.util.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
trait Traversable<T> {
|
||||||
|
|
||||||
|
/** Returns true if any elements in the collection match the given predicate */
|
||||||
|
fun any(predicate: fun(T): Boolean) : Boolean
|
||||||
|
|
||||||
|
/** Returns true if all elements in the collection match the given predicate */
|
||||||
|
fun all(predicate: fun(T): Boolean) : Boolean
|
||||||
|
|
||||||
|
/** Returns the first item in the collection which matches the given predicate or null if none matched */
|
||||||
|
fun find(predicate: fun(T): Boolean) : T?
|
||||||
|
|
||||||
|
/** Returns a new collection containing all elements in this collection which match the given predicate */
|
||||||
|
// TODO using: Collection<T> for the return type - I wonder if this exact type could be
|
||||||
|
// deduced somewhat from the This.Type; e.g. returning Set on a Set, Array on Array etc
|
||||||
|
fun filter(predicate: fun(T): Boolean) : Collection<T>
|
||||||
|
|
||||||
|
/** Performs the given operation on each element inside the collection */
|
||||||
|
fun foreach(operation: fun(element: T) : Unit)
|
||||||
|
|
||||||
|
/** Returns a new collection containing the results of applying the given function to each element in this collection */
|
||||||
|
fun <T, R> java.lang.Iterable<T>.map(transform : fun(T) : R) : Collection<R>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
TODO try use delegation here to make sure we implement all the methods in the Traversable API
|
||||||
|
|
||||||
|
class ListImpl<T>(coll: ArrayList<out T>) : Traversable<T> by coll {
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
namespace test.collections
|
||||||
|
|
||||||
|
// TODO can we avoid importing all this stuff by default I wonder?
|
||||||
|
// e.g. making println and the collection builder methods public by default?
|
||||||
|
import std.*
|
||||||
|
import std.io.*
|
||||||
|
import std.util.*
|
||||||
|
import std.test.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CollectionTest() : TestSupport() {
|
||||||
|
val data = arrayList("foo", "bar")
|
||||||
|
|
||||||
|
fun testAny() {
|
||||||
|
assert {
|
||||||
|
data.any{it.startsWith("f")}
|
||||||
|
}
|
||||||
|
assertNot {
|
||||||
|
data.any{it.startsWith("x")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testAll() {
|
||||||
|
assert {
|
||||||
|
data.all{it.length == 3}
|
||||||
|
}
|
||||||
|
assertNot {
|
||||||
|
data.all{s => s.startsWith("b")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFilter() {
|
||||||
|
val foo = data.filter{it.startsWith("f")}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
foo.all{it.startsWith("f")}
|
||||||
|
}
|
||||||
|
assertEquals(1, foo.size)
|
||||||
|
assertEquals(arrayList("foo"), foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFilterIntoLinkedList() {
|
||||||
|
// TODO would be nice to avoid the <String>
|
||||||
|
val foo = data.filter(linkedList<String>()){it.startsWith("f")}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
foo.all{it.startsWith("f")}
|
||||||
|
}
|
||||||
|
assertEquals(1, foo.size)
|
||||||
|
assertEquals(linkedList("foo"), foo)
|
||||||
|
|
||||||
|
assert {
|
||||||
|
foo is LinkedList<String>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFilterIntoSortedSet() {
|
||||||
|
// TODO would be nice to avoid the <String>
|
||||||
|
val foo = data.filter(hashSet<String>()){it.startsWith("f")}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
foo.all{it.startsWith("f")}
|
||||||
|
}
|
||||||
|
assertEquals(1, foo.size)
|
||||||
|
assertEquals(hashSet("foo"), foo)
|
||||||
|
|
||||||
|
assert {
|
||||||
|
foo is HashSet<String>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFind() {
|
||||||
|
val x = data.find{it.startsWith("x")}
|
||||||
|
assertNull(x)
|
||||||
|
fails {
|
||||||
|
x.sure()
|
||||||
|
}
|
||||||
|
|
||||||
|
val f = data.find{it.startsWith("f")}
|
||||||
|
f.sure()
|
||||||
|
assertEquals("foo", f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFlatMap() {
|
||||||
|
/**
|
||||||
|
TODO compiler bug
|
||||||
|
we should be able to remove the explicit type on the function
|
||||||
|
http://youtrack.jetbrains.net/issue/KT-849
|
||||||
|
*/
|
||||||
|
// TODO there should be a neater way to do this :)
|
||||||
|
|
||||||
|
val characters = arrayList('f', 'o', 'o', 'b', 'a', 'r')
|
||||||
|
/*
|
||||||
|
val characters = data.flatMap<String,Character>{
|
||||||
|
Arrays.asList((it as java.lang.String).toCharArray()) as Collection<Character>
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
todo {
|
||||||
|
println("Got list of characters ${characters}")
|
||||||
|
val text = characters.join("")
|
||||||
|
assertEquals("foobar", text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testForeach() {
|
||||||
|
var count = 0
|
||||||
|
val x = data.foreach{ count += it.length }
|
||||||
|
assertEquals(6, count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testJoin() {
|
||||||
|
val text = data.join("-", "<", ">")
|
||||||
|
assertEquals("<foo-bar>", text)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testMap() {
|
||||||
|
/**
|
||||||
|
TODO compiler bug
|
||||||
|
we should be able to remove the explicit type on the function
|
||||||
|
http://youtrack.jetbrains.net/issue/KT-849
|
||||||
|
*/
|
||||||
|
val lengths = data.map<String,Int>{s => s.length}
|
||||||
|
assert {
|
||||||
|
lengths.all{it == 3}
|
||||||
|
}
|
||||||
|
assertEquals(2, lengths.size)
|
||||||
|
assertEquals(arrayList(3, 3), lengths)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSort() {
|
||||||
|
val coll: List<String> = arrayList("foo", "bar", "abc")
|
||||||
|
|
||||||
|
// TODO fixme
|
||||||
|
// Some sort of in/out variance thing - or an issue with Java interop?
|
||||||
|
//coll.sort()
|
||||||
|
todo {
|
||||||
|
assertEquals(3, coll.size)
|
||||||
|
assertEquals(arrayList("abc", "bar", "foo"), coll)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testToArray() {
|
||||||
|
val arr = data.toArray()
|
||||||
|
println("Got array ${arr}")
|
||||||
|
todo {
|
||||||
|
assert {
|
||||||
|
arr is Array<String>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
namespace test.collections
|
||||||
|
|
||||||
|
import std.test.*
|
||||||
|
|
||||||
|
// TODO can we avoid importing all this stuff by default I wonder?
|
||||||
|
// e.g. making println and the collection builder methods public by default?
|
||||||
|
import std.*
|
||||||
|
import std.io.*
|
||||||
|
import std.util.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class ListTest() : TestSupport() {
|
||||||
|
val data = arrayList("foo", "bar")
|
||||||
|
|
||||||
|
fun testHeadAndTail() {
|
||||||
|
val h = data.head
|
||||||
|
assertEquals("foo", h)
|
||||||
|
|
||||||
|
val t = data.tail
|
||||||
|
assertEquals("bar", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFirstAndLast() {
|
||||||
|
val h = data.first
|
||||||
|
assertEquals("foo", h)
|
||||||
|
|
||||||
|
val t = data.last
|
||||||
|
assertEquals("bar", t)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
namespace test.collections
|
||||||
|
|
||||||
|
import std.*
|
||||||
|
import std.io.*
|
||||||
|
import std.util.*
|
||||||
|
import std.test.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class SetTest() : TestSupport() {
|
||||||
|
val data = hashSet("foo", "bar")
|
||||||
|
|
||||||
|
fun testAny() {
|
||||||
|
assert {
|
||||||
|
data.any{it.startsWith("f")}
|
||||||
|
}
|
||||||
|
assertNot {
|
||||||
|
data.any{it.startsWith("x")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testAll() {
|
||||||
|
assert {
|
||||||
|
data.all{it.length == 3}
|
||||||
|
}
|
||||||
|
assertNot {
|
||||||
|
data.all{s => s.startsWith("b")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFilter() {
|
||||||
|
val foo = data.filter{it.startsWith("f")}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
foo.all{it.startsWith("f")}
|
||||||
|
}
|
||||||
|
assertEquals(1, foo.size)
|
||||||
|
assertEquals(arrayList("foo"), foo)
|
||||||
|
|
||||||
|
// TODO ideally foo would now be a set
|
||||||
|
todo {
|
||||||
|
assert("Filter on a Set should return a Set") {
|
||||||
|
foo is Set<String>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testFind() {
|
||||||
|
val x = data.find{it.startsWith("x")}
|
||||||
|
assertNull(x)
|
||||||
|
fails {
|
||||||
|
x.sure()
|
||||||
|
}
|
||||||
|
|
||||||
|
val f = data.find{it.startsWith("f")}
|
||||||
|
f.sure()
|
||||||
|
assertEquals("foo", f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testMap() {
|
||||||
|
/**
|
||||||
|
TODO compiler bug
|
||||||
|
we should be able to remove the explicit type on the function
|
||||||
|
http://youtrack.jetbrains.net/issue/KT-849
|
||||||
|
*/
|
||||||
|
val lengths = data.map<String,Int>{s => s.length}
|
||||||
|
assert {
|
||||||
|
lengths.all{it == 3}
|
||||||
|
}
|
||||||
|
assertEquals(2, lengths.size)
|
||||||
|
assertEquals(arrayList(3, 3), lengths)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module-library" exported="">
|
||||||
|
<library>
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MODULE_DIR$/lib/junit-4.9.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module" module-name="stdlib" exported="" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
||||||
Reference in New Issue
Block a user