Merge remote-tracking branch 'origin/master'

Conflicts:
	compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java
This commit is contained in:
svtk
2011-12-06 22:42:50 +04:00
104 changed files with 1352 additions and 373 deletions
@@ -81,9 +81,14 @@ public class CallableMethod implements Callable {
public void invokeWithDefault(InstructionAdapter v, int mask) { public void invokeWithDefault(InstructionAdapter v, int mask) {
v.iconst(mask); v.iconst(mask);
String desc = getSignature().getDescriptor().replace(")", "I)"); String desc = getSignature().getDescriptor().replace(")", "I)");
if(getInvokeOpcode() != Opcodes.INVOKESTATIC) if("<init>".equals(getSignature().getName())) {
desc = desc.replace("(", "(L" + getOwner() + ";"); v.visitMethodInsn(Opcodes.INVOKESPECIAL, getOwner(), "<init>", desc);
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getName() + "$default", desc); }
else {
if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
desc = desc.replace("(", "(L" + getOwner() + ";");
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getName() + "$default", desc);
}
} }
public boolean isNeedsThis() { public boolean isNeedsThis() {
@@ -124,15 +124,17 @@ public abstract class CodegenContext {
return new ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName); return new ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName);
} }
public FrameMap prepareFrame() { public FrameMap prepareFrame(JetTypeMapper mapper) {
FrameMap frameMap = new FrameMap(); FrameMap frameMap = new FrameMap();
if (getContextKind() != OwnerKind.NAMESPACE) { if (getContextKind() != OwnerKind.NAMESPACE) {
frameMap.enterTemp(); // 0 slot for this frameMap.enterTemp(); // 0 slot for this
} }
if (getReceiverDescriptor() != null) { CallableDescriptor receiverDescriptor = getReceiverDescriptor();
frameMap.enterTemp(); // Next slot for fake this if (receiverDescriptor != null) {
Type type = mapper.mapType(receiverDescriptor.getReceiverParameter().getType());
frameMap.enterTemp(type.getSize()); // Next slot for fake this
} }
return frameMap; return frameMap;
@@ -1196,7 +1196,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
receiver.put(receiver.type, v); receiver.put(receiver.type, v);
} }
protected void generateFromResolvedCall(ReceiverDescriptor descriptor, Type type) { public void generateFromResolvedCall(ReceiverDescriptor descriptor, Type type) {
if(descriptor instanceof ClassReceiver) { if(descriptor instanceof ClassReceiver) {
Type exprType = asmType(descriptor.getType()); Type exprType = asmType(descriptor.getType());
ClassReceiver classReceiver = (ClassReceiver) descriptor; ClassReceiver classReceiver = (ClassReceiver) descriptor;
@@ -1377,7 +1377,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType receiverJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression()); JetType receiverJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression());
Type receiverType = asmType(receiverJetType); Type receiverType = asmType(receiverJetType);
gen(expr, receiverType); gen(expr, receiverType);
if(receiverType.getSort() != Type.OBJECT && receiverType.getSort() != Type.ARRAY) { assert receiverJetType != null;
if(!receiverJetType.isNullable()) {
StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression()); StackValue propValue = genQualified(StackValue.onStack(receiverType), expression.getSelectorExpression());
Type type = propValue.type; Type type = propValue.type;
propValue.put(type, v); propValue.put(type, v);
@@ -1691,18 +1692,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private StackValue generateElvis(JetBinaryExpression expression) { private StackValue generateElvis(JetBinaryExpression expression) {
final Type exprType = expressionType(expression); final Type exprType = expressionType(expression);
final Type leftType = expressionType(expression.getLeft()); JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLeft());
gen(expression.getLeft(), leftType); assert type != null;
v.dup(); final Type leftType = asmType(type);
Label end = new Label(); if(type.isNullable()) {
Label ifNull = new Label(); gen(expression.getLeft(), leftType);
v.ifnull(ifNull); v.dup();
StackValue.onStack(leftType).put(exprType, v); Label end = new Label();
v.goTo(end); Label ifNull = new Label();
v.mark(ifNull); v.ifnull(ifNull);
v.pop(); StackValue.onStack(leftType).put(exprType, v);
gen(expression.getRight(), exprType); v.goTo(end);
v.mark(end); v.mark(ifNull);
v.pop();
gen(expression.getRight(), exprType);
v.mark(end);
}
else {
gen(expression.getLeft(), leftType);
StackValue.onStack(leftType).put(exprType, v);
}
return StackValue.onStack(exprType); return StackValue.onStack(exprType);
} }
@@ -1830,7 +1839,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override @Override
public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) { public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationSign()); DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
final Callable callable = resolveToCallable(op, false); final Callable callable = resolveToCallable(op, false);
if (callable instanceof IntrinsicMethod) { if (callable instanceof IntrinsicMethod) {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable; IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
@@ -1847,7 +1856,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override @Override
public StackValue visitPostfixExpression(JetPostfixExpression expression, StackValue receiver) { public StackValue visitPostfixExpression(JetPostfixExpression expression, StackValue receiver) {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationSign()); DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
if (op instanceof FunctionDescriptor) { if (op instanceof FunctionDescriptor) {
final Type asmType = expressionType(expression); final Type asmType = expressionType(expression);
DeclarationDescriptor cls = op.getContainingDeclaration(); DeclarationDescriptor cls = op.getContainingDeclaration();
@@ -1,10 +1,12 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
@@ -26,17 +28,19 @@ public class FunctionCodegen {
private final CodegenContext owner; private final CodegenContext owner;
private final ClassBuilder v; private final ClassBuilder v;
private final GenerationState state; private final GenerationState state;
private final JetTypeMapper typeMapper;
public FunctionCodegen(CodegenContext owner, ClassBuilder v, GenerationState state) { public FunctionCodegen(CodegenContext owner, ClassBuilder v, GenerationState state) {
this.owner = owner; this.owner = owner;
this.v = v; this.v = v;
this.state = state; this.state = state;
typeMapper = state.getTypeMapper();
} }
public void gen(JetNamedFunction f) { public void gen(JetNamedFunction f) {
final FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f); final FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f);
assert functionDescriptor != null; assert functionDescriptor != null;
Method method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature(); Method method = typeMapper.mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature();
generateMethod(f, method, functionDescriptor); generateMethod(f, method, functionDescriptor);
} }
@@ -59,31 +63,77 @@ public class FunctionCodegen {
OwnerKind kind = context.getContextKind(); OwnerKind kind = context.getContextKind();
ReceiverDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
if (kind != OwnerKind.TRAIT_IMPL || bodyExpressions != null) { if (kind != OwnerKind.TRAIT_IMPL || bodyExpressions != null) {
boolean isStatic = kind == OwnerKind.NAMESPACE;
if (isStatic || kind == OwnerKind.TRAIT_IMPL)
flags |= ACC_STATIC;
boolean isStatic = kind == OwnerKind.NAMESPACE || kind == OwnerKind.TRAIT_IMPL; boolean isAbstract = !isStatic && !(kind == OwnerKind.TRAIT_IMPL) && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()));
if (isStatic) flags |= ACC_STATIC;
boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()));
if (isAbstract) flags |= ACC_ABSTRACT; if (isAbstract) flags |= ACC_ABSTRACT;
final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null); final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
if(kind != OwnerKind.TRAIT_IMPL && v.generateCode()) { if(v.generateCode()) {
int start = functionDescriptor.getReceiverParameter().exists() ? 1 : 0; int start = 0;
if(kind != OwnerKind.TRAIT_IMPL) {
AnnotationVisitor av = mv.visitAnnotation("Ljet/typeinfo/JetMethod;", true);
if(functionDescriptor.getReturnType().isNullable()) {
av.visit("nullableReturnType", true);
}
av.visitEnd();
}
if(kind == OwnerKind.TRAIT_IMPL) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, "Ljet/typeinfo/JetParameter;", true);
av.visit("value", "this$self");
av.visitEnd();
}
if(receiverParameter.exists()) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, "Ljet/typeinfo/JetParameter;", true);
av.visit("value", "this$receiver");
if(receiverParameter.getType().isNullable()) {
av.visit("nullable", true);
}
av.visitEnd();
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, "Ljet/typeinfo/JetTypeParameter;", true);
av.visit("value", typeParameterDescriptor.getName());
av.visitEnd();
}
for(int i = 0; i != paramDescrs.size(); ++i) { for(int i = 0; i != paramDescrs.size(); ++i) {
AnnotationVisitor annotationVisitor = mv.visitParameterAnnotation(i + start, "Ljet/typeinfo/JetParameterName;", true); AnnotationVisitor av = mv.visitParameterAnnotation(i + start, "Ljet/typeinfo/JetParameter;", true);
annotationVisitor.visit("value", paramDescrs.get(i).getName()); ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
annotationVisitor.visitEnd(); av.visit("name", parameterDescriptor.getName());
if(parameterDescriptor.hasDefaultValue()) {
av.visit("hasDefaultValue", true);
}
if(parameterDescriptor.getOutType().isNullable()) {
av.visit("nullable", true);
}
av.visitEnd();
} }
} }
if (!isAbstract && v.generateCode()) { if (!isAbstract && v.generateCode()) {
mv.visitCode(); mv.visitCode();
FrameMap frameMap = context.prepareFrame();
Label methodBegin = new Label();
mv.visitLabel(methodBegin);
FrameMap frameMap = context.prepareFrame(typeMapper);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state);
Type[] argTypes = jvmSignature.getArgumentTypes(); Type[] argTypes = jvmSignature.getArgumentTypes();
int add = functionDescriptor.getReceiverParameter().exists() ? state.getTypeMapper().mapType(functionDescriptor.getReceiverParameter().getType()).getSize() : 0; int add = 0;
if(kind == OwnerKind.TRAIT_IMPL)
add++;
if(receiverParameter.exists())
add++;
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
int slot = frameMap.enterTemp(); int slot = frameMap.enterTemp();
@@ -110,9 +160,9 @@ public class FunctionCodegen {
} }
else { else {
for (ValueParameterDescriptor parameter : paramDescrs) { for (ValueParameterDescriptor parameter : paramDescrs) {
Type sharedVarType = state.getTypeMapper().getSharedVarType(parameter); Type sharedVarType = typeMapper.getSharedVarType(parameter);
Type localVarType = state.getTypeMapper().mapType(parameter.getOutType());
if (sharedVarType != null) { if (sharedVarType != null) {
Type localVarType = typeMapper.mapType(parameter.getOutType());
int index = frameMap.getIndex(parameter); int index = frameMap.getIndex(parameter);
mv.visitTypeInsn(NEW, sharedVarType.getInternalName()); mv.visitTypeInsn(NEW, sharedVarType.getInternalName());
mv.visitInsn(DUP); mv.visitInsn(DUP);
@@ -127,6 +177,35 @@ public class FunctionCodegen {
codegen.returnExpression(bodyExpressions); codegen.returnExpression(bodyExpressions);
} }
Label methodEnd = new Label();
mv.visitLabel(methodEnd);
int k = 0;
if(expectedThisObject.exists()) {
Type type = typeMapper.mapType(expectedThisObject.getType());
// TODO: specify signature
mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++);
}
if(receiverParameter.exists()) {
Type type = typeMapper.mapType(receiverParameter.getType());
// TODO: specify signature
mv.visitLocalVariable("this$receiver", type.getDescriptor(), null, methodBegin, methodEnd, k);
k += type.getSize();
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
mv.visitLocalVariable(typeParameterDescriptor.getName(), JetTypeMapper.TYPE_TYPEINFO.getDescriptor(), null, methodBegin, methodEnd, k++);
}
for (ValueParameterDescriptor parameter : paramDescrs) {
Type type = typeMapper.mapType(parameter.getOutType());
// TODO: specify signature
mv.visitLocalVariable(parameter.getName(), type.getDescriptor(), null, methodBegin, methodEnd, k);
k += type.getSize();
}
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
@@ -148,7 +227,7 @@ public class FunctionCodegen {
} }
} }
static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration(); DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
if(kind != OwnerKind.TRAIT_IMPL) { if(kind != OwnerKind.TRAIT_IMPL) {
@@ -164,15 +243,18 @@ public class FunctionCodegen {
} }
boolean needed = false; boolean needed = false;
for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) { if(functionDescriptor != null) {
if(parameterDescriptor.hasDefaultValue()) { for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
needed = true; if(parameterDescriptor.hasDefaultValue()) {
break; needed = true;
break;
}
} }
} }
if(needed) { if(needed) {
boolean hasReceiver = functionDescriptor.getReceiverParameter().exists(); ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
boolean hasReceiver = receiverParameter.exists();
boolean isStatic = kind == OwnerKind.NAMESPACE; boolean isStatic = kind == OwnerKind.NAMESPACE;
if(kind == OwnerKind.TRAIT_IMPL) { if(kind == OwnerKind.TRAIT_IMPL) {
@@ -183,50 +265,46 @@ public class FunctionCodegen {
int flags = ACC_PUBLIC; // TODO. int flags = ACC_PUBLIC; // TODO.
String ownerInternalName = contextClass instanceof NamespaceDescriptor ? String ownerInternalName = contextClass instanceof NamespaceDescriptor ?
NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(contextClass)) : NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass)) :
state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
String descriptor = jvmSignature.getDescriptor().replace(")","I)"); String descriptor = jvmSignature.getDescriptor().replace(")","I)");
if(!isStatic) boolean isConstructor = "<init>".equals(jvmSignature.getName());
if(!isStatic && !isConstructor)
descriptor = descriptor.replace("(","(L" + ownerInternalName + ";"); descriptor = descriptor.replace("(","(L" + ownerInternalName + ";");
final MethodVisitor mv = v.newMethod(null, flags | ACC_STATIC, jvmSignature.getName() + "$default", descriptor, null, null); final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + "$default", descriptor, null, null);
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
if (v.generateCode()) { if (v.generateCode()) {
mv.visitCode(); mv.visitCode();
FrameMap frameMap = owner.prepareFrame(); FrameMap frameMap = owner.prepareFrame(state.getTypeMapper());
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state);
int var = 0; int var = 0;
if(!isStatic) { if(!isStatic) {
frameMap.enterTemp();
var++; var++;
} }
Type receiverType = receiverParameter.exists() ? state.getTypeMapper().mapType(receiverParameter.getType()) : Type.DOUBLE_TYPE;
if(hasReceiver) { if(hasReceiver) {
frameMap.enterTemp(); var += receiverType.getSize();
var++;
} }
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters(); List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
int slot = frameMap.enterTemp(); if(typeParameterDescriptor.isReified()) {
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO)); codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(var++, JetTypeMapper.TYPE_TYPEINFO));
var++; }
} }
Type[] argTypes = jvmSignature.getArgumentTypes(); Type[] argTypes = jvmSignature.getArgumentTypes();
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters(); List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
for (int i = 0; i < paramDescrs.size(); i++) { for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize(); int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize();
var += size; var += size;
frameMap.enter(parameter, size);
} }
frameMap.enterTemp();
int maskIndex = var; int maskIndex = var;
var = 0; var = 0;
@@ -235,7 +313,8 @@ public class FunctionCodegen {
} }
if(hasReceiver) { if(hasReceiver) {
mv.visitVarInsn(ALOAD, var++); // todo - Long etc. iv.load(var, receiverType);
var += receiverType.getSize();
} }
int extra = hasReceiver ? 1 : 0; int extra = hasReceiver ? 1 : 0;
@@ -15,7 +15,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetStandardLibrary;
import java.util.Collections; import java.util.Collections;
@@ -82,11 +82,12 @@ public class GenerationState {
return factory.forNamespace(namespace); return factory.forNamespace(namespace);
} }
public void compile(JetFile psiFile) { public BindingContext compile(JetFile psiFile) {
final JetNamespace namespace = psiFile.getRootNamespace(); final JetNamespace namespace = psiFile.getRootNamespace();
final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY); final BindingContext bindingContext = AnalyzerFacade.analyzeOneNamespaceWithJavaIntegration(namespace, JetControlFlowDataTraceFactory.EMPTY);
AnalyzingUtils.throwExceptionOnErrors(bindingContext); AnalyzingUtils.throwExceptionOnErrors(bindingContext);
compileCorrectNamespaces(bindingContext, Collections.singletonList(namespace)); compileCorrectNamespaces(bindingContext, Collections.singletonList(namespace));
return bindingContext;
// NamespaceCodegen codegen = forNamespace(namespace); // NamespaceCodegen codegen = forNamespace(namespace);
// bindingContexts.push(bindingContext); // bindingContexts.push(bindingContext);
// typeMapper = new JetTypeMapper(standardLibrary, bindingContext); // typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
@@ -269,7 +269,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
Method method; Method constructorMethod;
CallableMethod callableMethod; CallableMethod callableMethod;
if (constructorDescriptor == null) { if (constructorDescriptor == null) {
List<Type> parameterTypes = new ArrayList<Type>(); List<Type> parameterTypes = new ArrayList<Type>();
@@ -282,17 +282,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
} }
method = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); constructorMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList()); callableMethod = new CallableMethod("", constructorMethod, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
} }
else { else {
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind); callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
method = callableMethod.getSignature(); constructorMethod = callableMethod.getSignature();
} }
ObjectOrClosureCodegen closure = context.closure; ObjectOrClosureCodegen closure = context.closure;
if(closure != null) { if(closure != null) {
final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(method.getArgumentTypes())); final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(constructorMethod.getArgumentTypes()));
int insert = 0; int insert = 0;
if(closure.captureThis) { if(closure.captureThis) {
@@ -319,11 +319,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
} }
method = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); constructorMethod = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
} }
int flags = Opcodes.ACC_PUBLIC; // TODO int flags = Opcodes.ACC_PUBLIC; // TODO
final MethodVisitor mv = v.newMethod(myClass, flags, "<init>", method.getDescriptor(), null, null); final MethodVisitor mv = v.newMethod(myClass, flags, "<init>", constructorMethod.getDescriptor(), null, null);
if (!v.generateCode()) return; if (!v.generateCode()) return;
mv.visitCode(); mv.visitCode();
@@ -470,6 +470,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
mv.visitInsn(Opcodes.RETURN); mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod, constructorDescriptor, OwnerKind.IMPLEMENTATION );
} }
private void generateTraitMethods(ExpressionCodegen codegen) { private void generateTraitMethods(ExpressionCodegen codegen) {
@@ -8,12 +8,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor; import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method; import org.objectweb.asm.commons.Method;
@@ -95,16 +95,7 @@ public class JetTypeMapper {
} }
public static boolean isPrimitive(Type type) { public static boolean isPrimitive(Type type) {
return type == Type.INT_TYPE return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY;
|| type == Type.SHORT_TYPE
|| type == Type.BYTE_TYPE
|| type == Type.CHAR_TYPE
|| type == Type.SHORT_TYPE
|| type == Type.FLOAT_TYPE
|| type == Type.DOUBLE_TYPE
|| type == Type.LONG_TYPE
|| type == Type.BOOLEAN_TYPE
|| type == Type.VOID_TYPE;
} }
public static Type getBoxedType(final Type type) { public static Type getBoxedType(final Type type) {
@@ -139,7 +130,7 @@ public class JetTypeMapper {
String owner; String owner;
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof NamespaceDescriptor) { if (containingDeclaration instanceof NamespaceDescriptor) {
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName((NamespaceDescriptor) containingDeclaration)); owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName((NamespaceDescriptor) containingDeclaration));
} }
else if (containingDeclaration instanceof ClassDescriptor) { else if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
@@ -314,7 +305,7 @@ public class JetTypeMapper {
ClassDescriptor thisClass; ClassDescriptor thisClass;
if (functionParent instanceof NamespaceDescriptor) { if (functionParent instanceof NamespaceDescriptor) {
assert !superCall; assert !superCall;
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent)); owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(functionParent));
invokeOpcode = INVOKESTATIC; invokeOpcode = INVOKESTATIC;
thisClass = null; thisClass = null;
} }
@@ -329,7 +320,8 @@ public class JetTypeMapper {
ClassDescriptor containingClass = (ClassDescriptor) functionParent; ClassDescriptor containingClass = (ClassDescriptor) functionParent;
boolean isInterface = CodegenUtil.isInterface(containingClass); boolean isInterface = CodegenUtil.isInterface(containingClass);
OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION; OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION;
owner = mapType(containingClass.getDefaultType(), kind1).getInternalName(); Type type = mapType(containingClass.getDefaultType(), kind1);
owner = type.getInternalName();
invokeOpcode = isInterface invokeOpcode = isInterface
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL); : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
@@ -356,9 +348,6 @@ public class JetTypeMapper {
final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType(); final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType();
final List<ValueParameterDescriptor> parameters = f.getValueParameters(); final List<ValueParameterDescriptor> parameters = f.getValueParameters();
List<Type> parameterTypes = new ArrayList<Type>(); List<Type> parameterTypes = new ArrayList<Type>();
if (receiverType != null) {
parameterTypes.add(mapType(receiverType));
}
if(kind == OwnerKind.TRAIT_IMPL) { if(kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext); JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext);
@@ -370,6 +359,9 @@ public class JetTypeMapper {
valueParameterTypes.add(type); valueParameterTypes.add(type);
parameterTypes.add(type); parameterTypes.add(type);
} }
if (receiverType != null) {
parameterTypes.add(mapType(receiverType));
}
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) { for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
if(parameterDescriptor.isReified()) { if(parameterDescriptor.isReified()) {
parameterTypes.add(TYPE_TYPEINFO); parameterTypes.add(TYPE_TYPEINFO);
@@ -10,6 +10,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.lang.types.Variance;
import org.objectweb.asm.Type;
import java.util.List; import java.util.List;
@@ -17,6 +18,9 @@ import java.util.List;
* @author alex.tkachman * @author alex.tkachman
*/ */
public class SignatureUtil { public class SignatureUtil {
private SignatureUtil() {
}
public static String classToSignature(JetClass type, BindingContext bindingContext, JetTypeMapper typeMapper) { public static String classToSignature(JetClass type, BindingContext bindingContext, JetTypeMapper typeMapper) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
genTypeParams(type, sb); genTypeParams(type, sb);
@@ -33,7 +37,7 @@ public class SignatureUtil {
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
if(descriptor instanceof ClassDescriptor) { if(descriptor instanceof ClassDescriptor) {
JetType defaultType = ((ClassDescriptor) descriptor).getDefaultType(); JetType defaultType = ((ClassDescriptor) descriptor).getDefaultType();
org.objectweb.asm.Type type = typeMapper.mapType(defaultType, OwnerKind.IMPLEMENTATION); Type type = typeMapper.mapType(defaultType, OwnerKind.IMPLEMENTATION);
if(JetTypeMapper.isPrimitive(type)) { if(JetTypeMapper.isPrimitive(type)) {
type = JetTypeMapper.boxType(type); type = JetTypeMapper.boxType(type);
} }
@@ -5,6 +5,7 @@ import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.InstructionAdapter;
@@ -31,11 +32,11 @@ public class BinaryOp implements IntrinsicMethod {
if (receiver != null) { if (receiver != null) {
receiver.put(expectedType, v); receiver.put(expectedType, v);
} }
codegen.gen(arguments.get(0), expectedType); codegen.gen(arguments.get(0), shift() ? Type.INT_TYPE : expectedType);
} }
else { else {
codegen.gen(arguments.get(0), expectedType); codegen.gen(arguments.get(0), expectedType);
codegen.gen(arguments.get(1), expectedType); codegen.gen(arguments.get(1), shift() ? Type.INT_TYPE : expectedType);
} }
v.visitInsn(expectedType.getOpcode(opcode)); v.visitInsn(expectedType.getOpcode(opcode));
@@ -44,4 +45,8 @@ public class BinaryOp implements IntrinsicMethod {
} }
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
} }
private boolean shift() {
return opcode == Opcodes.ISHL || opcode == Opcodes.ISHR || opcode == Opcodes.IUSHR;
}
} }
@@ -0,0 +1,45 @@
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.JetExpression;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author alex.tkachman
*/
public class CompareTo implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver) {
assert arguments != null;
receiver.put(receiver.type, v);
codegen.gen(arguments.get(0), receiver.type);
if(receiver.type == Type.BYTE_TYPE || receiver.type == Type.SHORT_TYPE || receiver.type == Type.CHAR_TYPE)
v.sub(Type.INT_TYPE);
else if(receiver.type == Type.INT_TYPE) {
v.invokestatic("jet/runtime/Intrinsics", "compare", "(II)I");
}
else if(receiver.type == Type.BOOLEAN_TYPE) {
v.invokestatic("jet/runtime/Intrinsics", "compare", "(ZZ)I");
}
else if(receiver.type == Type.LONG_TYPE) {
v.invokestatic("jet/runtime/Intrinsics", "compare", "(JJ)I");
}
else if(receiver.type == Type.FLOAT_TYPE) {
v.invokestatic("java/lang/Float", "compare", "(FF)I");
}
else if(receiver.type == Type.DOUBLE_TYPE) {
v.invokestatic("java/lang/Double", "compare", "(DD)I");
}
else {
throw new UnsupportedOperationException();
}
return StackValue.onStack(Type.INT_TYPE);
}
}
@@ -24,20 +24,38 @@ public class Increment implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
JetExpression operand = arguments.get(0); boolean nullable = expectedType.getSort() == Type.OBJECT;
while(operand instanceof JetParenthesizedExpression) { if(nullable) {
operand = ((JetParenthesizedExpression)operand).getExpression(); expectedType = JetTypeMapper.unboxType(expectedType);
} }
if (operand instanceof JetReferenceExpression) { if(arguments.size() > 0) {
final int index = codegen.indexOfLocal((JetReferenceExpression) operand); JetExpression operand = arguments.get(0);
if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) { while(operand instanceof JetParenthesizedExpression) {
return StackValue.preIncrement(index, myDelta); operand = ((JetParenthesizedExpression)operand).getExpression();
} }
if (operand instanceof JetReferenceExpression) {
final int index = codegen.indexOfLocal((JetReferenceExpression) operand);
if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) {
return StackValue.preIncrement(index, myDelta);
}
}
StackValue value = codegen.genQualified(receiver, operand);
value. dupReceiver(v);
value. dupReceiver(v);
value.put(expectedType, v);
plusMinus(v, expectedType);
value.store(v);
value.put(expectedType, v);
} }
StackValue value = codegen.genQualified(receiver, operand); else {
value. dupReceiver(v); receiver.put(expectedType, v);
value. dupReceiver(v); plusMinus(v, expectedType);
value.put(expectedType, v); }
return StackValue.onStack(expectedType);
}
private void plusMinus(InstructionAdapter v, Type expectedType) {
if (expectedType == Type.LONG_TYPE) { if (expectedType == Type.LONG_TYPE) {
v.lconst(myDelta); v.lconst(myDelta);
} }
@@ -51,8 +69,5 @@ public class Increment implements IntrinsicMethod {
v.iconst(myDelta); v.iconst(myDelta);
} }
v.add(expectedType); v.add(expectedType);
value.store(v);
value.put(expectedType, v);
return StackValue.onStack(expectedType);
} }
} }
@@ -23,6 +23,7 @@ import java.util.*;
*/ */
public class IntrinsicMethods { public class IntrinsicMethods {
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus(); private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
private static final IntrinsicMethod NUMBER_CAST = new NumberCast(); private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
private static final IntrinsicMethod INV = new Inv(); private static final IntrinsicMethod INV = new Inv();
private static final IntrinsicMethod TYPEINFO = new TypeInfo(); private static final IntrinsicMethod TYPEINFO = new TypeInfo();
@@ -53,6 +54,7 @@ public class IntrinsicMethods {
} }
for (String type : PRIMITIVE_NUMBER_TYPES) { for (String type : PRIMITIVE_NUMBER_TYPES) {
declareIntrinsicFunction(type, "plus", 0, UNARY_PLUS);
declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS); declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS);
declareIntrinsicFunction(type, "inv", 0, INV); declareIntrinsicFunction(type, "inv", 0, INV);
declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO); declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO);
@@ -97,6 +99,9 @@ public class IntrinsicMethods {
declareIntrinsicFunction("FloatIterator", "next", 0, ITERATOR_NEXT); declareIntrinsicFunction("FloatIterator", "next", 0, ITERATOR_NEXT);
declareIntrinsicFunction("DoubleIterator", "next", 0, ITERATOR_NEXT); declareIntrinsicFunction("DoubleIterator", "next", 0, ITERATOR_NEXT);
for (String type : PRIMITIVE_NUMBER_TYPES) {
declareIntrinsicFunction(type, "compareTo", 1, new CompareTo());
}
// declareIntrinsicFunction("Any", "equals", 1, new Equals()); // declareIntrinsicFunction("Any", "equals", 1, new Equals());
// //
declareIntrinsicStringMethods(); declareIntrinsicStringMethods();
@@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
@@ -11,12 +12,22 @@ import java.util.List;
/** /**
* @author yole * @author yole
* @author alex.tkachman
*/ */
public class Inv implements IntrinsicMethod { public class Inv implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
boolean nullable = expectedType.getSort() == Type.OBJECT;
if(nullable) {
expectedType = JetTypeMapper.unboxType(expectedType);
}
receiver.put(expectedType, v); receiver.put(expectedType, v);
v.iconst(-1); if(expectedType == Type.LONG_TYPE) {
v.lconst(-1L);
}
else {
v.iconst(-1);
}
v.xor(expectedType); v.xor(expectedType);
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
} }
@@ -18,16 +18,24 @@ import java.util.List;
public class RangeTo implements IntrinsicMethod { public class RangeTo implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
JetBinaryExpression expression = (JetBinaryExpression) element; if(arguments.size()==1) {
final Type leftType = codegen.expressionType(expression.getLeft()); receiver.put(Type.INT_TYPE, v);
if (JetTypeMapper.isIntPrimitive(leftType)) { codegen.gen(arguments.get(0), Type.INT_TYPE);
codegen.gen(expression.getLeft(), Type.INT_TYPE);
codegen.gen(expression.getRight(), Type.INT_TYPE);
v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;"); v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;");
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE); return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
} }
else { else {
throw new UnsupportedOperationException("ranges are only supported for int objects"); JetBinaryExpression expression = (JetBinaryExpression) element;
final Type leftType = codegen.expressionType(expression.getLeft());
if (JetTypeMapper.isIntPrimitive(leftType)) {
codegen.gen(expression.getLeft(), Type.INT_TYPE);
codegen.gen(expression.getRight(), Type.INT_TYPE);
v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;");
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
}
else {
throw new UnsupportedOperationException("ranges are only supported for int objects");
}
} }
} }
} }
@@ -4,7 +4,12 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.InstructionAdapter;
@@ -16,9 +21,21 @@ import java.util.List;
public class Sure implements IntrinsicMethod { public class Sure implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); JetCallExpression call = (JetCallExpression) element;
v.invokestatic("jet/runtime/Intrinsics", "sure", "(Ljava/lang/Object;)Ljava/lang/Object;"); ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v); assert resolvedCall != null;
if(resolvedCall.getReceiverArgument().getType().isNullable()) {
receiver.put(receiver.type, v);
v.dup();
Label ok = new Label();
v.ifnonnull(ok);
v.invokestatic("jet/runtime/Intrinsics", "throwNpe", "()V");
v.mark(ok);
StackValue.onStack(receiver.type).put(expectedType, v);
}
else {
codegen.generateFromResolvedCall(resolvedCall.getReceiverArgument(), expectedType);
}
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
} }
} }
@@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
@@ -15,6 +16,10 @@ import java.util.List;
public class UnaryMinus implements IntrinsicMethod { public class UnaryMinus implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
boolean nullable = expectedType.getSort() == Type.OBJECT;
if(nullable) {
expectedType = JetTypeMapper.unboxType(expectedType);
}
if (arguments.size() == 1) { if (arguments.size() == 1) {
codegen.gen(arguments.get(0), expectedType); codegen.gen(arguments.get(0), expectedType);
} }
@@ -0,0 +1,27 @@
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.JetExpression;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author alex.tkachman
*/
public class UnaryPlus implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver) {
boolean nullable = expectedType.getSort() == Type.OBJECT;
if(nullable) {
expectedType = JetTypeMapper.unboxType(expectedType);
}
receiver.put(expectedType, v);
return StackValue.onStack(expectedType);
}
}
@@ -356,7 +356,7 @@ public class CompileEnvironment {
} }
} }
private static void writeToOutputDirectory(ClassFileFactory factory, final String outputDir) { public static void writeToOutputDirectory(ClassFileFactory factory, final String outputDir) {
List<String> files = factory.files(); List<String> files = factory.files();
for (String file : files) { for (String file : files) {
if(!skipFile(file)) { if(!skipFile(file)) {
@@ -11,9 +11,8 @@ import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespace; import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetFileType;
import java.io.File; import java.io.File;
@@ -93,10 +92,10 @@ public class CompileSession {
} }
return false; return false;
} }
final AnalyzingUtils instance = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS);
List<JetNamespace> allNamespaces = new ArrayList<JetNamespace>(mySourceFileNamespaces); List<JetNamespace> allNamespaces = new ArrayList<JetNamespace>(mySourceFileNamespaces);
allNamespaces.addAll(myLibrarySourceFileNamespaces); allNamespaces.addAll(myLibrarySourceFileNamespaces);
myBindingContext = instance.analyzeNamespaces(myEnvironment.getProject(), allNamespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); myBindingContext = AnalyzerFacade.analyzeNamespacesWithJavaIntegration(
myEnvironment.getProject(), allNamespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
ErrorCollector errorCollector = new ErrorCollector(myBindingContext); ErrorCollector errorCollector = new ErrorCollector(myBindingContext);
errorCollector.report(out); errorCollector.report(out);
return !errorCollector.hasErrors; return !errorCollector.hasErrors;
@@ -1,7 +1,9 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValue;
@@ -20,8 +22,10 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
/** /**
* @author abreslav * @author abreslav
@@ -35,21 +39,10 @@ public class AnalyzerFacade {
} }
}; };
private static final AnalyzingUtils ANALYZING_UTILS = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS);
private final static Key<CachedValue<BindingContext>> BINDING_CONTEXT = Key.create("BINDING_CONTEXT"); private final static Key<CachedValue<BindingContext>> BINDING_CONTEXT = Key.create("BINDING_CONTEXT");
private static final Object lock = new Object(); private static final Object lock = new Object();
public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
return ANALYZING_UTILS.analyzeNamespace(namespace, flowDataTraceFactory);
}
public static BindingContext analyzeFileWithCache(@NotNull final JetFile file, @NotNull final Function<JetFile, Collection<JetDeclaration>> declarationProvider) { public static BindingContext analyzeFileWithCache(@NotNull final JetFile file, @NotNull final Function<JetFile, Collection<JetDeclaration>> declarationProvider) {
return analyzeFileWithCache(ANALYZING_UTILS, file, declarationProvider);
}
public static BindingContext analyzeFileWithCache(@NotNull final AnalyzingUtils analyzingUtils,
@NotNull final JetFile file,
@NotNull final Function<JetFile, Collection<JetDeclaration>> declarationProvider) {
// TODO : Synchronization? // TODO : Synchronization?
CachedValue<BindingContext> bindingContextCachedValue = file.getUserData(BINDING_CONTEXT); CachedValue<BindingContext> bindingContextCachedValue = file.getUserData(BINDING_CONTEXT);
if (bindingContextCachedValue == null) { if (bindingContextCachedValue == null) {
@@ -58,11 +51,7 @@ public class AnalyzerFacade {
public Result<BindingContext> compute() { public Result<BindingContext> compute() {
synchronized (lock) { synchronized (lock) {
try { try {
BindingContext bindingContext = analyzingUtils.analyzeNamespaces( BindingContext bindingContext = analyzeNamespacesWithJavaIntegration(file.getProject(), declarationProvider.fun(file), Predicates.<PsiFile>equalTo(file), JetControlFlowDataTraceFactory.EMPTY);
file.getProject(),
declarationProvider.fun(file),
Predicates.<PsiFile>equalTo(file),
JetControlFlowDataTraceFactory.EMPTY);
return new Result<BindingContext>(bindingContext, PsiModificationTracker.MODIFICATION_COUNT); return new Result<BindingContext>(bindingContext, PsiModificationTracker.MODIFICATION_COUNT);
} }
catch (ProcessCanceledException e) { catch (ProcessCanceledException e) {
@@ -84,4 +73,39 @@ public class AnalyzerFacade {
} }
return bindingContextCachedValue.getValue(); return bindingContextCachedValue.getValue();
} }
public static BindingContext analyzeOneNamespaceWithJavaIntegration(JetNamespace namespace, JetControlFlowDataTraceFactory flowDataTraceFactory) {
return analyzeNamespacesWithJavaIntegration(namespace.getProject(), Collections.singleton(namespace), Predicates.<PsiFile>alwaysTrue(), flowDataTraceFactory);
}
public static BindingContext analyzeNamespacesWithJavaIntegration(Project project, Collection<? extends JetDeclaration> declarations, Predicate<PsiFile> filesToAnalyzeCompletely, JetControlFlowDataTraceFactory flowDataTraceFactory) {
BindingTraceContext bindingTraceContext = new BindingTraceContext();
return AnalyzingUtils.getInstance().analyzeNamespacesWithGivenTrace(
project,
JavaBridgeConfiguration.createJavaBridgeConfiguration(project, bindingTraceContext),
declarations,
filesToAnalyzeCompletely,
flowDataTraceFactory, bindingTraceContext);
}
public static BindingContext shallowAnalyzeFiles(Collection<PsiFile> files) {
assert files.size() > 0;
Project project = files.iterator().next().getProject();
Collection<JetNamespace> namespaces = collectRootNamespaces(files);
return analyzeNamespacesWithJavaIntegration(project, namespaces, Predicates.<PsiFile>alwaysFalse(), JetControlFlowDataTraceFactory.EMPTY);
}
public static List<JetNamespace> collectRootNamespaces(Collection<PsiFile> files) {
List<JetNamespace> namespaces = new ArrayList<JetNamespace>();
for (PsiFile file : files) {
if (file instanceof JetFile) {
namespaces.add(((JetFile) file).getRootNamespace());
}
}
return namespaces;
}
} }
@@ -0,0 +1,37 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.Configuration;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
/**
* @author abreslav
*/
public class JavaBridgeConfiguration implements Configuration {
public static Configuration createJavaBridgeConfiguration(@NotNull Project project, @NotNull BindingTrace trace) {
return new JavaBridgeConfiguration(project, trace);
}
private final JavaSemanticServices javaSemanticServices;
private JavaBridgeConfiguration(Project project, BindingTrace trace) {
this.javaSemanticServices = new JavaSemanticServices(project, JetSemanticServices.createSemanticServices(project), trace);
}
@Override
public void addDefaultImports(BindingTrace trace, WritableScope rootScope) {
rootScope.importScope(new JavaPackageScope("", null, javaSemanticServices));
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
}
@Override
public void extendNamespaceScope(BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) {
namespaceMemberScope.importScope(new JavaPackageScope(DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor, javaSemanticServices));
}
}
@@ -1,24 +0,0 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.ImportingStrategy;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
/**
* @author abreslav
*/
public class JavaDefaultImports {
public static final ImportingStrategy JAVA_DEFAULT_IMPORTS = new ImportingStrategy() {
@Override
public void addImports(Project project, JetSemanticServices semanticServices, BindingTrace trace, WritableScope rootScope) {
JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, trace);
rootScope.importScope(new JavaPackageScope("", null, javaSemanticServices));
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
}
};
private JavaDefaultImports() {
}
}
@@ -13,7 +13,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetFileType;
@@ -53,7 +52,7 @@ public class JavaDescriptorResolver {
} }
}; };
protected final Map<String, ClassDescriptor> classDescriptorCache = new HashMap<String, ClassDescriptor>(); protected final Map<String, ClassDescriptor> classDescriptorCache = Maps.newHashMap();
protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap(); protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap(); protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap(); protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
@@ -122,7 +121,7 @@ public class JavaDescriptorResolver {
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(), psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
!psiClass.hasModifierProperty(PsiModifier.FINAL)) !psiClass.hasModifierProperty(PsiModifier.FINAL))
); );
classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), psiClass)); classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass));
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor); classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false)); classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
@@ -163,7 +162,7 @@ public class JavaDescriptorResolver {
Collections.<AnnotationDescriptor>emptyList(), // TODO Collections.<AnnotationDescriptor>emptyList(), // TODO
false); false);
constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), Modality.FINAL, constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), Modality.FINAL,
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), constructor)); resolveVisibilityFromPsiModifiers(constructor));
constructorDescriptor.setReturnType(classDescriptor.getDefaultType()); constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor); classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, constructor, constructorDescriptor); semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, constructor, constructorDescriptor);
@@ -326,32 +325,65 @@ public class JavaDescriptorResolver {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(); List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
PsiParameter parameter = parameters[i]; PsiParameter parameter = parameters[i];
String name = parameter.getName(); ValueParameterDescriptor valueParameterDescriptor = resolveParameterDescriptor(containingDeclaration, i, parameter);
PsiType psiType = parameter.getType(); result.add(valueParameterDescriptor);
JetType varargElementType;
if (psiType instanceof PsiEllipsisType) {
PsiEllipsisType psiEllipsisType = (PsiEllipsisType) psiType;
varargElementType = semanticServices.getTypeTransformer().transformToType(psiEllipsisType.getComponentType());
}
else {
varargElementType = null;
}
JetType outType = semanticServices.getTypeTransformer().transformToType(psiType);
result.add(new ValueParameterDescriptorImpl(
containingDeclaration,
i,
Collections.<AnnotationDescriptor>emptyList(), // TODO
name == null ? "p" + i : name,
null, // TODO : review
outType,
false,
varargElementType
));
} }
return result; return result;
} }
private ValueParameterDescriptor resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) {
PsiType psiType = parameter.getType();
JetType varargElementType;
if (psiType instanceof PsiEllipsisType) {
PsiEllipsisType psiEllipsisType = (PsiEllipsisType) psiType;
varargElementType = semanticServices.getTypeTransformer().transformToType(psiEllipsisType.getComponentType());
}
else {
varargElementType = null;
}
boolean changeNullable = false;
boolean nullable = true;
// 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("jet.typeinfo.JetParameter")) {
PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue("name");
if (nameExpression != null) {
name = (String) nameExpression.getValue();
}
PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue("nullable");
if (nullableExpression != null) {
nullable = (Boolean) nullableExpression.getValue();
} else {
// default value of parameter
nullable = false;
changeNullable = true;
}
}
}
JetType 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
);
}
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) { public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field); VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
if (variableDescriptor != null) { if (variableDescriptor != null) {
@@ -363,7 +395,7 @@ public class JavaDescriptorResolver {
containingDeclaration, containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(), Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL, Modality.FINAL,
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), field), resolveVisibilityFromPsiModifiers(field),
!isFinal, !isFinal,
null, null,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
@@ -449,7 +481,7 @@ public class JavaDescriptorResolver {
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters), semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
semanticServices.getTypeTransformer().transformToType(returnType), semanticServices.getTypeTransformer().transformToType(returnType),
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)), Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), method) resolveVisibilityFromPsiModifiers(method)
); );
semanticServices.getTrace().record(BindingContext.FUNCTION, method, functionDescriptorImpl); semanticServices.getTrace().record(BindingContext.FUNCTION, method, functionDescriptorImpl);
FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl; FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
@@ -459,7 +491,7 @@ public class JavaDescriptorResolver {
return substitutedFunctionDescriptor; return substitutedFunctionDescriptor;
} }
private static Visibility resolveVisibilityFromPsiModifiers(BindingTrace trace, PsiModifierListOwner modifierListOwner) { private static Visibility resolveVisibilityFromPsiModifiers(PsiModifierListOwner modifierListOwner) {
//TODO report error //TODO report error
return modifierListOwner.hasModifierProperty(PsiModifier.PUBLIC) ? Visibility.PUBLIC : return modifierListOwner.hasModifierProperty(PsiModifier.PUBLIC) ? Visibility.PUBLIC :
(modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE) ? Visibility.PRIVATE : (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE) ? Visibility.PRIVATE :
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl;
@@ -34,7 +35,17 @@ public class JavaPackageScope extends JetScopeImpl {
@NotNull @NotNull
@Override @Override
public Set<FunctionDescriptor> getFunctions(@NotNull String name) { public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
return Collections.emptySet(); // TODO: what is GlobalSearchScope
PsiClass psiClass = semanticServices.getDescriptorResolver().javaFacade.findClass(packagePrefix + "namespace");
if (psiClass == null) {
return Collections.emptySet();
}
if (containingDescriptor == null) {
return Collections.emptySet();
}
return semanticServices.getDescriptorResolver().resolveFunctionGroup(containingDescriptor, psiClass, null, name, true);
} }
@NotNull @NotNull
@@ -1,6 +1,7 @@
package org.jetbrains.jet; package org.jetbrains.jet;
import com.intellij.core.JavaCoreEnvironment; import com.intellij.core.JavaCoreEnvironment;
import com.intellij.lang.java.JavaParserDefinition;
import com.intellij.openapi.Disposable; import com.intellij.openapi.Disposable;
import org.jetbrains.jet.lang.parsing.JetParserDefinition; import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetFileType;
@@ -15,6 +16,7 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
registerFileType(JetFileType.INSTANCE, "kts"); registerFileType(JetFileType.INSTANCE, "kts");
registerFileType(JetFileType.INSTANCE, "ktm"); registerFileType(JetFileType.INSTANCE, "ktm");
registerFileType(JetFileType.INSTANCE, "jet"); registerFileType(JetFileType.INSTANCE, "jet");
registerParserDefinition(new JavaParserDefinition());
registerParserDefinition(new JetParserDefinition()); registerParserDefinition(new JetParserDefinition());
} }
} }
@@ -0,0 +1,29 @@
package org.jetbrains.jet.lang;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
/**
* @author abreslav
*/
public interface Configuration {
Configuration EMPTY = new Configuration() {
@Override
public void addDefaultImports(BindingTrace trace, WritableScope rootScope) {
}
@Override
public void extendNamespaceScope(BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) {
}
};
void addDefaultImports(BindingTrace trace, WritableScope rootScope);
/**
*
* This method is called every time a namespace descriptor is created. Use it to add extra descriptors to the namespace, e.g. merge a Java package with a Kotlin one
*/
void extendNamespaceScope(BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope);
}
@@ -14,7 +14,6 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -284,7 +283,7 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitUnaryExpression(JetUnaryExpression expression) { public void visitUnaryExpression(JetUnaryExpression expression) {
JetSimpleNameExpression operationSign = expression.getOperationSign(); JetSimpleNameExpression operationSign = expression.getOperationReference();
IElementType operationType = operationSign.getReferencedNameElementType(); IElementType operationType = operationSign.getReferencedNameElementType();
JetExpression baseExpression = expression.getBaseExpression(); JetExpression baseExpression = expression.getBaseExpression();
if (baseExpression == null) return; if (baseExpression == null) return;
@@ -288,7 +288,7 @@ public class JetFlowInformationProvider {
operationReference = ((JetBinaryExpression) parent).getOperationReference(); operationReference = ((JetBinaryExpression) parent).getOperationReference();
} }
else if (parent instanceof JetUnaryExpression) { else if (parent instanceof JetUnaryExpression) {
operationReference = ((JetUnaryExpression) parent).getOperationSign(); operationReference = ((JetUnaryExpression) parent).getOperationReference();
} }
if (operationReference != null) { if (operationReference != null) {
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, operationReference); DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, operationReference);
@@ -48,6 +48,16 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) { public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) {
super(containingDeclaration); super(containingDeclaration);
if (containingDeclaration instanceof ClassDescriptor
|| containingDeclaration instanceof NamespaceLike
|| containingDeclaration instanceof ModuleDescriptor
|| containingDeclaration instanceof FunctionDescriptor)
{
} else {
throw new IllegalStateException();
}
TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace); TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace);
this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup").changeLockLevel(WritableScope.LockLevel.BOTH);
this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler).setDebugName("SupertypeResolution").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler).setDebugName("SupertypeResolution").changeLockLevel(WritableScope.LockLevel.BOTH);
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.inference.SolutionStatus; import org.jetbrains.jet.lang.resolve.calls.inference.SolutionStatus;
import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.resolve.DescriptorRenderer;
@@ -10,7 +10,7 @@ import org.jetbrains.jet.JetNodeTypes;
/** /**
* @author max * @author max
*/ */
public class JetBinaryExpression extends JetExpression { public class JetBinaryExpression extends JetExpression implements JetOperationExpression {
public JetBinaryExpression(@NotNull ASTNode node) { public JetBinaryExpression(@NotNull ASTNode node) {
super(node); super(node);
} }
@@ -46,6 +46,7 @@ public class JetBinaryExpression extends JetExpression {
return null; return null;
} }
@Override
@NotNull @NotNull
public JetSimpleNameExpression getOperationReference() { public JetSimpleNameExpression getOperationReference() {
return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE);
@@ -65,7 +65,7 @@ public class JetCallExpression extends JetExpression implements JetCallElement {
} }
else if (psi instanceof JetPrefixExpression) { else if (psi instanceof JetPrefixExpression) {
JetPrefixExpression prefixExpression = (JetPrefixExpression) psi; JetPrefixExpression prefixExpression = (JetPrefixExpression) psi;
if (JetTokens.LABELS.contains(prefixExpression.getOperationSign().getReferencedNameElementType())) { if (JetTokens.LABELS.contains(prefixExpression.getOperationReference().getReferencedNameElementType())) {
JetExpression labeledExpression = prefixExpression.getBaseExpression(); JetExpression labeledExpression = prefixExpression.getBaseExpression();
if (labeledExpression instanceof JetFunctionLiteralExpression) { if (labeledExpression instanceof JetFunctionLiteralExpression) {
result.add(labeledExpression); result.add(labeledExpression);
@@ -0,0 +1,11 @@
package org.jetbrains.jet.lang.psi;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public interface JetOperationExpression {
@NotNull
JetSimpleNameExpression getOperationReference();
}
@@ -25,7 +25,7 @@ public class JetPrefixExpression extends JetUnaryExpression {
@Nullable @IfNotParsed @Nullable @IfNotParsed
public JetExpression getBaseExpression() { public JetExpression getBaseExpression() {
PsiElement expression = getOperationSign().getNextSibling(); PsiElement expression = getOperationReference().getNextSibling();
while (expression != null && !(expression instanceof JetExpression)) { while (expression != null && !(expression instanceof JetExpression)) {
expression = expression.getNextSibling(); expression = expression.getNextSibling();
} }
@@ -26,7 +26,7 @@ public class JetPsiUtil {
} }
} }
else if (expression instanceof JetPrefixExpression) { else if (expression instanceof JetPrefixExpression) {
if (JetTokens.LABELS.contains(((JetPrefixExpression) expression).getOperationSign().getReferencedNameElementType())) { if (JetTokens.LABELS.contains(((JetPrefixExpression) expression).getOperationReference().getReferencedNameElementType())) {
JetExpression baseExpression = ((JetPrefixExpression) expression).getBaseExpression(); JetExpression baseExpression = ((JetPrefixExpression) expression).getBaseExpression();
if (baseExpression != null) { if (baseExpression != null) {
expression = baseExpression; expression = baseExpression;
@@ -10,6 +10,9 @@ import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
* Type reference element.
* Underlying token is {@link org.jetbrains.jet.JetNodeTypes#TYPE_REFERENCE}
*
* @author max * @author max
*/ */
public class JetTypeReference extends JetElement { public class JetTypeReference extends JetElement {
@@ -8,7 +8,7 @@ import org.jetbrains.jet.JetNodeTypes;
/** /**
* @author abreslav * @author abreslav
*/ */
public abstract class JetUnaryExpression extends JetExpression { public abstract class JetUnaryExpression extends JetExpression implements JetOperationExpression {
public JetUnaryExpression(ASTNode node) { public JetUnaryExpression(ASTNode node) {
super(node); super(node);
} }
@@ -16,8 +16,9 @@ public abstract class JetUnaryExpression extends JetExpression {
@Nullable @IfNotParsed @Nullable @IfNotParsed
public abstract JetExpression getBaseExpression(); public abstract JetExpression getBaseExpression();
@Override
@NotNull @NotNull
public JetSimpleNameExpression getOperationSign() { public JetSimpleNameExpression getOperationReference() {
return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE);
} }
} }
@@ -1,7 +1,6 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.TextRange;
@@ -10,6 +9,7 @@ import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.Configuration;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
@@ -17,20 +17,24 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/** /**
* @author abreslav * @author abreslav
*/ */
public class AnalyzingUtils { public class AnalyzingUtils {
public static AnalyzingUtils getInstance(@NotNull ImportingStrategy importingStrategy) {
return new AnalyzingUtils(importingStrategy); private static final AnalyzingUtils INSTANCE = new AnalyzingUtils();
public static AnalyzingUtils getInstance() {
return INSTANCE;
} }
public static void checkForSyntacticErrors(@NotNull PsiElement root) { public static void checkForSyntacticErrors(@NotNull PsiElement root) {
@@ -69,32 +73,26 @@ public class AnalyzingUtils {
} }
} }
private final ImportingStrategy importingStrategy; // --------------------------------------------------------------------------------------------------------------------------
private AnalyzingUtils(ImportingStrategy importingStrategy) {
this.importingStrategy = importingStrategy;
}
public BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
Project project = namespace.getProject();
List<JetDeclaration> declarations = Collections.<JetDeclaration>singletonList(namespace);
return analyzeNamespaces(project, declarations, Predicates.equalTo(namespace.getContainingFile()), flowDataTraceFactory);
}
public BindingContext analyzeNamespaces( public BindingContext analyzeNamespaces(
@NotNull Project project, @NotNull Project project,
@NotNull Configuration configuration,
@NotNull Collection<? extends JetDeclaration> declarations, @NotNull Collection<? extends JetDeclaration> declarations,
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely, @NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
BindingTraceContext bindingTraceContext = new BindingTraceContext(); BindingTraceContext bindingTraceContext = new BindingTraceContext();
return analyzeNamespacesWithGivenTrace(project, configuration, declarations, filesToAnalyzeCompletely, flowDataTraceFactory, bindingTraceContext);
}
public BindingContext analyzeNamespacesWithGivenTrace(Project project, Configuration configuration, Collection<? extends JetDeclaration> declarations, Predicate<PsiFile> filesToAnalyzeCompletely, JetControlFlowDataTraceFactory flowDataTraceFactory, BindingTraceContext bindingTraceContext) {
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project); JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project);
JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope(); JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
ModuleDescriptor owner = new ModuleDescriptor("<module>"); ModuleDescriptor owner = new ModuleDescriptor("<module>");
final WritableScope scope = new WritableScopeImpl(JetScope.EMPTY, owner, new TraceBasedRedeclarationHandler(bindingTraceContext)).setDebugName("Root scope in analyzeNamespace"); final WritableScope scope = new WritableScopeImpl(JetScope.EMPTY, owner, new TraceBasedRedeclarationHandler(bindingTraceContext)).setDebugName("Root scope in analyzeNamespace");
importingStrategy.addImports(project, semanticServices, bindingTraceContext, scope); // configuration.addImports(project, semanticServices, bindingTraceContext, scope);
scope.importScope(libraryScope); scope.importScope(libraryScope);
scope.changeLockLevel(WritableScope.LockLevel.BOTH); scope.changeLockLevel(WritableScope.LockLevel.BOTH);
@@ -132,29 +130,8 @@ public class AnalyzingUtils {
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
throw new IllegalStateException("Must be guaranteed not to happen by the parser"); throw new IllegalStateException("Must be guaranteed not to happen by the parser");
} }
}, declarations, filesToAnalyzeCompletely, flowDataTraceFactory); }, declarations, filesToAnalyzeCompletely, flowDataTraceFactory, configuration);
return bindingTraceContext.getBindingContext(); return bindingTraceContext.getBindingContext();
} }
public BindingContext shallowAnalyzeFiles(Collection<PsiFile> files) {
assert files.size() > 0;
Project project = files.iterator().next().getProject();
Collection<JetNamespace> namespaces = collectRootNamespaces(files);
return analyzeNamespaces(project, namespaces, Predicates.<PsiFile>alwaysFalse(), JetControlFlowDataTraceFactory.EMPTY);
}
public static List<JetNamespace> collectRootNamespaces(Collection<PsiFile> files) {
List<JetNamespace> namespaces = new ArrayList<JetNamespace>();
for (PsiFile file : files) {
if (file instanceof JetFile) {
namespaces.add(((JetFile) file).getRootNamespace());
}
}
return namespaces;
}
} }
@@ -41,11 +41,15 @@ public interface BindingContext {
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_SET = Slices.createSimpleSlice(); WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_SET = Slices.createSimpleSlice();
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice(); WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice();
/** A scope where type of expression has been resolved */
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice(); WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice();
WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice(); WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice();
WritableSlice<ValueParameterDescriptor, Boolean> AUTO_CREATED_IT = Slices.createSimpleSetSlice(); WritableSlice<ValueParameterDescriptor, Boolean> AUTO_CREATED_IT = Slices.createSimpleSetSlice();
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice(); WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice();
/** Has type of current expression has been already resolved */
WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice(); WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice();
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice(); WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice();
WritableSlice<CallableMemberDescriptor, Boolean> DELEGATED = Slices.createRemovableSetSlice(); WritableSlice<CallableMemberDescriptor, Boolean> DELEGATED = Slices.createRemovableSetSlice();
@@ -154,4 +154,14 @@ public class DescriptorUtils {
} }
return false; return false;
} }
public static String getFQName(DeclarationDescriptor descriptor) {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container != null && !(container instanceof ModuleDescriptor)) {
String baseName = getFQName(container);
if (!baseName.isEmpty()) return baseName + "." + descriptor.getName();
}
return descriptor.getName();
}
} }
@@ -1,19 +0,0 @@
package org.jetbrains.jet.lang.resolve;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
/**
* @author abreslav
*/
public interface ImportingStrategy {
ImportingStrategy NONE = new ImportingStrategy() {
@Override
public void addImports(Project project, JetSemanticServices semanticServices, BindingTrace trace, WritableScope rootScope) {
}
};
void addImports(Project project, JetSemanticServices semanticServices, BindingTrace trace, WritableScope rootScope);
}
@@ -1,18 +1,13 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED; import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED;
@@ -51,7 +46,7 @@ public class OverloadResolver {
} }
Key(NamespaceDescriptor namespaceDescriptor, String name) { Key(NamespaceDescriptor namespaceDescriptor, String name) {
this(DescriptorRenderer.getFQName(namespaceDescriptor), name); this(DescriptorUtils.getFQName(namespaceDescriptor), name);
} }
public String getNamespace() { public String getNamespace() {
@@ -6,6 +6,7 @@ import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.Configuration;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
@@ -23,15 +24,15 @@ import java.util.Set;
private final ObservableBindingTrace trace; private final ObservableBindingTrace trace;
private final JetSemanticServices semanticServices; private final JetSemanticServices semanticServices;
private final DescriptorResolver descriptorResolver; private final Configuration configuration;
private final DescriptorResolver descriptorResolver;
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap(); private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap(); private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap(); protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
protected final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap(); protected final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap(); private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
private final Map<JetNamedFunction, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap(); private final Map<JetNamedFunction, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
private final Map<JetSecondaryConstructor, ConstructorDescriptor> constructors = Maps.newLinkedHashMap(); private final Map<JetSecondaryConstructor, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap(); private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
@@ -40,14 +41,14 @@ import java.util.Set;
private final Predicate<PsiFile> analyzeCompletely; private final Predicate<PsiFile> analyzeCompletely;
private StringBuilder debugOutput; private StringBuilder debugOutput;
private boolean analyzingBootstrapLibrary = false; private boolean analyzingBootstrapLibrary = false;
public TopDownAnalysisContext(JetSemanticServices semanticServices, BindingTrace trace, Predicate<PsiFile> analyzeCompletely) { public TopDownAnalysisContext(JetSemanticServices semanticServices, BindingTrace trace, Predicate<PsiFile> analyzeCompletely, @NotNull Configuration configuration) {
this.trace = new ObservableBindingTrace(trace); this.trace = new ObservableBindingTrace(trace);
this.semanticServices = semanticServices; this.semanticServices = semanticServices;
this.descriptorResolver = semanticServices.getClassDescriptorResolver(trace); this.descriptorResolver = semanticServices.getClassDescriptorResolver(trace);
this.analyzeCompletely = analyzeCompletely; this.analyzeCompletely = analyzeCompletely;
this.configuration = configuration;
} }
public void debug(Object message) { public void debug(Object message) {
@@ -133,4 +134,8 @@ import java.util.Set;
return functions; return functions;
} }
@NotNull
public Configuration getConfiguration() {
return configuration;
}
} }
@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.Configuration;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
@@ -30,8 +31,10 @@ public class TopDownAnalyzer {
@NotNull NamespaceLike owner, @NotNull NamespaceLike owner,
@NotNull Collection<? extends JetDeclaration> declarations, @NotNull Collection<? extends JetDeclaration> declarations,
@NotNull Predicate<PsiFile> analyzeCompletely, @NotNull Predicate<PsiFile> analyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
process(semanticServices, trace, outerScope, owner, declarations, analyzeCompletely, flowDataTraceFactory, false); @NotNull Configuration configuration
) {
process(semanticServices, trace, outerScope, owner, declarations, analyzeCompletely, flowDataTraceFactory, configuration, false);
} }
private static void process( private static void process(
@@ -42,8 +45,9 @@ public class TopDownAnalyzer {
@NotNull Collection<? extends JetDeclaration> declarations, @NotNull Collection<? extends JetDeclaration> declarations,
@NotNull Predicate<PsiFile> analyzeCompletely, @NotNull Predicate<PsiFile> analyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull Configuration configuration,
boolean declaredLocally) { boolean declaredLocally) {
TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace, analyzeCompletely); TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace, analyzeCompletely, configuration);
doProcess(context, outerScope, owner, declarations, flowDataTraceFactory, declaredLocally); doProcess(context, outerScope, owner, declarations, flowDataTraceFactory, declaredLocally);
} }
@@ -89,7 +93,7 @@ public class TopDownAnalyzer {
@NotNull JetSemanticServices semanticServices, @NotNull JetSemanticServices semanticServices,
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) { @NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace, Predicates.<PsiFile>alwaysTrue()); TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace, Predicates.<PsiFile>alwaysTrue(), Configuration.EMPTY);
context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope()); context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope());
context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace); context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace);
context.getDeclaringScopes().put(namespace, outerScope); context.getDeclaringScopes().put(namespace, outerScope);
@@ -135,7 +139,7 @@ public class TopDownAnalyzer {
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
return ClassObjectStatus.NOT_ALLOWED; return ClassObjectStatus.NOT_ALLOWED;
} }
}, Collections.<JetDeclaration>singletonList(object), Predicates.equalTo(object.getContainingFile()), JetControlFlowDataTraceFactory.EMPTY, true); }, Collections.<JetDeclaration>singletonList(object), Predicates.equalTo(object.getContainingFile()), JetControlFlowDataTraceFactory.EMPTY, Configuration.EMPTY, true);
} }
} }
@@ -75,6 +75,7 @@ public class TypeHierarchyResolver {
WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace())); WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace()));
namespaceScope.changeLockLevel(WritableScope.LockLevel.BOTH); namespaceScope.changeLockLevel(WritableScope.LockLevel.BOTH);
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
context.getNamespaceScopes().put(namespace, namespaceScope); context.getNamespaceScopes().put(namespace, namespaceScope);
context.getDeclaringScopes().put(namespace, outerScope); context.getDeclaringScopes().put(namespace, outerScope);
@@ -215,6 +216,7 @@ public class TypeHierarchyResolver {
WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Namespace member scope"); WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Namespace member scope");
scope.changeLockLevel(WritableScope.LockLevel.BOTH); scope.changeLockLevel(WritableScope.LockLevel.BOTH);
namespaceDescriptor.initialize(scope); namespaceDescriptor.initialize(scope);
context.getConfiguration().extendNamespaceScope(context.getTrace(), namespaceDescriptor, scope);
owner.addNamespace(namespaceDescriptor); owner.addNamespace(namespaceDescriptor);
if (namespace != null) { if (namespace != null) {
context.getTrace().record(BindingContext.NAMESPACE, namespace, namespaceDescriptor); context.getTrace().record(BindingContext.NAMESPACE, namespace, namespaceDescriptor);
@@ -49,11 +49,14 @@ public class TypeResolver {
JetTypeElement typeElement = typeReference.getTypeElement(); JetTypeElement typeElement = typeReference.getTypeElement();
JetType type = resolveTypeElement(scope, annotations, typeElement, false); JetType type = resolveTypeElement(scope, annotations, typeElement, false);
trace.record(BindingContext.TYPE, typeReference, type); trace.record(BindingContext.TYPE, typeReference, type);
return type; return type;
} }
@NotNull @NotNull
private JetType resolveTypeElement(final JetScope scope, final List<AnnotationDescriptor> annotations, JetTypeElement typeElement, final boolean nullable) { private JetType resolveTypeElement(final JetScope scope, final List<AnnotationDescriptor> annotations,
JetTypeElement typeElement, final boolean nullable) {
final JetType[] result = new JetType[1]; final JetType[] result = new JetType[1];
if (typeElement != null) { if (typeElement != null) {
typeElement.accept(new JetVisitorVoid() { typeElement.accept(new JetVisitorVoid() {
@@ -70,6 +73,7 @@ public class TypeResolver {
resolveTypeProjections(scope, ErrorUtils.createErrorType("No type").getConstructor(), type.getTypeArguments()); resolveTypeProjections(scope, ErrorUtils.createErrorType("No type").getConstructor(), type.getTypeArguments());
return; return;
} }
if (classifierDescriptor instanceof TypeParameterDescriptor) { if (classifierDescriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor; TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
@@ -268,6 +272,8 @@ public class TypeResolver {
ClassifierDescriptor classifierDescriptor; ClassifierDescriptor classifierDescriptor;
if (userType.isAbsoluteInRootNamespace()) { if (userType.isAbsoluteInRootNamespace()) {
classifierDescriptor = JetModuleUtil.getRootNamespaceType(userType).getMemberScope().getClassifier(referencedName); classifierDescriptor = JetModuleUtil.getRootNamespaceType(userType).getMemberScope().getClassifier(referencedName);
trace.record(BindingContext.RESOLUTION_SCOPE, userType.getReferenceExpression(),
JetModuleUtil.getRootNamespaceType(userType).getMemberScope());
} }
else { else {
JetUserType qualifier = userType.getQualifier(); JetUserType qualifier = userType.getQualifier();
@@ -278,7 +284,9 @@ public class TypeResolver {
return ErrorUtils.getErrorClass(); return ErrorUtils.getErrorClass();
} }
classifierDescriptor = scope.getClassifier(referencedName); classifierDescriptor = scope.getClassifier(referencedName);
trace.record(BindingContext.RESOLUTION_SCOPE, userType.getReferenceExpression(), scope);
} }
return classifierDescriptor; return classifierDescriptor;
} }
@@ -162,7 +162,7 @@ public class CallMaker {
} }
public static Call makeCall(@NotNull ReceiverDescriptor baseAsReceiver, JetUnaryExpression expression) { public static Call makeCall(@NotNull ReceiverDescriptor baseAsReceiver, JetUnaryExpression expression) {
return makeCall(expression, baseAsReceiver, null, expression.getOperationSign(), Collections.<ValueArgument>emptyList()); return makeCall(expression, baseAsReceiver, null, expression.getOperationReference(), Collections.<ValueArgument>emptyList());
} }
public static Call makeArraySetCall(@NotNull ReceiverDescriptor arrayAsReceiver, JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide) { public static Call makeArraySetCall(@NotNull ReceiverDescriptor arrayAsReceiver, JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide) {
@@ -19,10 +19,10 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lang.types.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.types.inference.ConstraintSystemSolution; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
import org.jetbrains.jet.lang.types.inference.ConstraintSystemImpl; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
import org.jetbrains.jet.lang.types.inference.SolutionStatus; import org.jetbrains.jet.lang.resolve.calls.inference.SolutionStatus;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import java.util.*; import java.util.*;
@@ -6,7 +6,7 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.inference.SolutionStatus; import org.jetbrains.jet.lang.resolve.calls.inference.SolutionStatus;
import java.util.Collection; import java.util.Collection;
@@ -1,4 +1,4 @@
package org.jetbrains.jet.lang.types.inference; package org.jetbrains.jet.lang.resolve.calls.inference;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
@@ -1,4 +1,4 @@
package org.jetbrains.jet.lang.types.inference; package org.jetbrains.jet.lang.resolve.calls.inference;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@@ -1,4 +1,4 @@
package org.jetbrains.jet.lang.types.inference; package org.jetbrains.jet.lang.resolve.calls.inference;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -1,4 +1,4 @@
package org.jetbrains.jet.lang.types.inference; package org.jetbrains.jet.lang.resolve.calls.inference;
/** /**
* @author abreslav * @author abreslav
@@ -38,7 +38,7 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
@Override @Override
public WritableScope changeLockLevel(LockLevel lockLevel) { public WritableScope changeLockLevel(LockLevel lockLevel) {
if (lockLevel.ordinal() < this.lockLevel.ordinal()) { if (lockLevel.ordinal() < this.lockLevel.ordinal()) {
throw new IllegalStateException("cannot lower lock level from " + this.lockLevel + " to " + lockLevel); throw new IllegalStateException("cannot lower lock level from " + this.lockLevel + " to " + lockLevel + " at " + debugName);
} }
this.lockLevel = lockLevel; this.lockLevel = lockLevel;
return this; return this;
@@ -46,13 +46,13 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
protected void checkMayRead() { protected void checkMayRead() {
if (lockLevel != LockLevel.READING && lockLevel != LockLevel.BOTH) { if (lockLevel != LockLevel.READING && lockLevel != LockLevel.BOTH) {
throw new IllegalStateException("cannot read with lock level " + lockLevel); throw new IllegalStateException("cannot read with lock level " + lockLevel + " at " + debugName);
} }
} }
protected void checkMayWrite() { protected void checkMayWrite() {
if (lockLevel != LockLevel.WRITING && lockLevel != LockLevel.BOTH) { if (lockLevel != LockLevel.WRITING && lockLevel != LockLevel.BOTH) {
throw new IllegalStateException("cannot write with lock level " + lockLevel); throw new IllegalStateException("cannot write with lock level " + lockLevel + " at " + debugName);
} }
} }
@@ -613,7 +613,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context) { public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context) {
JetExpression baseExpression = expression.getBaseExpression(); JetExpression baseExpression = expression.getBaseExpression();
if (baseExpression == null) return null; if (baseExpression == null) return null;
JetSimpleNameExpression operationSign = expression.getOperationSign(); JetSimpleNameExpression operationSign = expression.getOperationReference();
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
String referencedName = operationSign.getReferencedName(); String referencedName = operationSign.getReferencedName();
referencedName = referencedName == null ? " <?>" : referencedName; referencedName = referencedName == null ? " <?>" : referencedName;
@@ -634,7 +634,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor( FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor(
CallMaker.makeCall(receiver, expression), CallMaker.makeCall(receiver, expression),
expression.getOperationSign(), expression.getOperationReference(),
name); name);
if (functionDescriptor == null) return null; if (functionDescriptor == null) return null;
@@ -109,7 +109,7 @@ public class DataFlowUtils {
@Override @Override
public void visitUnaryExpression(JetUnaryExpression expression) { public void visitUnaryExpression(JetUnaryExpression expression) {
IElementType operationTokenType = expression.getOperationSign().getReferencedNameElementType(); IElementType operationTokenType = expression.getOperationReference().getReferencedNameElementType();
if (operationTokenType == JetTokens.EXCL) { if (operationTokenType == JetTokens.EXCL) {
JetExpression baseExpression = expression.getBaseExpression(); JetExpression baseExpression = expression.getBaseExpression();
if (baseExpression != null) { if (baseExpression != null) {
@@ -18,16 +18,6 @@ import java.util.List;
*/ */
public class DescriptorRenderer implements Renderer { public class DescriptorRenderer implements Renderer {
public static String getFQName(DeclarationDescriptor descriptor) {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container != null && !(container instanceof ModuleDescriptor)) {
String baseName = getFQName(container);
if (!baseName.isEmpty()) return baseName + "." + descriptor.getName();
}
return descriptor.getName();
}
public static final DescriptorRenderer TEXT = new DescriptorRenderer(); public static final DescriptorRenderer TEXT = new DescriptorRenderer();
public static final DescriptorRenderer HTML = new DescriptorRenderer() { public static final DescriptorRenderer HTML = new DescriptorRenderer() {
@@ -0,0 +1,29 @@
fun escapeChar(c : Char) : String? = when (c) {
'\\' => "\\\\"
'\n' => "\\n"
'"' => "\\\""
else => String.valueOf(c)
}
fun String.escape(i : Int = 0, result : String = "") : String =
if (i == length) result
else escape(i + 1, result + escapeChar(get(i)))
fun box() : String {
val s = " System.out?.println(\"fun escapeChar(c : Char) : String? = when (c) {\");\n System.out?.println(\" '\\\\\\\\' => \\\"\\\\\\\\\\\\\\\\\\\"\");\n System.out?.println(\" '\\\\n' => \\\"\\\\\\\\n\\\"\");\n System.out?.println(\" '\\\"' => \\\"\\\\\\\\\\\\\\\"\\\"\");\n System.out?.println(\" else => String.valueOf(c)\");\n System.out?.println(\"}\");\n System.out?.println();\n System.out?.println(\"fun String.escape(i : Int = 0, result : String = \\\"\\\") : String =\");\n System.out?.println(\" if (i == length) result\");\n System.out?.println(\" else escape(i + 1, result + escapeChar(this.get(i)))\");\n System.out?.println();\n System.out?.println(\"fun main(args : Array<String>) {\");\n System.out?.println(\" val s = \\\"\" + s.escape() + \"\\\";\");\n System.out?.println(s);\n}\n";
System.out?.println("fun escapeChar(c : Char) : String? = when (c) {");
System.out?.println(" '\\\\' => \"\\\\\\\\\"");
System.out?.println(" '\\n' => \"\\\\n\"");
System.out?.println(" '\"' => \"\\\\\\\"\"");
System.out?.println(" else => String.valueOf(c)");
System.out?.println("}");
System.out?.println();
System.out?.println("fun String.escape(i : Int = 0, result : String = \"\") : String =");
System.out?.println(" if (i == length) result");
System.out?.println(" else escape(i + 1, result + escapeChar(this.get(i)))");
System.out?.println();
System.out?.println("fun main(args : Array<String>) {");
System.out?.println(" val s = \"" + s.escape() + "\";");
System.out?.println(s);
return "OK"
}
@@ -0,0 +1,12 @@
namespace demo_range
fun Int?.rangeTo(other : Int?) : IntRange = this.sure().rangeTo(other.sure())
fun box() : String {
val x : Int? = 10
val y : Int? = 12
for (i in x..y)
System.out?.println(i.inv())
return "OK"
}
@@ -0,0 +1,11 @@
namespace bitwise_demo
fun Long?.shl(bits : Int?) : Long = this.sure().shl(bits.sure())
fun box() : String {
val x : Long? = 10
val y : Int? = 12
System.out?.println(x.shl(y))
return "OK"
}
@@ -0,0 +1,12 @@
namespace demo_range
fun Int?.plus() : Int = this.sure().plus()
fun Int?.dec() : Int = this.sure().dec()
fun Int?.inc() : Int = this.sure().inc()
fun Int?.minus() : Int = this.sure().minus()
fun box() : String {
val x : Int? = 10
System.out?.println(x?.inv())// * x?.plus() * x?.dec() * x?.minus() as Number)
return "OK"
}
@@ -0,0 +1,9 @@
namespace demo_long
fun Long?.inv() : Long = this.sure().inv()
fun box() : String {
val x : Long? = 10
System.out?.println(x.inv())
return if(x.inv() == -11.lng) "OK" else "fail"
}
@@ -0,0 +1,9 @@
// +JDK
// KT-689 Allow to put Java and Kotlin files in the same packages
// This is a stub test. One should not extend Java packages that come from libraries.
namespace java
val c : lang.Class<*>? = null
val <T> Array<T>?.length : Int get() = if (this != null) this.size else throw NullPointerException()
@@ -0,0 +1,13 @@
// KT-716 Type inference failed
// +JDK
fun <T> typeinfo.TypeInfo<T>.getJavaClass() : java.lang.Class<T> {
val t : java.lang.Object = this <!CAST_NEVER_SUCCEEDS!>as<!> java.lang.Object
return <!UNCHECKED_CAST!>t.getClass() as java.lang.Class<T><!> // inferred type is Object but Serializable was expected
}
fun getJavaClass<T>() = typeinfo.typeinfo<T>.getJavaClass()
fun main(args : Array<String>) {
System.out?.println(getJavaClass<String>)
}
+3
View File
@@ -0,0 +1,3 @@
namespace test
class Ramification
+5
View File
@@ -0,0 +1,5 @@
namespace test
class River {
fun song() = 1
}
@@ -0,0 +1,3 @@
namespace test
fun fff(a: String) = 1
@@ -0,0 +1,3 @@
namespace test
fun fff(a: String?) = 1
+3
View File
@@ -0,0 +1,3 @@
namespace test
fun f() = 1
@@ -32,7 +32,7 @@ public abstract class JetTestCaseBuilder {
} }
public interface NamedTestFactory { public interface NamedTestFactory {
@NotNull Test createTest(@NotNull String dataPath, @NotNull String name); @NotNull Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file);
} }
@NotNull @NotNull
@@ -90,7 +90,7 @@ public abstract class JetTestCaseBuilder {
String fileName = file.getName(); String fileName = file.getName();
assert fileName != null; assert fileName != null;
String extension = fileName.endsWith(extensionJet) ? extensionJet : extensionKt; String extension = fileName.endsWith(extensionJet) ? extensionJet : extensionKt;
suite.addTest(factory.createTest(dataPath, fileName.substring(0, fileName.length() - extension.length()))); suite.addTest(factory.createTest(dataPath, fileName.substring(0, fileName.length() - extension.length()), file));
} }
} }
} }
@@ -1,11 +1,14 @@
package org.jetbrains.jet; package org.jetbrains.jet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.Severity; import org.jetbrains.jet.lang.diagnostics.Severity;
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnostic; import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnostic;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice; import org.jetbrains.jet.util.slicedmap.WritableSlice;
@@ -120,4 +123,8 @@ public class JetTestUtils {
} }
} }
}; };
public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
return AnalyzerFacade.analyzeOneNamespaceWithJavaIntegration(namespace, flowDataTraceFactory);
}
} }
@@ -0,0 +1,247 @@
package org.jetbrains.jet;
import com.intellij.lang.ASTFactory;
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;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.ClassBuilderFactory;
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.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
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.plugin.JetLanguage;
import org.junit.Assert;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Set;
/**
* @author Stepan Koltsov
*/
public class ReadClassDataTest extends UsefulTestCase {
protected final Disposable myTestRootDisposable = new Disposable() {
@Override
public void dispose() {
}
};
private JetCoreEnvironment jetCoreEnvironment;
private File tmpdir;
private final File testFile;
public ReadClassDataTest(@NotNull File testFile) {
this.testFile = testFile;
setName(testFile.getName());
}
@Override
protected void setUp() throws Exception {
super.setUp();
tmpdir = new File("tmp/" + this.getClass().getSimpleName() + "." + this.getName());
rmrf(tmpdir);
mkdirs(tmpdir);
}
@Override
public void tearDown() throws Exception {
Disposer.dispose(myTestRootDisposable);
}
private void mkdirs(File file) throws IOException {
if (file.isDirectory()) {
return;
}
if (!file.mkdirs()) {
throw new IOException();
}
}
private void rmrf(File file) {
if (file != null) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
rmrf(child);
}
}
file.delete();
}
}
private void createMockCoreEnvironment() {
jetCoreEnvironment = new JetCoreEnvironment(myTestRootDisposable);
final File rtJar = new File(JetTestCaseBuilder.getHomeDirectory(), "compiler/testData/mockJDK-1.7/jre/lib/rt.jar");
jetCoreEnvironment.addToClasspath(rtJar);
jetCoreEnvironment.addToClasspath(new File(JetTestCaseBuilder.getHomeDirectory(), "compiler/testData/mockJDK-1.7/jre/lib/annotations.jar"));
}
@Override
public void runTest() throws Exception {
if (true) return;
createMockCoreEnvironment();
LanguageASTFactory.INSTANCE.addExplicitExtension(JavaLanguage.INSTANCE, new JavaASTFactory());
String text = FileUtil.loadFile(testFile);
LightVirtualFile virtualFile = new LightVirtualFile("Hello.kt", JetLanguage.INSTANCE, text);
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES);
AnalyzingUtils.checkForSyntacticErrors(psiFile);
BindingContext bindingContext = state.compile(psiFile);
ClassFileFactory classFileFactory = state.getFactory();
CompileEnvironment.writeToOutputDirectory(classFileFactory, tmpdir.getPath());
NamespaceDescriptor namespaceFromSource = (NamespaceDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiFile.getRootNamespace());
Assert.assertEquals("test", namespaceFromSource.getName());
Disposer.dispose(myTestRootDisposable);
createMockCoreEnvironment();
jetCoreEnvironment.addToClasspath(tmpdir);
JetSemanticServices jetSemanticServices = JetSemanticServices.createSemanticServices(jetCoreEnvironment.getProject());
JavaSemanticServices semanticServices = new JavaSemanticServices(jetCoreEnvironment.getProject(), jetSemanticServices, new BindingTraceContext());
JavaDescriptorResolver javaDescriptorResolver = semanticServices.getDescriptorResolver();
NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace("test");
compareNamespaces(namespaceFromSource, namespaceFromClass);
}
private void compareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb) {
Assert.assertEquals(nsa.getName(), nsb.getName());
System.out.println("namespace " + nsa.getName());
for (DeclarationDescriptor ad : nsa.getMemberScope().getAllDescriptors()) {
if (ad instanceof ClassifierDescriptor) {
ClassifierDescriptor bd = nsb.getMemberScope().getClassifier(ad.getName());
compareClassifiers((ClassifierDescriptor) ad, bd);
} else if (ad instanceof FunctionDescriptor) {
Set<FunctionDescriptor> functions = nsb.getMemberScope().getFunctions(ad.getName());
Assert.assertTrue(functions.size() >= 1);
Assert.assertTrue("not implemented", functions.size() == 1);
FunctionDescriptor bd = functions.iterator().next();
compareFunctions((FunctionDescriptor) ad, bd);
} else {
throw new AssertionError("Unknown member: " + ad);
}
}
}
private void compareClassifiers(@NotNull ClassifierDescriptor a, @NotNull ClassifierDescriptor b) {
Assert.assertEquals(a.getName(), b.getName());
System.out.println("classifier " + a.getName());
if (a instanceof ClassDescriptor || b instanceof ClassDescriptor) {
compareClasses((ClassDescriptor) a, (ClassDescriptor) b);
}
}
private void compareClasses(@NotNull ClassDescriptor a, @NotNull ClassDescriptor b) {
System.out.println("... is class");
}
private void compareFunctions(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {
Assert.assertEquals(a.getName(), b.getName());
Assert.assertEquals(a.getValueParameters().size(), b.getValueParameters().size());
for (int i = 0; i < a.getValueParameters().size(); ++i) {
compareAnything(ValueParameterDescriptor.class, a.getValueParameters().get(i), b.getValueParameters().get(i));
}
System.out.println("function " + a.getName());
}
private <T> void compareAnything(Class<T> clazz, T a, T b) {
System.out.println("Comparing " + clazz);
Assert.assertNotNull(a);
Assert.assertNotNull(b);
for (Method method : clazz.getMethods()) {
if (!isGetter(method)) {
continue;
}
if (method.getName().equals("getContainingDeclaration")) {
continue;
}
if (clazz.equals(ValueParameterDescriptor.class)) {
if (method.getName().equals("isRef") || method.getName().equals("getOriginal")) {
continue;
}
}
System.out.println(method.getName());
Object ap = invoke(method, a);
Object bp = invoke(method, b);
Assert.assertEquals(ap, bp);
}
}
private static boolean isGetter(Method method) {
if (method.getParameterTypes().length > 0) {
return false;
}
if (method.getName().matches("is.+")) {
return method.getReturnType().equals(boolean.class);
} else if (method.getName().matches("get.+")) {
return true;
} else {
return false;
}
}
private static Object invoke(Method method, Object thiz, Object... args) {
try {
return method.invoke(thiz, args);
} catch (Exception e) {
throw new RuntimeException("failed to invoke " + method + ": " + e);
}
}
public static Test suite() {
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readClass", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new ReadClassDataTest(file);
}
});
}
}
@@ -11,10 +11,10 @@ import junit.framework.TestSuite;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.lang.cfg.LoopInfo; import org.jetbrains.jet.lang.cfg.LoopInfo;
import org.jetbrains.jet.lang.cfg.pseudocode.*; import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -72,7 +72,7 @@ public class JetControlFlowTest extends JetLiteFixture {
}; };
AnalyzerFacade.analyzeNamespace(file.getRootNamespace(), new JetControlFlowDataTraceFactory() { JetTestUtils.analyzeNamespace(file.getRootNamespace(), new JetControlFlowDataTraceFactory() {
@NotNull @NotNull
@Override @Override
public JetPseudocodeTrace createTrace(JetElement element) { public JetPseudocodeTrace createTrace(JetElement element) {
@@ -420,7 +420,7 @@ public class JetControlFlowTest extends JetLiteFixture {
suite.addTest(JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/cfg/", true, new JetTestCaseBuilder.NamedTestFactory() { suite.addTest(JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/cfg/", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetControlFlowTest(dataPath, name); return new JetControlFlowTest(dataPath, name);
} }
})); }));
@@ -3,11 +3,10 @@ package org.jetbrains.jet.checkers;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.ImportingStrategy;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import java.util.Collections; import java.util.Collections;
@@ -81,7 +80,10 @@ public class CheckerTestUtilTest extends JetLiteFixture {
} }
public void test(PsiFile psiFile) { public void test(PsiFile psiFile) {
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), (JetFile) psiFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER); BindingContext bindingContext = AnalyzerFacade.analyzeOneNamespaceWithJavaIntegration(
((JetFile) psiFile).getRootNamespace(),
JetControlFlowDataTraceFactory.EMPTY);
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString(); String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString();
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList(); List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
@@ -9,15 +9,16 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.lang.Configuration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.ImportingStrategy; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
import java.io.File;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -81,14 +82,20 @@ public class JetDiagnosticsTest extends JetLiteFixture {
List<TestFile> testFileFiles = createTestFiles(testFileName, expectedText); List<TestFile> testFileFiles = createTestFiles(testFileName, expectedText);
boolean importJdk = expectedText.contains("+JDK"); boolean importJdk = expectedText.contains("+JDK");
ImportingStrategy importingStrategy = importJdk ? JavaDefaultImports.JAVA_DEFAULT_IMPORTS : ImportingStrategy.NONE; // Configuration configuration = importJdk ? JavaBridgeConfiguration.createJavaBridgeConfiguration(getProject()) : Configuration.EMPTY;
List<JetDeclaration> namespaces = Lists.newArrayList(); List<JetDeclaration> namespaces = Lists.newArrayList();
for (TestFile testFileFile : testFileFiles) { for (TestFile testFileFile : testFileFiles) {
namespaces.add(testFileFile.jetFile.getRootNamespace()); namespaces.add(testFileFile.jetFile.getRootNamespace());
} }
BindingContext bindingContext = AnalyzingUtils.getInstance(importingStrategy).analyzeNamespaces(getProject(), namespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); BindingContext bindingContext;
if (importJdk) {
bindingContext = AnalyzerFacade.analyzeNamespacesWithJavaIntegration(getProject(), namespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
}
else {
bindingContext = AnalyzingUtils.getInstance().analyzeNamespaces(getProject(), Configuration.EMPTY, namespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
}
StringBuilder actualText = new StringBuilder(); StringBuilder actualText = new StringBuilder();
for (TestFile testFileFile : testFileFiles) { for (TestFile testFileFile : testFileFiles) {
@@ -167,7 +174,7 @@ public class JetDiagnosticsTest extends JetLiteFixture {
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/diagnostics/tests", true, new JetTestCaseBuilder.NamedTestFactory() { return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/diagnostics/tests", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetDiagnosticsTest(dataPath, name); return new JetDiagnosticsTest(dataPath, name);
} }
}); });
@@ -39,7 +39,7 @@ public class FunctionGenTest extends CodegenTestCase {
loadText("fun foo(x: String?, y: Any?) = x + y"); loadText("fun foo(x: String?, y: Any?) = x + y");
String text = generateToText(); String text = generateToText();
assertTrue(text.contains(".stringPlus")); assertTrue(text.contains(".stringPlus"));
System.out.println(text); // System.out.println(text);
Method foo = generateFunction(); Method foo = generateFunction();
assertEquals("something239", foo.invoke(null, "something", 239)); assertEquals("something239", foo.invoke(null, "something", 239));
assertEquals("null239", foo.invoke(null, null, 239)); assertEquals("null239", foo.invoke(null, null, 239));
@@ -52,7 +52,7 @@ public class FunctionGenTest extends CodegenTestCase {
loadText("fun foo(x: String, y: Any?) = x + y + 120"); loadText("fun foo(x: String, y: Any?) = x + y + 120");
String text = generateToText(); String text = generateToText();
assertFalse(text.contains(".stringPlus")); assertFalse(text.contains(".stringPlus"));
System.out.println(text); // System.out.println(text);
Method foo = generateFunction(); Method foo = generateFunction();
assertEquals("something239120", foo.invoke(null, "something", 239)); assertEquals("something239120", foo.invoke(null, "something", 239));
assertEquals("null239120", foo.invoke(null, null, 239)); assertEquals("null239120", foo.invoke(null, null, 239));
@@ -285,6 +285,36 @@ public class PrimitiveTypesTest extends CodegenTestCase {
blackBoxFile("regressions/kt518.jet"); blackBoxFile("regressions/kt518.jet");
} }
public void testKt711 () throws Exception {
loadText("fun box() = if ((1 ?: 0) == 1) \"OK\" else \"fail\"");
blackBox();
}
public void testSureNonnull () throws Exception {
loadText("fun box() = 10.sure().toString()");
assertFalse(generateToText().contains("IFNONNULL"));
}
public void testSureNullable () throws Exception {
loadText("val a : Int? = 10; fun box() = a.sure().toString()");
assertTrue(generateToText().contains("IFNONNULL"));
}
public void testSafeNonnull () throws Exception {
loadText("fun box() = 10?.toString()");
assertFalse(generateToText().contains("IFNULL"));
}
public void testSafeNullable () throws Exception {
loadText("val a : Int? = 10; fun box() = a?.toString()");
assertTrue(generateToText().contains("IFNULL"));
}
public void testKt737() throws Exception {
loadText("fun box() = if(3.compareTo(2) != 1) \"fail\" else if(5.byt.compareTo(10.lng) >= 0) \"fail\" else \"OK\"");
assertEquals("OK", blackBox());
}
public void testKt665() throws Exception { public void testKt665() throws Exception {
loadText("fun f(x: Long, zzz: Long = 1): Long\n" + loadText("fun f(x: Long, zzz: Long = 1): Long\n" +
"{\n" + "{\n" +
@@ -298,7 +328,27 @@ public class PrimitiveTypesTest extends CodegenTestCase {
" System.out?.println(f(six))\n" + " System.out?.println(f(six))\n" +
" return \"OK\"" + " return \"OK\"" +
"}"); "}");
System.out.println(generateToText());
blackBox(); blackBox();
} }
public void testKt752 () {
blackBoxFile("regressions/kt752.jet");
}
public void testKt753 () {
blackBoxFile("regressions/kt753.jet");
}
public void testKt684 () {
blackBoxFile("regressions/kt684.jet");
}
public void testKt756 () {
blackBoxFile("regressions/kt756.jet");
System.out.println(generateToText());
}
public void testKt757 () {
blackBoxFile("regressions/kt757.jet");
}
} }
@@ -104,7 +104,7 @@ public class JetParsingTest extends ParsingTestCase {
JetTestCaseBuilder.NamedTestFactory factory = new JetTestCaseBuilder.NamedTestFactory() { JetTestCaseBuilder.NamedTestFactory factory = new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetParsingTest(dataPath, name); return new JetParsingTest(dataPath, name);
} }
}; };
@@ -2,6 +2,7 @@ package org.jetbrains.jet.resolve;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
@@ -11,7 +12,6 @@ import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnostic;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -84,7 +84,7 @@ public class ExpectedResolveData {
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject()); JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject());
JetStandardLibrary lib = semanticServices.getStandardLibrary(); JetStandardLibrary lib = semanticServices.getStandardLibrary();
BindingContext bindingContext = AnalyzerFacade.analyzeNamespace(file.getRootNamespace(), JetControlFlowDataTraceFactory.EMPTY); BindingContext bindingContext = JetTestUtils.analyzeNamespace(file.getRootNamespace(), JetControlFlowDataTraceFactory.EMPTY);
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
if (diagnostic instanceof UnresolvedReferenceDiagnostic) { if (diagnostic instanceof UnresolvedReferenceDiagnostic) {
UnresolvedReferenceDiagnostic unresolvedReferenceDiagnostic = (UnresolvedReferenceDiagnostic) diagnostic; UnresolvedReferenceDiagnostic unresolvedReferenceDiagnostic = (UnresolvedReferenceDiagnostic) diagnostic;
@@ -157,7 +157,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
return JetTestCaseBuilder.suiteForDirectory(getHomeDirectory() + "/compiler/testData/", "/resolve/", true, new JetTestCaseBuilder.NamedTestFactory() { return JetTestCaseBuilder.suiteForDirectory(getHomeDirectory() + "/compiler/testData/", "/resolve/", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetResolveTest(dataPath + "/" + name + ".jet", name); return new JetResolveTest(dataPath + "/" + name + ".jet", name);
} }
}); });
@@ -8,7 +8,7 @@ import java.lang.reflect.Method;
public class JetNpeTest extends CodegenTestCase { public class JetNpeTest extends CodegenTestCase {
public void testStackTrace () { public void testStackTrace () {
try { try {
Intrinsics.sure(null); Intrinsics.throwNpe();
fail("No Sure thrown"); fail("No Sure thrown");
} }
catch (NullPointerException e) { catch (NullPointerException e) {
@@ -25,7 +25,7 @@ public class JetNpeTest extends CodegenTestCase {
public void testNull () throws Exception { public void testNull () throws Exception {
loadText("fun box() = if(null.sure() == 10) \"OK\" else \"fail\""); loadText("fun box() = if(null.sure() == 10) \"OK\" else \"fail\"");
System.out.println(generateToText()); // System.out.println(generateToText());
Method box = generateFunction("box"); Method box = generateFunction("box");
assertThrows(box, NullPointerException.class, null); assertThrows(box, NullPointerException.class, null);
} }
+2
View File
@@ -59,7 +59,9 @@
<codeInsight.overrideMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.OverrideMethodsHandler"/> <codeInsight.overrideMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.OverrideMethodsHandler"/>
<!--
<java.elementFinder implementation="org.jetbrains.jet.plugin.java.JavaElementFinder"/> <java.elementFinder implementation="org.jetbrains.jet.plugin.java.JavaElementFinder"/>
-->
<toolWindow id="CodeWindow" <toolWindow id="CodeWindow"
factoryClass="org.jetbrains.jet.plugin.internal.codewindow.BytecodeToolwindow$Factory" factoryClass="org.jetbrains.jet.plugin.internal.codewindow.BytecodeToolwindow$Factory"
anchor="right"/> anchor="right"/>
@@ -52,6 +52,11 @@ public class JetQuickDocumentationProvider extends AbstractDocumentationProvider
return "Not a reference"; return "Not a reference";
} }
@Override
public String generateDoc(PsiElement element, PsiElement originalElement) {
return getQuickNavigateInfo(element, originalElement);
}
private String render(DeclarationDescriptor declarationDescriptor) { private String render(DeclarationDescriptor declarationDescriptor) {
return DescriptorRenderer.HTML.render(declarationDescriptor); return DescriptorRenderer.HTML.render(declarationDescriptor);
} }
@@ -20,7 +20,7 @@ public class LabelsAnnotator implements Annotator {
element.accept(new JetVisitorVoid() { element.accept(new JetVisitorVoid() {
@Override @Override
public void visitPrefixExpression(JetPrefixExpression expression) { public void visitPrefixExpression(JetPrefixExpression expression) {
JetSimpleNameExpression operationSign = expression.getOperationSign(); JetSimpleNameExpression operationSign = expression.getOperationReference();
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
holder.createInfoAnnotation(operationSign, null).setTextAttributes(JetHighlighter.JET_LABEL_IDENTIFIER); holder.createInfoAnnotation(operationSign, null).setTextAttributes(JetHighlighter.JET_LABEL_IDENTIFIER);
} }
@@ -24,9 +24,8 @@ import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespace; import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetFileType;
import java.io.File; import java.io.File;
@@ -59,7 +58,7 @@ public class JetCompiler implements TranslatingCompiler {
public void compile(final CompileContext compileContext, Chunk<Module> moduleChunk, final VirtualFile[] virtualFiles, OutputSink outputSink) { public void compile(final CompileContext compileContext, Chunk<Module> moduleChunk, final VirtualFile[] virtualFiles, OutputSink outputSink) {
if (virtualFiles.length == 0) return; if (virtualFiles.length == 0) return;
Module module = compileContext.getModuleByFile(virtualFiles[0]); final Module module = compileContext.getModuleByFile(virtualFiles[0]);
final VirtualFile outputDir = compileContext.getModuleOutputDirectory(module); final VirtualFile outputDir = compileContext.getModuleOutputDirectory(module);
if (outputDir == null) { if (outputDir == null) {
compileContext.addMessage(ERROR, "[Internal Error] No output directory", "", -1, -1); compileContext.addMessage(ERROR, "[Internal Error] No output directory", "", -1, -1);
@@ -80,10 +79,8 @@ public class JetCompiler implements TranslatingCompiler {
} }
} }
BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces( BindingContext bindingContext =
compileContext.getProject(), namespaces, AnalyzerFacade.analyzeNamespacesWithJavaIntegration(compileContext.getProject(), namespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
Predicates.<PsiFile>alwaysTrue(),
JetControlFlowDataTraceFactory.EMPTY);
boolean errors = false; boolean errors = false;
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
@@ -35,9 +35,8 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespace; import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetFileType;
import java.util.*; import java.util.*;
@@ -211,8 +210,8 @@ public class JavaElementFinder extends PsiElementFinder {
if (dirty.size() > 0) { if (dirty.size() > 0) {
final BindingContext context = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).shallowAnalyzeFiles(dirty); final BindingContext context = AnalyzerFacade.shallowAnalyzeFiles(dirty);
state.compileCorrectNamespaces(context, AnalyzingUtils.collectRootNamespaces(dirty)); state.compileCorrectNamespaces(context, AnalyzerFacade.collectRootNamespaces(dirty));
state.getFactory().files(); state.getFactory().files();
} }
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
@@ -78,7 +79,6 @@ class JetSimpleNameReference extends JetPsiReference {
private Object[] collectLookupElements(BindingContext bindingContext, JetScope scope) { private Object[] collectLookupElements(BindingContext bindingContext, JetScope scope) {
List<LookupElement> result = Lists.newArrayList(); List<LookupElement> result = Lists.newArrayList();
for (final DeclarationDescriptor descriptor : scope.getAllDescriptors()) { for (final DeclarationDescriptor descriptor : scope.getAllDescriptors()) {
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal());
LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName()); LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName());
String typeText = ""; String typeText = "";
String tailText = ""; String tailText = "";
@@ -100,16 +100,19 @@ class JetSimpleNameReference extends JetPsiReference {
typeText = DescriptorRenderer.TEXT.renderType(outType); typeText = DescriptorRenderer.TEXT.renderType(outType);
} }
else if (descriptor instanceof ClassDescriptor) { else if (descriptor instanceof ClassDescriptor) {
tailText = " (" + DescriptorRenderer.getFQName(descriptor.getContainingDeclaration()) + ")"; tailText = " (" + DescriptorUtils.getFQName(descriptor.getContainingDeclaration()) + ")";
tailTextGrayed = true; tailTextGrayed = true;
} }
else { else {
typeText = DescriptorRenderer.TEXT.render(descriptor); typeText = DescriptorRenderer.TEXT.render(descriptor);
} }
element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText); element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText);
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal());
if (declaration != null) { if (declaration != null) {
element = element.setIcon(declaration.getIcon(Iconable.ICON_FLAG_OPEN | Iconable.ICON_FLAG_VISIBILITY)); element = element.setIcon(declaration.getIcon(Iconable.ICON_FLAG_OPEN | Iconable.ICON_FLAG_VISIBILITY));
} }
result.add(element); result.add(element);
} }
return result.toArray(); return result.toArray();
-14
View File
@@ -24,17 +24,3 @@ namespace boundsWithSubstitutors {
abstract val x : fun (B<<error>Char</error>>) : B<<error>Any</error>> abstract val x : fun (B<<error>Char</error>>) : B<<error>Any</error>>
} }
fun test() {
foo<<error>Int?</error>>()
foo<Int>()
bar<Int?>()
bar<Int>()
bar<<error>Double?</error>>()
bar<<error>Double</error>>()
1.buzz<<error>Double</error>>()
}
fun foo<T : Any>() {}
fun bar<T : Int?>() {}
fun <T : <warning>Int</warning>> Int.buzz() : Unit {}
+13
View File
@@ -0,0 +1,13 @@
fun test() {
foo<<error>Int?</error>>()
foo<Int>()
bar<Int?>()
bar<Int>()
bar<<error>Double?</error>>()
bar<<error>Double</error>>()
1.buzz<<error>Double</error>>()
}
fun foo<T : Any>() {}
fun bar<T : Int?>() {}
fun <T : <warning>Int</warning>> Int.buzz() : Unit {}
@@ -0,0 +1,13 @@
open class MySecondClass() {
}
open class MyFirstClass<T> {
}
class A() : My<caret> {
public fun test() {
}
}
// EXIST: MySecondClass, MyFirstClass
@@ -0,0 +1,11 @@
namespace Test.SubTest.AnotherTest
open class TestClass {
}
class A() : Test.SubTest.AnotherTest.Te<caret> {
public fun test() {
}
}
// EXIST: TestClass
@@ -0,0 +1,10 @@
open class MyClass() {
}
class A() : My<caret> {
public fun test() {
val a : MyC<caret>
}
}
// EXIST: MyClass
@@ -58,21 +58,21 @@ public class JetPsiCheckerTest extends LightDaemonAnalyzerTestCase {
JetTestCaseBuilder.appendTestsInDirectory(PluginTestCaseBase.getTestDataPathBase(), "/checker/", false, JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() { JetTestCaseBuilder.appendTestsInDirectory(PluginTestCaseBase.getTestDataPathBase(), "/checker/", false, JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetPsiCheckerTest(dataPath, name); return new JetPsiCheckerTest(dataPath, name);
} }
}, suite); }, suite);
JetTestCaseBuilder.appendTestsInDirectory(PluginTestCaseBase.getTestDataPathBase(), "/checker/regression/", false, JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() { JetTestCaseBuilder.appendTestsInDirectory(PluginTestCaseBase.getTestDataPathBase(), "/checker/regression/", false, JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetPsiCheckerTest(dataPath, name); return new JetPsiCheckerTest(dataPath, name);
} }
}, suite); }, suite);
JetTestCaseBuilder.appendTestsInDirectory(PluginTestCaseBase.getTestDataPathBase(), "/checker/infos/", false, JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() { JetTestCaseBuilder.appendTestsInDirectory(PluginTestCaseBase.getTestDataPathBase(), "/checker/infos/", false, JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetPsiCheckerTest(dataPath, name).setCheckInfos(true); return new JetPsiCheckerTest(dataPath, name).setCheckInfos(true);
} }
}, suite); }, suite);
@@ -0,0 +1,59 @@
package org.jetbrains.jet.completion;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import java.io.File;
/**
* @author Nikolay.Krasko
*/
public class JetBasicCompletionTest extends JetCompletionTestBase {
private final String myPath;
private final String myName;
public JetBasicCompletionTest(@NotNull String path, @NotNull String name) {
myPath = path;
myName = name;
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
setName("testCompletionExecute");
}
public void testCompletionExecute() {
doTest();
}
@Override
protected String getTestDataPath() {
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
File.separator;
}
@NotNull
@Override
public String getName() {
return "test" + myName;
}
@NotNull
public static TestSuite suite() {
TestSuite suite = new TestSuite();
JetTestCaseBuilder.appendTestsInDirectory(
PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/", false,
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetBasicCompletionTest(dataPath, name);
}
}, suite);
return suite;
}
}
@@ -22,10 +22,10 @@ public class KeywordsCompletionTest extends JetCompletionTestBase {
myName = name; myName = name;
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null" // Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
setName("testComletionExecute"); setName("testCompletionExecute");
} }
public void testComletionExecute() { public void testCompletionExecute() {
doTest(); doTest();
} }
@@ -51,7 +51,7 @@ public class KeywordsCompletionTest extends JetCompletionTestBase {
@NotNull @NotNull
@Override @Override
public junit.framework.Test createTest(@NotNull String dataPath, @NotNull String name) { public junit.framework.Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new KeywordsCompletionTest(dataPath, name); return new KeywordsCompletionTest(dataPath, name);
} }
}, suite); }, suite);
@@ -53,7 +53,7 @@ public class JetQuickFixTest extends LightQuickFixTestCase {
JetTestCaseBuilder.NamedTestFactory namedTestFactory = new JetTestCaseBuilder.NamedTestFactory() { JetTestCaseBuilder.NamedTestFactory namedTestFactory = new JetTestCaseBuilder.NamedTestFactory() {
@NotNull @NotNull
@Override @Override
public Test createTest(@NotNull String dataPath, @NotNull String name) { public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new JetQuickFixTest(dataPath, name); return new JetQuickFixTest(dataPath, name);
} }
}; };
+13 -7
View File
@@ -13,14 +13,20 @@ public class Intrinsics {
return ((self == null) ? "null" : self) + ((other == null) ? "null" : other.toString()); return ((self == null) ? "null" : self) + ((other == null) ? "null" : other.toString());
} }
public static Object sure(Object self) { public static void throwNpe() {
if(self == null) throw new JetNullPointerException();
return throwNpe();
return self;
} }
private static Object throwNpe() { public static int compare(long thisVal, long anotherVal) {
throw new JetNullPointerException(); return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
public static int compare(int thisVal, int anotherVal) {
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
public static int compare(boolean thisVal, boolean anotherVal) {
return (thisVal == anotherVal ? 0 : (anotherVal ? 1 : -1));
} }
private static Throwable sanitizeStackTrace(Throwable throwable) { private static Throwable sanitizeStackTrace(Throwable throwable) {
@@ -32,7 +38,7 @@ public class Intrinsics {
list.add(ste); list.add(ste);
} }
else { else {
if("jet.runtime.Intrinsics".equals(ste.getClassName()) && "sure".equals(ste.getMethodName())) { if("jet.runtime.Intrinsics".equals(ste.getClassName()) && "throwNpe".equals(ste.getMethodName())) {
skip = false; skip = false;
} }
} }
+27
View File
@@ -0,0 +1,27 @@
package jet.typeinfo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation for method
*
* The fact of receiver presence must be deducted from presence of 'this$receiver' parameter
*
* @author alex.tkachman
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JetMethod {
/**
* @return type projections or empty
*/
JetTypeProjection[] returnTypeProjections() default {};
/**
* @return is this type returnTypeNullable
*/
boolean nullableReturnType() default false;
}
+35
View File
@@ -0,0 +1,35 @@
package jet.typeinfo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation for parameters
*
* @author alex.tkachman
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface JetParameter {
/**
* @return name of parameter
*/
String name ();
/**
* @return type projections or empty
*/
JetTypeProjection[] typeProjections() default {};
/**
* @return is this type nullable
*/
boolean nullable () default false;
/**
* @return if this parameter has default value
*/
boolean hasDefaultValue () default false;
}
@@ -0,0 +1,20 @@
package jet.typeinfo;
/**
* @author alex.tkachman
*/
public @interface JetTypeDescriptor{
//
// case of type parameter
//
String varName() default "";
boolean reified () default true;
TypeInfoVariance variance() default TypeInfoVariance.INVARIANT;
int [] upperBounds() default {};
//
// case of real type
//
Class javaClass() default Object.class;
JetTypeProjection [] projections() default {};
}

Some files were not shown because too many files have changed in this diff Show More