Merge remote-tracking branch 'origin/master'

This commit is contained in:
svtk
2011-12-20 20:54:43 +04:00
76 changed files with 1962 additions and 296 deletions
+1
View File
@@ -8,3 +8,4 @@ out
.idea/codeStyleSettings.xml
.idea/workspace.xml
tmp
*TestMy.java
+1
View File
@@ -12,6 +12,7 @@
<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$/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>
</project>
@@ -126,9 +126,7 @@ public abstract class ClassBodyCodegen {
}
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(v, "static initializer", myClass);
}
}
}
@@ -147,8 +147,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
mv.visitLabel(ret);
mv.visitInsn(ARETURN);
mv.visitMaxs(0,0);
mv.visitEnd();
FunctionCodegen.endVisit(mv, "$getInstance", fun);
}
}
@@ -205,8 +204,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
iv.areturn(JetTypeMapper.TYPE_OBJECT);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(mv, "bridge", fun);
}
}
@@ -286,8 +284,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
iv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(iv, "constructor", fun);
}
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) {
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) {
@@ -204,7 +212,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetExpression elseExpression = expression.getElse();
if (thenExpression == null && elseExpression == null) {
throw new CompilationException();
throw new CompilationException("Both brunches of if/else are null", null, expression);
}
if (isEmptyExpression(thenExpression)) {
@@ -225,6 +233,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
condition.condJump(elseLabel, true, v); // == 0, i.e. false
Label end = continueLabel == null ? new Label() : continueLabel;
if(continueLabel != null)
asmType = Type.VOID_TYPE;
gen(thenExpression, asmType);
@@ -1126,7 +1137,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, callee);
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);
@@ -1403,7 +1414,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
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());
if(resolvedCall != null) {
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);
if(resolvedCall == 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();
@@ -2098,7 +2109,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else {
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();
}
private static class CompilationException extends RuntimeException {
private CompilationException() {
}
private CompilationException(String message) {
super(message);
}
}
@Override
public String toString() {
return context.getContextDescriptor().toString();
@@ -110,6 +110,7 @@ public class FunctionCodegen {
if(receiverParameter.getType().isNullable()) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
}
av.visit(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
av.visitEnd();
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
@@ -223,7 +224,7 @@ public class FunctionCodegen {
k += type.getSize();
}
mv.visitMaxs(0, 0);
endVisit(mv, null, fun);
mv.visitEnd();
generateBridgeIfNeeded(owner, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind);
@@ -233,6 +234,16 @@ public class FunctionCodegen {
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) {
Set<? extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenDescriptors();
if(kind != OwnerKind.TRAIT_IMPL) {
@@ -390,7 +401,7 @@ public class FunctionCodegen {
iv.areturn(jvmSignature.getReturnType());
mv.visitMaxs(0, 0);
endVisit(mv, "default method", state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, functionDescriptor));
mv.visitEnd();
}
}
@@ -426,7 +437,7 @@ public class FunctionCodegen {
if(jvmSignature.getReturnType() == Type.VOID_TYPE)
iv.aconst(null);
iv.areturn(overriden.getReturnType());
mv.visitMaxs(0, 0);
endVisit(mv, "bridge method", state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, functionDescriptor));
mv.visitEnd();
}
}
@@ -198,8 +198,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType());
mv.visitMaxs(0,0);
mv.visitEnd();
FunctionCodegen.endVisit(iv, "accessor", null);
}
}
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.areturn(method.getReturnType());
mv.visitMaxs(0,0);
mv.visitEnd();
FunctionCodegen.endVisit(iv, "accessor", null);
}
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.areturn(method.getReturnType());
mv.visitMaxs(0,0);
mv.visitEnd();
FunctionCodegen.endVisit(iv, "accessor", null);
}
}
else {
@@ -465,8 +462,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
outer.visitVarInsn(Opcodes.ALOAD, 0);
outer.visitFieldInsn(Opcodes.GETFIELD, classname, "this$0", outerType.getDescriptor());
outer.visitInsn(Opcodes.ARETURN);
outer.visitMaxs(0, 0);
outer.visitEnd();
FunctionCodegen.endVisit(outer, "getOuterObject", myClass);
}
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
@@ -518,8 +514,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateTraitMethods(codegen);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(mv, "constructor", myClass);
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod, constructorDescriptor, OwnerKind.IMPLEMENTATION);
}
@@ -572,8 +567,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.checkcast(function.getReturnType());
}
iv.areturn(function.getReturnType());
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(iv, "trait method", bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, fun));
}
FunctionCodegen.generateBridgeIfNeeded(context, state, v, function, fun, kind);
@@ -708,8 +702,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(mv, "constructor", null);
}
}
@@ -821,8 +814,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
iv.areturn(JetTypeMapper.TYPE_TYPEINFO);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(iv, "getTypeInfo", myClass);
}
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.putfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(iv, "$setTypeInfo", myClass);
}
}
}
@@ -853,8 +844,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
v.getstatic(owner, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(v, "getTypeInfo", myClass);
}
}
@@ -66,7 +66,6 @@ public class JetTypeMapper {
private final HashMap<JetType,String> knowTypeNames = new HashMap<JetType, String>();
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_INT_RANGE = Type.getObjectType("jet/IntRange");
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_FLOAT_ITERATOR = Type.getObjectType("jet/FloatIterator");
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() {
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();
@@ -62,8 +62,11 @@ public class NamespaceCodegen {
else if (declaration instanceof JetNamedFunction) {
try {
functionCodegen.gen((JetNamedFunction) declaration);
} catch (Exception e) {
throw new RuntimeException("Failed to generate function " + declaration.getName(), e);
} catch (CompilationException e) {
throw e;
}
catch (Exception e) {
throw new CompilationException("Failed to generate function " + declaration.getName(), e, declaration);
}
}
else if (declaration instanceof JetClassOrObject) {
@@ -107,7 +110,7 @@ public class NamespaceCodegen {
}
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
FunctionCodegen.endVisit(mv, "static initializer for namespace", namespace);
mv.visitEnd();
}
}
@@ -134,8 +137,7 @@ public class NamespaceCodegen {
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
v.visitLabel(end);
v.visitInsn(ARETURN);
v.visitMaxs(0, 0);
v.visitEnd();
FunctionCodegen.endVisit(v, "type info method", namespace);
}
}
}
@@ -154,8 +154,7 @@ public class PropertyCodegen {
type.getDescriptor());
}
iv.areturn(type);
mv.visitMaxs(0, 0);
mv.visitEnd();
FunctionCodegen.endVisit(mv, "getter", origin);
}
}
@@ -207,7 +206,7 @@ public class PropertyCodegen {
}
iv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
FunctionCodegen.endVisit(mv, "setter", origin);
mv.visitEnd();
}
}
@@ -20,6 +20,7 @@ import java.util.*;
/**
* @author yole
* @author alex.tkachman
*/
public class IntrinsicMethods {
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("Array"), 1, new NewArray());
declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure());
declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 1, new StupidSync());
declareIntrinsicFunction("ByteIterator", "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);
}
}
@@ -9,6 +9,7 @@ import com.intellij.psi.*;
import com.intellij.psi.search.DelegatingGlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScope;
import jet.typeinfo.TypeInfoVariance;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -56,9 +57,38 @@ public class JavaDescriptorResolver {
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<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
protected final Map<PsiElement, NamespaceDescriptor> namespaceDescriptorCache = Maps.newHashMap();
@@ -145,11 +175,8 @@ public class JavaDescriptorResolver {
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
// TODO: initialize
if (psiClass.getModifierList().findAnnotation(StdlibNames.JET_CLASS.getFqName()) == null) {
// UGLY HACK (Andrey Breslav is not sure what did he mean)
initializeTypeParameters(psiClass);
}
// UGLY HACK (Andrey Breslav is not sure what did he mean)
initializeTypeParameters(psiClass);
supertypes.addAll(getSupertypes(psiClass));
if (psiClass.isInterface()) {
@@ -188,7 +215,11 @@ public class JavaDescriptorResolver {
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
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));
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor);
@@ -208,7 +239,7 @@ public class JavaDescriptorResolver {
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
if (typeParametersString != null) {
return resolveClassTypeParametersFromJetSignature(typeParametersString, classDescriptor);
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor);
}
}
}
@@ -216,49 +247,107 @@ public class JavaDescriptorResolver {
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)
*/
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>();
new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
@Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
return new JetSignatureExceptionsAdapter() {
int index = 0;
return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance) {
@Override
public JetSignatureVisitor visitClassBound() {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
@Override
protected void done(@NotNull JetType jetType) {
// TODO
}
};
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
r.add(typeParameterDescriptor);
}
@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.getIndex()
);
typeParameterDescriptorCache.put(psiTypeParameter, typeParameterDescriptor);
typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameterDescriptor));
return typeParameterDescriptor;
}
private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptor typeParameterDescriptor) {
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));
private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor;
if (typeParameterDescriptorInitialization.origin == TypeParameterDescriptorOrigin.KOTLIN) {
List<?> upperBounds = typeParameterDescriptorInitialization.upperBoundsForKotlin;
if (upperBounds.size() == 0){
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
} else {
for (JetType upperBound : typeParameterDescriptorInitialization.upperBoundsForKotlin) {
typeParameterDescriptor.addUpperBound(upperBound);
}
}
// 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) {
for (PsiTypeParameter psiTypeParameter : typeParameterListOwner.getTypeParameters()) {
initializeTypeParameter(psiTypeParameter, resolveTypeParameter(psiTypeParameter));
initializeTypeParameter(psiTypeParameter, resolveTypeParameterInitialization(psiTypeParameter));
}
}
@NotNull
private TypeParameterDescriptor resolveTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
private TypeParameterDescriptorInitialization resolveTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
TypeParameterDescriptorInitialization typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
assert typeParameterDescriptor != null : psiTypeParameter.getText();
return typeParameterDescriptor;
}
@@ -423,21 +527,71 @@ public class JavaDescriptorResolver {
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceDescriptor);
return namespaceDescriptor;
}
private static class ValueParameterDescriptors {
private final JetType receiverType;
private final List<ValueParameterDescriptor> descriptors;
public List<ValueParameterDescriptor> resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
PsiParameter parameter = parameters[i];
ValueParameterDescriptor valueParameterDescriptor = resolveParameterDescriptor(containingDeclaration, i, parameter);
if (valueParameterDescriptor != null) {
result.add(valueParameterDescriptor);
}
private ValueParameterDescriptors(@Nullable JetType receiverType, List<ValueParameterDescriptor> descriptors) {
this.receiverType = receiverType;
this.descriptors = descriptors;
}
return result;
}
@Nullable
private ValueParameterDescriptor resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) {
public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) {
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();
JetType varargElementType;
@@ -453,13 +607,11 @@ public class JavaDescriptorResolver {
boolean nullable = true;
String typeFromAnnotation = null;
boolean receiver = false;
// TODO: must be very slow, make it lazy?
String name = parameter.getName() != null ? parameter.getName() : "p" + i;
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())) {
PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD);
@@ -480,8 +632,16 @@ public class JavaDescriptorResolver {
if (signatureExpression != null) {
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())) {
return null;
return JvmMethodParameterMeaning.typeInfo(new Object());
}
}
@@ -491,16 +651,20 @@ public class JavaDescriptorResolver {
} else {
outType = semanticServices.getTypeTransformer().transformToType(psiType);
}
return new ValueParameterDescriptorImpl(
containingDeclaration,
i,
Collections.<AnnotationDescriptor>emptyList(), // TODO
name,
null, // TODO : review
changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType,
false,
varargElementType
);
if (receiver) {
return JvmMethodParameterMeaning.receiver(outType);
} else {
return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl(
containingDeclaration,
i,
Collections.<AnnotationDescriptor>emptyList(), // TODO
name,
null, // TODO : review
changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType,
false,
varargElementType
));
}
}
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
@@ -592,12 +756,13 @@ public class JavaDescriptorResolver {
);
methodDescriptorCache.put(method, functionDescriptorImpl);
List<TypeParameterDescriptor> typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl);
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters);
functionDescriptorImpl.initialize(
null,
valueParameterDescriptors.receiverType,
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
typeParameters,
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
semanticServices.getDescriptorResolver().makeReturnType(returnType, method),
valueParameterDescriptors.descriptors,
makeReturnType(returnType, method),
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
resolveVisibilityFromPsiModifiers(method)
);
@@ -616,7 +781,9 @@ public class JavaDescriptorResolver {
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
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>();
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
@Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
return new JetSignatureExceptionsAdapter() {
int index = 0;
return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance) {
@Override
public JetSignatureVisitor visitClassBound() {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
@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);
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
r.add(typeParameterDescriptor);
}
};
}
});
return r;
@@ -719,7 +858,8 @@ public class JavaDescriptorResolver {
(modifierListOwner.hasModifierProperty(PsiModifier.PROTECTED) ? Visibility.PROTECTED : Visibility.INTERNAL));
}
public TypeParameterDescriptor resolveTypeParameter(PsiTypeParameter typeParameter) {
@NotNull
private TypeParameterDescriptorInitialization resolveTypeParameterInitialization(PsiTypeParameter typeParameter) {
PsiTypeParameterListOwner owner = typeParameter.getOwner();
if (owner instanceof PsiClass) {
PsiClass psiClass = (PsiClass) owner;
@@ -744,4 +884,8 @@ public class JavaDescriptorResolver {
}
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_NULLABLE_FIELD = "nullable";
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");
+35 -1
View File
@@ -34,6 +34,8 @@ namespace io {
fun readLine() : String?
}
fun <R> Any.synchronized(block : fun() : R) : R
fun Any?.identityEquals(other : Any?) : Boolean // = this === other
// 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>
}
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?>
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
}
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 contains (elem: Int) : Boolean
@@ -28,6 +28,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
int index) {
TypeParameterDescriptor typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index);
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound());
typeParameterDescriptor.setInitialized();
return typeParameterDescriptor;
}
@@ -52,6 +53,8 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
private final boolean reified;
private boolean initialized = false;
private TypeParameterDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
@@ -74,25 +77,61 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
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() {
checkInitialized();
return reified;
}
public Variance getVariance() {
checkInitialized();
return variance;
}
public void addUpperBound(@NotNull JetType bound) {
checkUninitialized();
doAddUpperBound(bound);
}
private void doAddUpperBound(JetType bound) {
upperBounds.add(bound); // TODO : Duplicates?
}
public void addDefaultUpperBound() {
checkUninitialized();
if (upperBounds.isEmpty()) {
doAddUpperBound(JetStandardClasses.getDefaultBound());
}
}
@NotNull
public Set<JetType> getUpperBounds() {
checkInitialized();
return upperBounds;
}
@NotNull
public JetType getUpperBoundsAsType() {
checkInitialized();
if (upperBoundsAsType == null) {
assert upperBounds != null : "Upper bound list is null in " + getName();
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
@@ -106,11 +145,13 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
@NotNull
public Set<JetType> getLowerBounds() {
//checkInitialized();
return Collections.singleton(JetStandardClasses.getNothingType());
}
@NotNull
public JetType getLowerBoundsAsType() {
checkInitialized();
return JetStandardClasses.getNothingType();
}
@@ -118,6 +159,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
//checkInitialized();
return typeConstructor;
}
@@ -135,12 +177,14 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
checkInitialized();
return visitor.visitTypeParameterDescriptor(this, data);
}
@NotNull
@Override
public JetType getDefaultType() {
//checkInitialized();
if (defaultType == null) {
defaultType = new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
@@ -159,6 +203,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
@Override
public JetType getClassObjectType() {
checkInitialized();
if (classObjectUpperBounds.isEmpty()) return null;
if (classObjectBoundsAsType == null) {
@@ -176,15 +221,19 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
}
public void addClassObjectBound(@NotNull JetType bound) {
checkUninitialized();
classObjectUpperBounds.add(bound); // TODO : Duplicates?
}
public int getIndex() {
checkInitialized();
return index;
}
@NotNull
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) {
if (parameter.getUpperBounds().isEmpty()) {
parameter.addUpperBound(JetStandardClasses.getDefaultBound());
}
parameter.addDefaultUpperBound();
parameter.setInitialized();
if (JetStandardClasses.isNothing(parameter.getUpperBoundsAsType())) {
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.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.*;
@@ -348,7 +349,7 @@ public class CallResolver {
if (callElement instanceof JetBinaryExpression) {
JetBinaryExpression binaryExpression = (JetBinaryExpression) callElement;
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();
if (right != null) {
trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, right.getText()));
@@ -510,15 +511,6 @@ public class CallResolver {
}
else {
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)));
}
}
@@ -259,7 +259,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
assert constraintQueue.isEmpty() || unsolvedUnknowns.isEmpty() : constraintQueue + " " + unsolvedUnknowns;
for (TypeValue unknown : unsolvedUnknowns) {
for (TypeValue unknown : Sets.newLinkedHashSet(unsolvedUnknowns)) {
if (!computeValueFor(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");
@@ -44,6 +44,7 @@ public class DescriptorSubstitutor {
descriptor.getVariance(),
descriptor.getName(),
descriptor.getIndex());
substituted.setInitialized();
mutableSubstitution.put(descriptor.getTypeConstructor(), new TypeProjection(substituted.getDefaultType()));
@@ -1,10 +1,11 @@
package org.jetbrains.jet.lang.types.expressions;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
/**
@@ -12,6 +13,10 @@ import org.jetbrains.jet.lexer.JetTokens;
*/
public class OperatorConventions {
public static final String EQUALS = "equals";
public static final String COMPARE_TO = "compareTo";
public static final String CONTAINS = "contains";
private OperatorConventions() {}
public static final ImmutableSet<String> NUMBER_CONVERSIONS = ImmutableSet.of(
@@ -23,7 +28,7 @@ public class OperatorConventions {
"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.MINUSMINUS, "dec")
.put(JetTokens.PLUS, "plus")
@@ -31,7 +36,7 @@ public class OperatorConventions {
.put(JetTokens.EXCL, "not")
.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.PLUS, "plus")
.put(JetTokens.MINUS, "minus")
@@ -41,11 +46,22 @@ public class OperatorConventions {
.put(JetTokens.RANGE, "rangeTo")
.build();
public static final ImmutableSet<IElementType> COMPARISON_OPERATIONS = ImmutableSet.<IElementType>of(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ);
public static final ImmutableSet<IElementType> EQUALS_OPERATIONS = ImmutableSet.<IElementType>of(JetTokens.EQEQ, JetTokens.EXCLEQ);
public static final ImmutableSet<JetToken> NOT_OVERLOADABLE =
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 ImmutableMap<IElementType, String> ASSIGNMENT_OPERATIONS = ImmutableMap.<IElementType, String>builder()
public static final ImmutableSet<JetToken> COMPARISON_OPERATIONS =
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.DIVEQ, "divAssign")
.put(JetTokens.PERCEQ, "modAssign")
@@ -53,7 +69,7 @@ public class OperatorConventions {
.put(JetTokens.MINUSEQ, "minusAssign")
.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.DIVEQ, JetTokens.DIV)
.put(JetTokens.PERCEQ, JetTokens.PERC)
@@ -62,17 +78,16 @@ public class OperatorConventions {
.build();
@Nullable
public static String getNameForOperationSymbol(@NotNull IElementType token) {
public static String getNameForOperationSymbol(@NotNull JetToken token) {
String name = UNARY_OPERATION_NAMES.get(token);
if (name != null) return name;
name = BINARY_OPERATION_NAMES.get(token);
if (name != null) return name;
name = ASSIGNMENT_OPERATIONS.get(token);
if (name != null) return name;
if (COMPARISON_OPERATIONS.contains(token)) return "compareTo";
if (EQUALS_OPERATIONS.contains(token)) return "equals";
if (IN_OPERATIONS.contains(token)) return "contains";
if (COMPARISON_OPERATIONS.contains(token)) return COMPARE_TO;
if (EQUALS_OPERATIONS.contains(token)) return EQUALS;
if (IN_OPERATIONS.contains(token)) return CONTAINS;
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;
import com.intellij.lang.LanguageASTFactory;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.psi.impl.source.tree.JavaASTFactory;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.testFramework.UsefulTestCase;
import junit.framework.Test;
@@ -70,8 +67,6 @@ public class CompileJavaAgainstKotlinTest extends UsefulTestCase {
protected void runTest() throws Throwable {
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
LanguageASTFactory.INSTANCE.addExplicitExtension(JavaLanguage.INSTANCE, new JavaASTFactory());
String text = FileUtil.loadFile(ktFile);
@@ -1,14 +1,11 @@
package org.jetbrains.jet;
import com.intellij.lang.LanguageASTFactory;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.psi.impl.source.tree.JavaASTFactory;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.testFramework.UsefulTestCase;
import junit.framework.Test;
@@ -18,15 +15,7 @@ import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.compiler.CompileEnvironment;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
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.descriptors.*;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
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.JavaSemanticServices;
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.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.plugin.JetLanguage;
@@ -44,6 +33,7 @@ import org.junit.Assert;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -92,9 +82,6 @@ public class ReadClassDataTest extends UsefulTestCase {
public void runTest() throws Exception {
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
LanguageASTFactory.INSTANCE.addExplicitExtension(JavaLanguage.INSTANCE, new JavaASTFactory());
String text = FileUtil.loadFile(testFile);
LightVirtualFile virtualFile = new LightVirtualFile(testFile.getName(), JetLanguage.INSTANCE, text);
@@ -159,7 +146,8 @@ public class ReadClassDataTest extends UsefulTestCase {
private String serializeContent(ClassDescriptor klass) {
StringBuilder sb = new StringBuilder();
sb.append("class ");
serialize(klass.getKind(), sb);
sb.append(" ");
serialize(klass, sb);
@@ -174,9 +162,6 @@ public class ReadClassDataTest extends UsefulTestCase {
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>();
for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) {
typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType()));
@@ -184,15 +169,37 @@ public class ReadClassDataTest extends UsefulTestCase {
JetScope memberScope = klass.getMemberScope(typeArguments);
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);
sb.append("\n");
}
}
sb.append("}\n");
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) {
@@ -220,6 +227,12 @@ public class ReadClassDataTest extends UsefulTestCase {
serializeCommaSeparated(fun.getTypeParameters(), sb);
sb.append(">");
}
if (fun.getReceiverParameter().exists()) {
serialize(fun.getReceiverParameter(), sb);
sb.append(".");
}
sb.append(fun.getName());
sb.append("(");
serializeCommaSeparated(fun.getValueParameters(), sb);
@@ -227,6 +240,21 @@ public class ReadClassDataTest extends UsefulTestCase {
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) {
sb.append(valueParameter.getName());
sb.append(": ");
@@ -274,16 +302,20 @@ public class ReadClassDataTest extends UsefulTestCase {
}
private void serializeCommaSeparated(List<?> list, StringBuilder sb) {
serializeSeparated(list, sb, ", ");
}
private void serializeSeparated(List<?> list, StringBuilder sb, String sep) {
boolean first = true;
for (Object o : list) {
if (!first) {
sb.append(", ");
sb.append(sep);
}
serialize(o, sb);
first = false;
}
}
private Method getMethodToSerialize(Object o) {
// TODO: cache
for (Method method : ReadClassDataTest.class.getDeclaredMethods()) {
@@ -311,6 +343,10 @@ public class ReadClassDataTest extends UsefulTestCase {
Method method = getMethodToSerialize(o);
invoke(method, this, o, sb);
}
private void serialize(String s, StringBuilder sb) {
sb.append(s);
}
private void serialize(ModuleDescriptor module, StringBuilder sb) {
// nop
@@ -331,11 +367,20 @@ public class ReadClassDataTest extends UsefulTestCase {
sb.append(".");
sb.append(ns.getName());
}
private void serialize(TypeParameterDescriptor param, StringBuilder sb) {
serialize(param.getVariance(), sb);
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());
}
public void testKt779 () throws Exception {
blackBoxFile("regressions/kt779.jet");
// System.out.println(generateToText());
}
public void testCreateMultiInt () throws Exception {
loadText("fun foo() = Array<Array<Int>> (5, { Array<Int>(it, {239}) })");
Method foo = generateFunction();
@@ -231,8 +231,25 @@ public class ControlStructuresTest extends CodegenTestCase {
// System.out.println(generateToText());
}
public void testKt772() throws Exception {
blackBoxFile("regressions/kt772.jet");
// System.out.println(generateToText());
}
public void testQuicksort() throws Exception {
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());
}
}
@@ -138,6 +138,11 @@ public class TypeInfoTest extends CodegenTestCase {
// System.out.println(generateToText());
}
public void testKt511() throws Exception {
blackBoxFile("regressions/kt511.jet");
// System.out.println(generateToText());
}
public void testInner() throws Exception {
blackBoxFile("typeInfo/inner.jet");
System.out.println(generateToText());
+22 -33
View File
@@ -1,20 +1,13 @@
namespace lockperformance
import std.io.*
import std.util.*
import std.concurrent.*
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CountDownLatch;
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 {
val cdl = CountDownLatch(this)
val res = cdl.op()
@@ -22,41 +15,37 @@ fun <T> Int.latch(op: fun CountDownLatch.() : T) : T {
return res
}
fun Int.times(action: fun Int.()) {
for(i in 0..this-1)
action()
}
fun main(args: Array<String>) {
val processors = Runtime.getRuntime().sure().availableProcessors()
var threadNum = 1
while(threadNum <= 1024) {
val counter = AtomicInteger()
val start = System.currentTimeMillis()
threadNum.latch{
val lock = ReentrantLock()
threadNum.times {
thread {
while(true) {
lock.lock()
try {
if (counter.get() == 100000000) {
countDown();
break;
} else {
counter.incrementAndGet();
val duration = measureTimeMillis {
threadNum.latch{
val lock = ReentrantLock()
for(i in 0..threadNum-1) {
thread {
while(true) {
lock.lock()
try {
if (counter.get() == 100000000) {
countDown();
break;
} else {
counter.incrementAndGet();
}
}
finally {
lock.unlock()
}
}
finally {
lock.unlock()
}
}
}
}
}
System.out?.println(threadNum.toString() + " " + (System.currentTimeMillis() - start));
println(threadNum.toString() + " " + duration)
if(threadNum < 2 * processors)
threadNum = threadNum + 1
@@ -16,10 +16,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.Chunk;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.CompilationErrorHandler;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -102,7 +99,12 @@ public class JetCompiler implements TranslatingCompiler {
generationState.compileCorrectNamespaces(bindingContext, namespaces, new CompilationErrorHandler() {
@Override
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 final GenerationState state;
// private final CompileContext compileContext;
@@ -1,7 +1,6 @@
package org.jetbrains.jet.plugin.compiler;
import com.google.common.collect.Sets;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
@@ -41,7 +40,7 @@ public final class WholeProjectAnalyzerFacade {
final Set<JetDeclaration> namespaces = Sets.newLinkedHashSet();
final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
if (rootManager != null && !ApplicationManager.getApplication().isUnitTestMode()) {
if (rootManager != null /* && !ApplicationManager.getApplication().isUnitTestMode() */) {
VirtualFile[] contentRoots = rootManager.getContentRoots();
CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() {
@@ -57,7 +56,6 @@ public final class WholeProjectAnalyzerFacade {
}
}
});
}
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() {
//setFilter(); //to launch only part of tests
TestSuite suite = new TestSuite();
FilenameFilter fileNameFilter = new FilenameFilter() {
FilenameFilter singleFileNameFilter = new FilenameFilter() {
@Override
public boolean accept(File file, String s) {
if (s.startsWith("before")) return true;
return false;
return s.startsWith("before") && !JetPsiCheckerMultifileTest.isMultiFileName(s);
}
};
JetTestCaseBuilder.NamedTestFactory namedTestFactory = new JetTestCaseBuilder.NamedTestFactory() {
JetTestCaseBuilder.NamedTestFactory singleFileNamedTestFactory = new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetQuickFixTest(dataPath, name);
}
};
File dir = new File(getTestDataPathBase());
List<String> subDirs = Arrays.asList(quickFixTestsFilter != null ? dir.list(quickFixTestsFilter) : dir.list());
Collections.sort(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;
}
+82
View File
@@ -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>
+66
View File
@@ -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()
}
}
+38
View File
@@ -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>())
+204
View File
@@ -2,8 +2,212 @@ namespace std.util
import java.util.*
/** Returns the size of the collection */
val Collection<*>.size : Int
get() = size()
/** Returns true if this collection is empty */
val Collection<*>.empty : Boolean
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
+19
View File
@@ -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
}
+41
View File
@@ -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
}
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface BooleanIterable extends Iterable<Boolean> {
@Override
BooleanIterator iterator();
}
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface ByteIterable extends Iterable<Byte> {
@Override
ByteIterator iterator();
}
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface CharIterable extends Iterable<Character> {
@Override
CharIterator iterator();
}
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface DoubleIterable extends Iterable<Double> {
@Override
DoubleIterator iterator();
}
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface FloatIterable extends Iterable<Float> {
@Override
FloatIterator iterator();
}
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface IntIterable extends Iterable<Integer> {
@Override
IntIterator iterator();
}
+4 -4
View File
@@ -2,7 +2,7 @@ package jet;
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 int start;
@@ -39,7 +39,7 @@ public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObj
}
@Override
public Iterator<Integer> iterator() {
public IntIterator iterator() {
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 int cur;
@@ -86,7 +86,7 @@ public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObj
}
@Override
public Integer next() {
public int nextInt() {
count--;
if(reversed) {
return cur--;
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface LongIterable extends Iterable<Long> {
@Override
LongIterator iterator();
}
+4 -4
View File
@@ -2,7 +2,7 @@ package jet;
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 long start;
@@ -39,7 +39,7 @@ public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
}
@Override
public Iterator<Long> iterator() {
public LongIterator iterator() {
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 long cur;
@@ -86,7 +86,7 @@ public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
}
@Override
public Long next() {
public long nextLong() {
count--;
if(reversed) {
return cur--;
+9
View File
@@ -0,0 +1,9 @@
package jet;
/**
* @author alex.tkachman
*/
public interface ShortIterable extends Iterable<Short> {
@Override
ShortIterator iterator();
}
+8
View File
@@ -1,5 +1,7 @@
package jet.runtime;
import jet.Function0;
import java.util.ArrayList;
/**
@@ -29,6 +31,12 @@ public class Intrinsics {
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) {
StackTraceElement[] stackTrace = throwable.getStackTrace();
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
@@ -35,6 +35,11 @@ public @interface JetValueParameter {
*/
boolean hasDefaultValue () default false;
/**
* @return if this parameter is receiver
*/
boolean receiver() default false;
/**
* @return type unless Java type is correct Kotlin type.
*/
Binary file not shown.
+69
View File
@@ -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() {
}
+35
View File
@@ -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 {
}
*/
+153
View File
@@ -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>
}
}
}
}
+30
View File
@@ -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)
}
}
+73
View File
@@ -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)
}
}
+23
View File
@@ -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>