diff --git a/.gitignore b/.gitignore
index 927b20cd726..57a2b37fbb5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,7 @@ patches-master
out
dist
ideaSDK
-PluginVerifier
+dependencies
.idea/dictionaries/yozh.xml
.idea/workspace.xml
tmp
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index b6d87385922..1a6acd9fda1 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -171,7 +171,7 @@
-
+
diff --git a/.idea/libraries/js_libs.xml b/.idea/libraries/js_libs.xml
index f81c39f0b22..54a91f2d97b 100644
--- a/.idea/libraries/js_libs.xml
+++ b/.idea/libraries/js_libs.xml
@@ -1,7 +1,6 @@
-
diff --git a/.idea/runConfigurations/Integration_Tests.xml b/.idea/runConfigurations/Integration_Tests.xml
new file mode 100644
index 00000000000..218f6e6775d
--- /dev/null
+++ b/.idea/runConfigurations/Integration_Tests.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TeamCityBuild.xml b/TeamCityBuild.xml
index a37cd929ec5..bf903653b59 100644
--- a/TeamCityBuild.xml
+++ b/TeamCityBuild.xml
@@ -10,11 +10,11 @@
-
+
-
+
diff --git a/bin/kotlin b/bin/kotlin
index 5cca3809cde..933ac6ed261 100755
--- a/bin/kotlin
+++ b/bin/kotlin
@@ -23,6 +23,7 @@ classpath="$classpath:$root/out/production/stdlib"
classpath="$classpath:$root/lib/*:$ideaRoot/lib/*:$ideaRoot/lib/rt/*"
exec java $JAVA_OPTS \
+ -ea \
-classpath "$classpath" \
org.jetbrains.jet.cli.jvm.K2JVMCompiler \
"$@"
diff --git a/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java
index d03683a331b..8127a45ad66 100644
--- a/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java
+++ b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java
@@ -42,17 +42,18 @@ public class BytecodeCompiler {
/**
- * Creates new instance of {@link org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentConfiguration} instance using the arguments specified.
+ * Creates new instance of {@link org.jetbrains.jet.cli.jvm.compiler.K2JVMCompileEnvironmentConfiguration} instance using the arguments specified.
*
* @param stdlib path to "kotlin-runtime.jar", only used if not null and not empty
* @param classpath compilation classpath, only used if not null and not empty
*
* @return compile environment instance
*/
- private CompileEnvironmentConfiguration env( String stdlib, String[] classpath ) {
+ private K2JVMCompileEnvironmentConfiguration env( String stdlib, String[] classpath ) {
CompilerDependencies dependencies = CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.REGULAR);
JetCoreEnvironment environment = new JetCoreEnvironment(CompileEnvironmentUtil.createMockDisposable(), dependencies);
- CompileEnvironmentConfiguration env = new CompileEnvironmentConfiguration(environment, dependencies, MessageCollector.PLAIN_TEXT_TO_SYSTEM_ERR);
+ K2JVMCompileEnvironmentConfiguration
+ env = new K2JVMCompileEnvironmentConfiguration(environment, MessageCollector.PLAIN_TEXT_TO_SYSTEM_ERR);
if (( stdlib != null ) && ( stdlib.trim().length() > 0 )) {
File file = new File(stdlib);
@@ -140,7 +141,7 @@ public class BytecodeCompiler {
*/
public void moduleToJar ( @NotNull String module, @NotNull String jar, boolean includeRuntime, @Nullable String stdlib, @Nullable String[] classpath ) {
try {
- CompileEnvironmentConfiguration env = env(stdlib, classpath);
+ K2JVMCompileEnvironmentConfiguration env = env(stdlib, classpath);
List modules = CompileEnvironmentUtil.loadModuleScript(module, env.getMessageCollector());
File directory = new File(module).getParentFile();
boolean success = KotlinToJVMBytecodeCompiler.compileModules(env, modules, directory, jar, null, includeRuntime);
diff --git a/build.xml b/build.xml
index cdee4e237a9..4172b626402 100644
--- a/build.xml
+++ b/build.xml
@@ -19,6 +19,7 @@
+
@@ -36,6 +37,9 @@
+
+
+
@@ -166,17 +170,40 @@
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -189,11 +216,13 @@
+
-
-
+
-
+
+
+
@@ -213,8 +242,61 @@
-
+
+
+
+
+
+ (kotlinc.internal.com.intellij.lang.ASTNode);
+ }
+
+ # Keep the special static methods that are required in enumeration classes.
+ -keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+ }
+
+ -keepclassmembers class * {
+ ** toString();
+ ** hashCode();
+ ** project();
+
+ ** TYPE;
+ ** ourInstance;
+ }
+ ]]>
+
diff --git a/build/jarjar-1.2.jar b/build/jarjar-1.2.jar
deleted file mode 100644
index e32d30cd2ac..00000000000
Binary files a/build/jarjar-1.2.jar and /dev/null differ
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
index ea23cbc798f..311950b55e8 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
@@ -79,7 +79,7 @@ public class CallableMethod implements Callable {
}
public void setNeedsReceiver(@Nullable CallableDescriptor receiverClass) {
- this.receiverFunction = receiverClass;
+ this.receiverFunction = receiverClass.getOriginal();
}
public JetType getThisType() {
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
index 7637d081dbf..75503de6efe 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
@@ -154,7 +154,8 @@ public class ExpressionCodegen extends JetVisitor {
throw e;
}
catch (Throwable error) {
- throw new CompilationException(error.getMessage(), error, selector);
+ String message = error.getMessage();
+ throw new CompilationException(message != null ? message : "null", error, selector);
}
}
@@ -888,7 +889,7 @@ public class ExpressionCodegen extends JetVisitor {
return answer;
}
- private void markLineNumber(JetElement statement) {
+ private void markLineNumber(@NotNull JetElement statement) {
final Document document = statement.getContainingFile().getViewProvider().getDocument();
if (document != null) {
int lineNumber = document.getLineNumber(statement.getTextRange().getStartOffset()); // 0-based
@@ -963,13 +964,17 @@ public class ExpressionCodegen extends JetVisitor {
descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
}
else {
+ if(resolvedCall instanceof VariableAsFunctionResolvedCall) {
+ VariableAsFunctionResolvedCall call = (VariableAsFunctionResolvedCall) resolvedCall;
+ resolvedCall = call.getVariableCall();
+ }
receiver = StackValue.receiver(resolvedCall, receiver, this, null, state);
descriptor = resolvedCall.getResultingDescriptor();
}
- if (descriptor instanceof VariableAsFunctionDescriptor) {
- descriptor = ((VariableAsFunctionDescriptor) descriptor).getVariableDescriptor();
- }
+ //if (descriptor instanceof VariableAsFunctionDescriptor) {
+ // descriptor = ((VariableAsFunctionDescriptor) descriptor).getVariableDescriptor();
+ //}
final IntrinsicMethod intrinsic = state.getInjector().getIntrinsics().getIntrinsic(descriptor);
if (intrinsic != null) {
@@ -1254,14 +1259,24 @@ public class ExpressionCodegen extends JetVisitor {
}
else if (funDescriptor instanceof FunctionDescriptor) {
final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor;
- return invokeFunction(expression, fd, receiver);
+ if(resolvedCall instanceof VariableAsFunctionResolvedCall) {
+ VariableAsFunctionResolvedCall call = (VariableAsFunctionResolvedCall) resolvedCall;
+ ResolvedCallWithTrace functionCall = call.getFunctionCall();
+ return invokeFunction(expression, functionCall.getResultingDescriptor(), receiver, functionCall);
+ }
+ else {
+ return invokeFunction(expression, fd, receiver, resolvedCall);
+ }
}
else {
throw new UnsupportedOperationException("unknown type of callee descriptor: " + funDescriptor);
}
}
- private StackValue invokeFunction(JetCallExpression expression, DeclarationDescriptor fd, StackValue receiver) {
+ private StackValue invokeFunction(JetCallExpression expression,
+ DeclarationDescriptor fd,
+ StackValue receiver,
+ ResolvedCall extends CallableDescriptor> resolvedCall) {
boolean superCall = false;
if (expression.getParent() instanceof JetQualifiedExpression) {
final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
@@ -1294,8 +1309,6 @@ public class ExpressionCodegen extends JetVisitor {
return returnValueAsStackValue((FunctionDescriptor) fd, callReturnType);
}
else {
- ResolvedCall extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
- assert resolvedCall != null;
receiver = StackValue.receiver(resolvedCall, receiver, this, null, state);
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
@@ -1323,11 +1336,11 @@ public class ExpressionCodegen extends JetVisitor {
}
CallableMethod callableMethod;
- if (fd instanceof VariableAsFunctionDescriptor) {
- assert !superCall;
- callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
- }
- else if (fd instanceof ExpressionAsFunctionDescriptor || (fd instanceof SimpleFunctionDescriptor && fd.getContainingDeclaration() instanceof FunctionDescriptor)) {
+ //if (fd instanceof VariableAsFunctionDescriptor) {
+ // assert !superCall;
+ // callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
+ //}
+ if (fd instanceof ExpressionAsFunctionDescriptor || (fd instanceof SimpleFunctionDescriptor && fd.getContainingDeclaration() instanceof FunctionDescriptor)) {
SimpleFunctionDescriptor invoke = CodegenUtil.createInvoke((FunctionDescriptor) fd);
callableMethod = ClosureCodegen.asCallableMethod(invoke);
}
@@ -1350,6 +1363,10 @@ public class ExpressionCodegen extends JetVisitor {
ResolvedCall extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
assert resolvedCall != null;
+ if(resolvedCall instanceof VariableAsFunctionResolvedCall) {
+ resolvedCall = ((VariableAsFunctionResolvedCall)resolvedCall).getFunctionCall();
+ }
+
if(!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod, state);
receiver.put(receiver.type, v);
@@ -1396,7 +1413,7 @@ public class ExpressionCodegen extends JetVisitor {
else if(descriptor instanceof ExpressionReceiver) {
ExpressionReceiver expressionReceiver = (ExpressionReceiver) descriptor;
JetExpression expr = expressionReceiver.getExpression();
- Type exprType = expressionType(expr);
+ Type exprType = asmType(expressionReceiver.getType());
gen(expr, exprType);
if(type != null)
StackValue.onStack(exprType).put(type, v);
@@ -1529,15 +1546,55 @@ public class ExpressionCodegen extends JetVisitor {
Type type = asmType(outType);
assert type.getSort() == Type.ARRAY;
Type elementType = correctElementType(type);
- int size = valueArgument.getArguments().size();
+ List arguments = valueArgument.getArguments();
+ int size = arguments.size();
- v.iconst(valueArgument.getArguments().size());
- v.newarray(elementType);
+ boolean hasSpread = false;
for(int i = 0; i != size; ++i) {
- v.dup();
- v.iconst(i);
- gen(valueArgument.getArguments().get(i).getArgumentExpression(), elementType);
- StackValue.arrayElement(elementType, false).store(v);
+ if(arguments.get(i).getSpreadElement() != null) {
+ hasSpread = true;
+ break;
+ }
+ }
+
+ if(hasSpread) {
+ if(size == 1) {
+ gen(arguments.get(0).getArgumentExpression(), type);
+ }
+ else {
+ String owner = "jet/runtime/Intrinsics$SpreadBuilder";
+ v.anew(Type.getObjectType(owner));
+ v.dup();
+ v.invokespecial(owner, "", "()V");
+ for(int i = 0; i != size; ++i) {
+ v.dup();
+ ValueArgument argument = arguments.get(i);
+ if(argument.getSpreadElement() != null) {
+ gen(argument.getArgumentExpression(),JetTypeMapper.TYPE_OBJECT);
+ v.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V");
+ }
+ else {
+ gen(argument.getArgumentExpression(), elementType);
+ v.invokevirtual(owner, "add", "(Ljava/lang/Object;)Z");
+ v.pop();
+ }
+ }
+ v.dup();
+ v.invokevirtual(owner, "size", "()I");
+ v.newarray(elementType);
+ v.invokevirtual(owner, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;");
+ v.checkcast(type);
+ }
+ }
+ else {
+ v.iconst(arguments.size());
+ v.newarray(elementType);
+ for(int i = 0; i != size; ++i) {
+ v.dup();
+ v.iconst(i);
+ gen(arguments.get(i).getArgumentExpression(), elementType);
+ StackValue.arrayElement(elementType, false).store(v);
+ }
}
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
index 0a828995516..d759cf0e671 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
@@ -159,7 +159,7 @@ public class FunctionCodegen {
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i + start);
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
av.writeName(parameterDescriptor.getName());
- av.writeHasDefaultValue(parameterDescriptor.hasDefaultValue());
+ av.writeHasDefaultValue(parameterDescriptor.declaresDefaultValue());
av.writeNullable(parameterDescriptor.getType().isNullable());
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) {
av.writeType(jvmSignature.getKotlinParameterTypes().get(i + start).getKotlinSignature());
@@ -312,7 +312,7 @@ public class FunctionCodegen {
boolean needed = false;
if(functionDescriptor != null) {
for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
- if(parameterDescriptor.hasDefaultValue()) {
+ if(parameterDescriptor.declaresDefaultValue()) {
needed = true;
break;
}
@@ -398,7 +398,7 @@ public class FunctionCodegen {
Type t = argumentTypes[extra + index];
Label endArg = null;
- if (parameterDescriptor.hasDefaultValue()) {
+ if (parameterDescriptor.declaresDefaultValue()) {
iv.load(maskIndex, Type.INT_TYPE);
iv.iconst(1 << index);
iv.and(Type.INT_TYPE);
@@ -418,7 +418,7 @@ public class FunctionCodegen {
iv.load(var, t);
var += t.getSize();
- if (parameterDescriptor.hasDefaultValue()) {
+ if (parameterDescriptor.declaresDefaultValue()) {
iv.mark(endArg);
}
}
@@ -446,22 +446,22 @@ public class FunctionCodegen {
}
}
- private static boolean differentMethods(Method method, Method overriden) {
- if(!method.getReturnType().equals(overriden.getReturnType()))
+ private static boolean differentMethods(Method method, Method overridden) {
+ if(!method.getReturnType().equals(overridden.getReturnType()))
return true;
Type[] methodArgumentTypes = method.getArgumentTypes();
- Type[] overridenArgumentTypes = overriden.getArgumentTypes();
- if(methodArgumentTypes.length != overridenArgumentTypes.length)
+ Type[] overriddenArgumentTypes = overridden.getArgumentTypes();
+ if(methodArgumentTypes.length != overriddenArgumentTypes.length)
return true;
for(int i = 0; i != methodArgumentTypes.length; ++i)
- if(!methodArgumentTypes[i].equals(overridenArgumentTypes[i]))
+ if(!methodArgumentTypes[i].equals(overriddenArgumentTypes[i]))
return true;
return false;
}
private static void checkOverride(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) {
Method method = state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod();
- Method overriden = state.getInjector().getJetTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod();
+ Method overridden = state.getInjector().getJetTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod();
if(overriddenFunction.getModality() == Modality.ABSTRACT) {
Set extends FunctionDescriptor> overriddenFunctions = overriddenFunction.getOverriddenDescriptors();
@@ -470,17 +470,17 @@ public class FunctionCodegen {
}
}
- if(differentMethods(method, overriden)) {
+ if(differentMethods(method, overridden)) {
int flags = ACC_PUBLIC | ACC_BRIDGE; // TODO.
- final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overriden.getDescriptor(), null, null);
+ final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overridden.getDescriptor(), null, null);
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
StubCodegen.generateStubCode(mv);
}
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
mv.visitCode();
- Type[] argTypes = overriden.getArgumentTypes();
+ Type[] argTypes = overridden.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
for (int i = 0, reg = 1; i < argTypes.length; i++) {
@@ -495,11 +495,11 @@ public class FunctionCodegen {
}
iv.invokevirtual(state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), MapTypeMode.VALUE).getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
- if(JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType()))
+ if(JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overridden.getReturnType()))
StackValue.valueOf(iv, jvmSignature.getReturnType());
if(jvmSignature.getReturnType() == Type.VOID_TYPE)
iv.aconst(null);
- iv.areturn(overriden.getReturnType());
+ iv.areturn(overridden.getReturnType());
endVisit(mv, "bridge method", BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
}
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
index 7a7b2cd023d..c9475688601 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
@@ -551,7 +551,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
JetValueParameterAnnotationWriter jetValueParameterAnnotation = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
jetValueParameterAnnotation.writeName(valueParameter.getName());
- jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.hasDefaultValue());
+ jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue());
jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i));
jetValueParameterAnnotation.visitEnd();
++i;
@@ -1024,18 +1024,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
continue;
}
- Collection overridenDeclarations = OverridingUtil.getOverridenDeclarations(callableMemberDescriptor);
- for (CallableMemberDescriptor overridenDeclaration : overridenDeclarations) {
- if (overridenDeclaration.getModality() != Modality.ABSTRACT) {
- if (!CodegenUtil.isInterface(overridenDeclaration.getContainingDeclaration())) {
+ Collection overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor);
+ for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) {
+ if (overriddenDeclaration.getModality() != Modality.ABSTRACT) {
+ if (!CodegenUtil.isInterface(overriddenDeclaration.getContainingDeclaration())) {
continue root;
}
}
}
- for (CallableMemberDescriptor overridenDeclaration : overridenDeclarations) {
- if (overridenDeclaration.getModality() != Modality.ABSTRACT) {
- r.add(Pair.create(callableMemberDescriptor, overridenDeclaration));
+ for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) {
+ if (overriddenDeclaration.getModality() != Modality.ABSTRACT) {
+ r.add(Pair.create(callableMemberDescriptor, overriddenDeclaration));
}
}
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
index c19b4e25aa9..ed2ccb6502c 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
@@ -54,6 +54,7 @@ public class JetTypeMapper {
public static final Type TYPE_NOTHING = Type.getObjectType("jet/Nothing");
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
public static final Type JL_STRING_BUILDER = Type.getObjectType("java/lang/StringBuilder");
+ public static final Type JL_ARRAY_LIST = Type.getObjectType("java/util/ArrayList");
public static final Type JL_STRING_TYPE = Type.getObjectType("java/lang/String");
public static final Type JL_CHAR_SEQUENCE_TYPE = Type.getObjectType("java/lang/CharSequence");
private static final Type JL_COMPARABLE_TYPE = Type.getObjectType("java/lang/Comparable");
@@ -941,9 +942,10 @@ public class JetTypeMapper {
return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
}
else if (descriptor instanceof VariableDescriptor) {
- Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) descriptor);
- if (aBoolean != null && aBoolean) {
- JetType outType = ((VariableDescriptor) descriptor).getType();
+ VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
+ Boolean aBoolean = bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor);
+ if (aBoolean != null && aBoolean && variableDescriptor.isVar()) {
+ JetType outType = variableDescriptor.getType();
return StackValue.sharedTypeForType(mapType(outType, MapTypeMode.VALUE));
}
else {
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java
index c06ad378323..debed8671dc 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java
@@ -34,12 +34,14 @@ import java.util.List;
public class Concat implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) {
- codegen.generateStringBuilderConstructor();
if (receiver == null || receiver == StackValue.none()) { // LHS + RHS
+ codegen.generateStringBuilderConstructor();
codegen.invokeAppend(arguments.get(0)); // StringBuilder(LHS)
codegen.invokeAppend(arguments.get(1));
}
else { // LHS.plus(RHS)
+ receiver.put(JetTypeMapper.TYPE_OBJECT, v);
+ codegen.generateStringBuilderConstructor();
v.swap(); // StringBuilder LHS
codegen.invokeAppendMethod(expectedType); // StringBuilder(LHS)
codegen.invokeAppend(arguments.get(0));
diff --git a/compiler/cli/cli.iml b/compiler/cli/cli.iml
index 7a376081b61..03add988345 100644
--- a/compiler/cli/cli.iml
+++ b/compiler/cli/cli.iml
@@ -14,6 +14,7 @@
+
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java
new file mode 100644
index 00000000000..88dc62ee16c
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.cli.common;
+
+import com.sampullara.cli.Args;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
+import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
+import org.jetbrains.jet.cli.common.messages.MessageRenderer;
+import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException;
+
+import java.io.PrintStream;
+import java.util.List;
+
+import static org.jetbrains.jet.cli.common.ExitCode.INTERNAL_ERROR;
+import static org.jetbrains.jet.cli.common.ExitCode.OK;
+
+/**
+ * @author Pavel Talanov
+ */
+public abstract class CLICompiler {
+
+ @NotNull
+ public ExitCode exec(@NotNull PrintStream errStream, @NotNull String... args) {
+ A arguments = createArguments();
+ if (!parseArguments(errStream, arguments, args)) {
+ return INTERNAL_ERROR;
+ }
+ return exec(errStream, arguments);
+ }
+
+ /**
+ * Returns true if the arguments can be parsed correctly
+ */
+ protected boolean parseArguments(@NotNull PrintStream errStream, @NotNull A arguments, @NotNull String[] args) {
+ try {
+ Args.parse(arguments, args);
+ return true;
+ }
+ catch (IllegalArgumentException e) {
+ usage(errStream);
+ }
+ catch (Throwable t) {
+ // Always use tags
+ errStream.println(MessageRenderer.TAGS.renderException(t));
+ }
+ return false;
+ }
+
+ /**
+ * Allow derived classes to add additional command line arguments
+ */
+ protected void usage(@NotNull PrintStream target) {
+ // We should say something like
+ // Args.usage(target, K2JVMCompilerArguments.class);
+ // but currently cli-parser we are using does not support that
+ // a corresponding patch has been sent to the authors
+ // For now, we are using this:
+ PrintStream oldErr = System.err;
+ System.setErr(target);
+ try {
+ // TODO: use proper argv0
+ Args.usage(createArguments());
+ }
+ finally {
+ System.setErr(oldErr);
+ }
+ }
+
+ /**
+ * Strategy method to configure the environment, allowing compiler
+ * based tools to customise their own plugins
+ */
+ //TODO: add parameter annotations when KT-1863 is resolved
+ protected void configureEnvironment(@NotNull C configuration, @NotNull A arguments) {
+ List plugins = arguments.getCompilerPlugins();
+ configuration.getCompilerPlugins().addAll(plugins);
+ }
+
+ @NotNull
+ protected abstract A createArguments();
+
+ /**
+ * Executes the compiler on the parsed arguments
+ */
+ @NotNull
+ public ExitCode exec(final PrintStream errStream, A arguments) {
+ if (arguments.isHelp()) {
+ usage(errStream);
+ return OK;
+ }
+ System.setProperty("java.awt.headless", "true");
+ final MessageRenderer messageRenderer = getMessageRenderer(arguments);
+ errStream.print(messageRenderer.renderPreamble());
+ printVersionIfNeeded(errStream, arguments, messageRenderer);
+ try {
+ return doExecute(errStream, arguments, messageRenderer);
+ }
+ finally {
+ errStream.print(messageRenderer.renderConclusion());
+ }
+ }
+
+ //TODO: can't declare parameters as not null due to KT-1863
+ @NotNull
+ protected abstract ExitCode doExecute(PrintStream stream, A arguments, MessageRenderer renderer);
+
+ @NotNull
+ private MessageRenderer getMessageRenderer(@NotNull A arguments) {
+ return arguments.isTags() ? MessageRenderer.TAGS : MessageRenderer.PLAIN;
+ }
+
+ protected void printVersionIfNeeded(@NotNull PrintStream errStream,
+ @NotNull A arguments,
+ @NotNull MessageRenderer messageRenderer) {
+ if (arguments.isVersion()) {
+ String versionMessage = messageRenderer.render(CompilerMessageSeverity.INFO,
+ "Kotlin Compiler version " + CompilerVersion.VERSION,
+ CompilerMessageLocation.NO_LOCATION);
+ errStream.println(versionMessage);
+ }
+ }
+
+ /**
+ * Useful main for derived command line tools
+ */
+ public static void doMain(@NotNull CLICompiler compiler, @NotNull String[] args) {
+ try {
+ ExitCode rc = compiler.exec(System.out, args);
+ if (rc != OK) {
+ System.err.println("exec() finished with " + rc + " return code");
+ System.exit(rc.getCode());
+ }
+ }
+ catch (CompileEnvironmentException e) {
+ System.err.println(e.getMessage());
+ System.exit(INTERNAL_ERROR.getCode());
+ }
+ }
+}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentConfiguration.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CompileEnvironmentConfiguration.java
similarity index 59%
rename from compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentConfiguration.java
rename to compiler/cli/src/org/jetbrains/jet/cli/common/CompileEnvironmentConfiguration.java
index e95f3ba7186..525357b7efd 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentConfiguration.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CompileEnvironmentConfiguration.java
@@ -14,45 +14,32 @@
* limitations under the License.
*/
-package org.jetbrains.jet.cli.jvm.compiler;
+package org.jetbrains.jet.cli.common;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.cli.common.CompilerPlugin;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
-import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import java.util.List;
/**
- * @author abreslav
+ * @author Pavel Talanov
*/
-public class CompileEnvironmentConfiguration {
- private final JetCoreEnvironment environment;
- private final CompilerDependencies compilerDependencies;
- private final MessageCollector messageCollector;
+public abstract class CompileEnvironmentConfiguration {
- private List compilerPlugins = Lists.newArrayList();
+ @NotNull
+ private final MessageCollector messageCollector;
+ @NotNull
+ private final List compilerPlugins = Lists.newArrayList();
/**
* NOTE: It's very important to call dispose for every object of this class or there will be memory leaks.
+ *
* @see Disposer
*/
- public CompileEnvironmentConfiguration(@NotNull JetCoreEnvironment environment,
- @NotNull CompilerDependencies compilerDependencies, @NotNull MessageCollector messageCollector) {
+ public CompileEnvironmentConfiguration(@NotNull MessageCollector messageCollector) {
this.messageCollector = messageCollector;
- this.compilerDependencies = compilerDependencies;
- this.environment = environment;
- }
-
- public JetCoreEnvironment getEnvironment() {
- return environment;
- }
-
- @NotNull
- public CompilerDependencies getCompilerDependencies() {
- return compilerDependencies;
}
@NotNull
@@ -60,6 +47,7 @@ public class CompileEnvironmentConfiguration {
return messageCollector;
}
+ @NotNull
public List getCompilerPlugins() {
return compilerPlugins;
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerArguments.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerArguments.java
new file mode 100644
index 00000000000..ea12b40e35c
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerArguments.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.cli.common;
+
+import com.google.common.collect.Lists;
+import com.sampullara.cli.Argument;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Pavel Talanov
+ */
+public abstract class CompilerArguments {
+ @NotNull
+ private List compilerPlugins = Lists.newArrayList();
+
+ @NotNull
+ public List getCompilerPlugins() {
+ return compilerPlugins;
+ }
+
+ /**
+ * Sets the compiler plugins to be used when working with the {@link org.jetbrains.jet.cli.CLICompiler}
+ */
+ public void setCompilerPlugins(@NotNull List compilerPlugins) {
+ this.compilerPlugins = compilerPlugins;
+ }
+
+ public abstract boolean isHelp();
+ public abstract boolean isTags();
+ public abstract boolean isVersion();
+}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPlugin.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPlugin.java
index 8587929d80c..27a17b51f0c 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPlugin.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPlugin.java
@@ -16,10 +16,12 @@
package org.jetbrains.jet.cli.common;
+import org.jetbrains.annotations.NotNull;
+
/**
* A simple interface for compiler plugins to run after the compiler has finished such as for things like
* generating documentation or code generation etc
*/
public interface CompilerPlugin {
- void processFiles(CompilerPluginContext context);
+ void processFiles(@NotNull CompilerPluginContext context);
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPluginContext.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPluginContext.java
index 7716e3130ed..c42512800c8 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPluginContext.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerPluginContext.java
@@ -17,6 +17,7 @@
package org.jetbrains.jet.cli.common;
import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -27,8 +28,12 @@ import java.util.List;
* the {@link Project}, the {@link BindingContext} and the underlying {@link JetFile} files.
*/
public class CompilerPluginContext {
+ @NotNull
private final Project project;
+ //TODO: should we in fact store AnalyzeExhaust here?
+ @NotNull
private final BindingContext context;
+ @NotNull
private final List files;
public CompilerPluginContext(Project project, BindingContext context, List files) {
@@ -37,14 +42,17 @@ public class CompilerPluginContext {
this.files = files;
}
+ @NotNull
public BindingContext getContext() {
return context;
}
+ @NotNull
public List getFiles() {
return files;
}
+ @NotNull
public Project getProject() {
return project;
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompilerVersion.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerVersion.java
similarity index 91%
rename from compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompilerVersion.java
rename to compiler/cli/src/org/jetbrains/jet/cli/common/CompilerVersion.java
index 460d5c89493..98f1b3940e6 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompilerVersion.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CompilerVersion.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package org.jetbrains.jet.cli.jvm;
+package org.jetbrains.jet.cli.common;
/**
* @author abreslav
*/
-public class K2JVMCompilerVersion {
+public class CompilerVersion {
// The value of this constant is generated by the build script
// DON'T MODIFY IT
public static final String VERSION = "@snapshot@";
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/messages/MessageRenderer.java b/compiler/cli/src/org/jetbrains/jet/cli/common/messages/MessageRenderer.java
index 15eb3824455..1c266127a95 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/common/messages/MessageRenderer.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/common/messages/MessageRenderer.java
@@ -42,7 +42,7 @@ public interface MessageRenderer {
out.append(" line=\"").append(location.getLine()).append("\"");
out.append(" column=\"").append(location.getColumn()).append("\"");
}
- out.append(">\n");
+ out.append(">");
out.append(e(message));
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompileEnvironmentConfiguration.java b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompileEnvironmentConfiguration.java
new file mode 100644
index 00000000000..79d9f14567e
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompileEnvironmentConfiguration.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.cli.js;
+
+import com.intellij.openapi.util.Disposer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.cli.common.CompileEnvironmentConfiguration;
+import org.jetbrains.jet.cli.common.messages.MessageCollector;
+
+/**
+ * @author Pavel Talanov
+ */
+public class K2JSCompileEnvironmentConfiguration extends CompileEnvironmentConfiguration {
+ /**
+ * NOTE: It's very important to call dispose for every object of this class or there will be memory leaks.
+ *
+ * @see Disposer
+ */
+ public K2JSCompileEnvironmentConfiguration(@NotNull MessageCollector messageCollector) {
+ super(messageCollector);
+ }
+}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java
index 63d8e8fb778..c88a483958c 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java
@@ -16,12 +16,83 @@
package org.jetbrains.jet.cli.js;
+import com.google.common.base.Predicates;
+import com.intellij.openapi.Disposable;
+import com.intellij.psi.PsiFile;
+import jet.Function0;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.analyzer.AnalyzeExhaust;
+import org.jetbrains.jet.cli.common.CLICompiler;
+import org.jetbrains.jet.cli.common.ExitCode;
+import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport;
+import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
+import org.jetbrains.jet.cli.common.messages.MessageRenderer;
+import org.jetbrains.jet.cli.common.messages.PrintingMessageCollector;
+import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
+import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
+import org.jetbrains.jet.lang.psi.JetFile;
+import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
+import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS;
+import org.jetbrains.k2js.config.Config;
+
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.List;
+
+import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.NO_LOCATION;
+
/**
* @author Pavel Talanov
*/
-public final class K2JSCompiler {
+public class K2JSCompiler extends CLICompiler {
public static void main(String... args) {
- //TODO
+ doMain(new K2JSCompiler(), args);
+ }
+
+ @NotNull
+ @Override
+ protected K2JSCompilerArguments createArguments() {
+ return new K2JSCompilerArguments();
+ }
+
+
+ @NotNull
+ @Override
+ protected ExitCode doExecute(PrintStream stream, K2JSCompilerArguments arguments, MessageRenderer renderer) {
+ PrintingMessageCollector messageCollector = new PrintingMessageCollector(stream, renderer, true);
+ if (arguments.module != null) {
+ stream.print(renderer.render(CompilerMessageSeverity.ERROR, "Module arg is not supported", NO_LOCATION));
+ return ExitCode.INTERNAL_ERROR;
+ }
+
+ if (arguments.srcdir == null) {
+ stream.print(renderer.render(CompilerMessageSeverity.ERROR, "Specify sources location via -srcdir", NO_LOCATION));
+ return ExitCode.INTERNAL_ERROR;
+ }
+
+ Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
+ final JetCoreEnvironment environmentForJS = JetCoreEnvironment.getCoreEnvironmentForJS(rootDisposable);
+ environmentForJS.addSources(arguments.srcdir);
+ AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector);
+ final List sources = environmentForJS.getSourceFiles();
+ analyzerWithCompilerReport.analyzeAndReport(new Function0() {
+ @Override
+ public AnalyzeExhaust invoke() {
+ BindingContext context = AnalyzerFacadeForJS
+ .analyzeFiles(sources, Predicates.alwaysTrue(), new Config(environmentForJS.getProject()) {
+ @NotNull
+ @Override
+ protected List generateLibFiles() {
+ return Collections.emptyList();
+ }
+ });
+ return AnalyzeExhaust.success(context, JetStandardLibrary.getInstance());
+ }
+ }, sources);
+
+ stream.print(renderer.render(CompilerMessageSeverity.ERROR, "Greeting", NO_LOCATION));
+ return ExitCode.OK;
}
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java
index 46522696f05..75f0855d864 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompilerArguments.java
@@ -16,9 +16,46 @@
package org.jetbrains.jet.cli.js;
+import com.sampullara.cli.Argument;
+import org.jetbrains.jet.cli.common.CompilerArguments;
+
/**
* @author Pavel Talanov
*/
-//TODO
-public class K2JSCompilerArguments {
+public class K2JSCompilerArguments extends CompilerArguments {
+ @Argument(value = "output", description = "Output directory")
+ public String outputDir;
+
+ @Argument(value = "module", description = "Module to compile")
+ public String module;
+
+ @Argument(value = "srcdir", description = "Sources directory")
+ public String srcdir;
+
+ @Argument(value = "tags", description = "Demarcate each compilation message (error, warning, etc) with an open and close tag")
+ public boolean tags;
+
+ @Argument(value = "verbose", description = "Enable verbose logging output")
+ public boolean verbose;
+
+ @Argument(value = "version", description = "Display compiler version")
+ public boolean version;
+
+ @Argument(value = "help", alias = "h", description = "show help")
+ public boolean help;
+
+ @Override
+ public boolean isHelp() {
+ return help;
+ }
+
+ @Override
+ public boolean isTags() {
+ return tags;
+ }
+
+ @Override
+ public boolean isVersion() {
+ return version;
+ }
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java
index 007253e25e5..6cf5b743e6a 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java
@@ -20,15 +20,16 @@ import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
-import com.sampullara.cli.Args;
import jet.modules.Module;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.cli.common.CompilerPlugin;
+import org.jetbrains.jet.cli.common.CLICompiler;
import org.jetbrains.jet.cli.common.ExitCode;
-import org.jetbrains.jet.cli.common.messages.PrintingMessageCollector;
-import org.jetbrains.jet.codegen.CompilationException;
-import org.jetbrains.jet.cli.jvm.compiler.*;
import org.jetbrains.jet.cli.common.messages.*;
+import org.jetbrains.jet.cli.jvm.compiler.K2JVMCompileEnvironmentConfiguration;
+import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
+import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
+import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
+import org.jetbrains.jet.codegen.CompilationException;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.utils.PathUtil;
@@ -44,138 +45,101 @@ import static org.jetbrains.jet.cli.common.ExitCode.*;
* @author alex.tkachman
*/
@SuppressWarnings("UseOfSystemOutOrSystemErr")
-public class K2JVMCompiler {
+public class K2JVMCompiler extends CLICompiler {
public static void main(String... args) {
doMain(new K2JVMCompiler(), args);
}
- /**
- * Useful main for derived command line tools
- */
- public static void doMain(K2JVMCompiler compiler, String[] args) {
- try {
- ExitCode rc = compiler.exec(System.out, args);
- if (rc != OK) {
- System.err.println("exec() finished with " + rc + " return code");
- System.exit(rc.getCode());
+ @Override
+ @NotNull
+ protected ExitCode doExecute(PrintStream errStream,
+ K2JVMCompilerArguments arguments,
+ MessageRenderer messageRenderer) {
+
+ CompilerSpecialMode mode = parseCompilerSpecialMode(arguments);
+ File jdkHeadersJar;
+ if (mode.includeJdkHeaders()) {
+ if (arguments.jdkHeaders != null) {
+ jdkHeadersJar = new File(arguments.jdkHeaders);
+ }
+ else {
+ jdkHeadersJar = PathUtil.getAltHeadersPath();
}
}
- catch (CompileEnvironmentException e) {
- System.err.println(e.getMessage());
- System.exit(INTERNAL_ERROR.getCode());
+ else {
+ jdkHeadersJar = null;
}
- }
+ File runtimeJar;
- public ExitCode exec(PrintStream errStream, String... args) {
- K2JVMCompilerArguments arguments = createArguments();
- if (!parseArguments(errStream, arguments, args)) {
+ if (mode.includeKotlinRuntime()) {
+ if (arguments.stdlib != null) {
+ runtimeJar = new File(arguments.stdlib);
+ }
+ else {
+ runtimeJar = PathUtil.getDefaultRuntimePath();
+ }
+ }
+ else {
+ runtimeJar = null;
+ }
+
+ CompilerDependencies dependencies = new CompilerDependencies(mode, CompilerDependencies.findRtJar(), jdkHeadersJar, runtimeJar);
+ PrintingMessageCollector messageCollector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose);
+ Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
+
+ JetCoreEnvironment environment = JetCoreEnvironment.getCoreEnvironmentForJVM(rootDisposable, dependencies);
+ K2JVMCompileEnvironmentConfiguration configuration =
+ new K2JVMCompileEnvironmentConfiguration(environment, messageCollector);
+
+ messageCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment",
+ CompilerMessageLocation.NO_LOCATION);
+ try {
+ configureEnvironment(configuration, arguments);
+
+ boolean noErrors;
+ if (arguments.module != null) {
+ List modules = CompileEnvironmentUtil
+ .loadModuleScript(arguments.module, new PrintingMessageCollector(errStream, messageRenderer, false));
+ File directory = new File(arguments.module).getParentFile();
+ noErrors = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules,
+ directory, arguments.jar, arguments.outputDir,
+ arguments.includeRuntime);
+ }
+ else {
+ // TODO ideally we'd unify to just having a single field that supports multiple files/dirs
+ if (arguments.getSourceDirs() != null) {
+ noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSourceDirectories(configuration,
+ arguments.getSourceDirs(), arguments.jar,
+ arguments.outputDir,
+ arguments.includeRuntime);
+ }
+ else {
+ noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSources(configuration,
+ arguments.src, arguments.jar, arguments.outputDir,
+ arguments.includeRuntime);
+ }
+ }
+ return noErrors ? OK : COMPILATION_ERROR;
+ }
+ catch (CompilationException e) {
+ messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(e),
+ MessageUtil.psiElementToMessageLocation(e.getElement()));
return INTERNAL_ERROR;
}
- return exec(errStream, arguments);
- }
-
- /**
- * Executes the compiler on the parsed arguments
- */
- public ExitCode exec(final PrintStream errStream, K2JVMCompilerArguments arguments) {
- if (arguments.help) {
- usage(errStream);
- return OK;
- }
- System.setProperty("java.awt.headless", "true");
-
- final MessageRenderer messageRenderer = arguments.tags ? MessageRenderer.TAGS : MessageRenderer.PLAIN;
-
- errStream.print(messageRenderer.renderPreamble());
-
- try {
- if (arguments.version) {
- errStream.println(messageRenderer.render(CompilerMessageSeverity.INFO, "Kotlin Compiler version " + K2JVMCompilerVersion.VERSION, CompilerMessageLocation.NO_LOCATION));
- }
-
- CompilerSpecialMode mode = parseCompilerSpecialMode(arguments);
-
- File jdkHeadersJar;
- if (mode.includeJdkHeaders()) {
- if (arguments.jdkHeaders != null) {
- jdkHeadersJar = new File(arguments.jdkHeaders);
- }
- else {
- jdkHeadersJar = PathUtil.getAltHeadersPath();
- }
- }
- else {
- jdkHeadersJar = null;
- }
- File runtimeJar;
-
- if (mode.includeKotlinRuntime()) {
- if (arguments.stdlib != null) {
- runtimeJar = new File(arguments.stdlib);
- }
- else {
- runtimeJar = PathUtil.getDefaultRuntimePath();
- }
- }
- else {
- runtimeJar = null;
- }
-
- CompilerDependencies dependencies = new CompilerDependencies(mode, CompilerDependencies.findRtJar(), jdkHeadersJar, runtimeJar);
- PrintingMessageCollector messageCollector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose);
- Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
-
- JetCoreEnvironment environment = new JetCoreEnvironment(rootDisposable, dependencies);
- CompileEnvironmentConfiguration configuration = new CompileEnvironmentConfiguration(environment, dependencies, messageCollector);
-
- messageCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment",
+ catch (Throwable t) {
+ messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(t),
CompilerMessageLocation.NO_LOCATION);
- try {
- configureEnvironment(configuration, arguments);
-
- boolean noErrors;
- if (arguments.module != null) {
- List modules = CompileEnvironmentUtil.loadModuleScript(arguments.module, new PrintingMessageCollector(errStream, messageRenderer, false));
- File directory = new File(arguments.module).getParentFile();
- noErrors = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules,
- directory, arguments.jar, arguments.outputDir,
- arguments.includeRuntime);
- }
- else {
- // TODO ideally we'd unify to just having a single field that supports multiple files/dirs
- if (arguments.getSourceDirs() != null) {
- noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSourceDirectories(configuration,
- arguments.getSourceDirs(), arguments.jar, arguments.outputDir, arguments.includeRuntime);
- }
- else {
- noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSources(configuration,
- arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime);
- }
- }
- return noErrors ? OK : COMPILATION_ERROR;
- }
- catch (CompilationException e) {
- messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(e),
- MessageUtil.psiElementToMessageLocation(e.getElement()));
- return INTERNAL_ERROR;
- }
- catch (Throwable t) {
- messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(t), CompilerMessageLocation.NO_LOCATION);
- return INTERNAL_ERROR;
- }
- finally {
- Disposer.dispose(rootDisposable);
- messageCollector.printToErrStream();
- }
+ return INTERNAL_ERROR;
}
finally {
- errStream.print(messageRenderer.renderConclusion());
+ Disposer.dispose(rootDisposable);
+ messageCollector.printToErrStream();
}
}
@NotNull
- private CompilerSpecialMode parseCompilerSpecialMode(@NotNull K2JVMCompilerArguments arguments) {
+ private static CompilerSpecialMode parseCompilerSpecialMode(@NotNull K2JVMCompilerArguments arguments) {
if (arguments.mode == null) {
return CompilerSpecialMode.REGULAR;
}
@@ -190,65 +154,37 @@ public class K2JVMCompiler {
throw new IllegalArgumentException("unknown compiler mode: " + arguments.mode);
}
- /**
- * Returns true if the arguments can be parsed correctly
- */
- protected boolean parseArguments(PrintStream errStream, K2JVMCompilerArguments arguments, String[] args) {
- try {
- Args.parse(arguments, args);
- return true;
- }
- catch (IllegalArgumentException e) {
- usage(errStream);
- }
- catch (Throwable t) {
- // Always use tags
- errStream.println(MessageRenderer.TAGS.renderException(t));
- }
- return false;
- }
-
- protected void usage(PrintStream target) {
- // We should say something like
- // Args.usage(target, K2JVMCompilerArguments.class);
- // but currently cli-parser we are using does not support that
- // a corresponding patch has been sent to the authors
- // For now, we are using this:
-
- PrintStream oldErr = System.err;
- System.setErr(target);
- try {
- // TODO: use proper argv0
- Args.usage(new K2JVMCompilerArguments());
- } finally {
- System.setErr(oldErr);
- }
- }
/**
* Allow derived classes to add additional command line arguments
*/
+ @NotNull
+ @Override
protected K2JVMCompilerArguments createArguments() {
return new K2JVMCompilerArguments();
}
- /**
- * Strategy method to configure the environment, allowing compiler
- * based tools to customise their own plugins
- */
- protected void configureEnvironment(CompileEnvironmentConfiguration configuration, K2JVMCompilerArguments arguments) {
- // install any compiler plugins
- List plugins = arguments.getCompilerPlugins();
- if (plugins != null) {
- configuration.getCompilerPlugins().addAll(plugins);
- }
+ //TODO: Hacked! Be sure that our kotlin stuff builds correctly before you remove.
+ // our compiler throws method not found error
+ // probably relates to KT-1863... well, may be not
+ @NotNull
+ @Override
+ public ExitCode exec(PrintStream errStream, K2JVMCompilerArguments arguments) {
+ return super.exec(errStream, arguments);
+ }
- if (configuration.getCompilerDependencies().getRuntimeJar() != null) {
- CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(), configuration.getCompilerDependencies().getRuntimeJar());
+
+ @Override
+ protected void configureEnvironment(@NotNull K2JVMCompileEnvironmentConfiguration configuration, @NotNull K2JVMCompilerArguments arguments) {
+ super.configureEnvironment(configuration, arguments);
+
+ if (configuration.getEnvironment().getCompilerDependencies().getRuntimeJar() != null) {
+ CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(),
+ configuration.getEnvironment().getCompilerDependencies().getRuntimeJar());
}
if (arguments.classpath != null) {
- final Iterable classpath = Splitter.on(File.pathSeparatorChar).split(arguments.classpath);
+ Iterable classpath = Splitter.on(File.pathSeparatorChar).split(arguments.classpath);
CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(), Iterables.toArray(classpath, String.class));
}
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompilerArguments.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompilerArguments.java
index bed558b5f08..761c2d8bd3e 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompilerArguments.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompilerArguments.java
@@ -18,16 +18,15 @@
package org.jetbrains.jet.cli.jvm;
import com.sampullara.cli.Argument;
-import org.jetbrains.jet.cli.common.CompilerPlugin;
+import org.jetbrains.jet.cli.common.CompilerArguments;
-import java.util.ArrayList;
import java.util.List;
/**
* Command line arguments for the {@link K2JVMCompiler}
*/
-public class K2JVMCompilerArguments {
- private List compilerPlugins = new ArrayList();
+public class K2JVMCompilerArguments extends CompilerArguments {
+
// TODO ideally we'd unify this with 'src' to just having a single field that supports multiple files/dirs
private List sourceDirs;
@@ -40,18 +39,12 @@ public class K2JVMCompilerArguments {
this.sourceDirs = sourceDirs;
}
- @Argument(value = "output", description = "output directory")
- public String outputDir;
-
@Argument(value = "jar", description = "jar file name")
public String jar;
@Argument(value = "src", description = "source file or directory")
public String src;
- @Argument(value = "module", description = "module to compile")
- public String module;
-
@Argument(value = "classpath", description = "classpath to use when compiling")
public String classpath;
@@ -64,12 +57,15 @@ public class K2JVMCompilerArguments {
@Argument(value = "jdkHeaders", description = "Path to the kotlin-jdk-headers.jar")
public String jdkHeaders;
- @Argument(value = "help", alias = "h", description = "show help")
- public boolean help;
-
@Argument(value = "mode", description = "Special compiler modes: stubs or jdkHeaders")
public String mode;
+ @Argument(value = "output", description = "output directory")
+ public String outputDir;
+
+ @Argument(value = "module", description = "module to compile")
+ public String module;
+
@Argument(value = "tags", description = "Demarcate each compilation message (error, warning, etc) with an open and close tag")
public boolean tags;
@@ -79,6 +75,8 @@ public class K2JVMCompilerArguments {
@Argument(value = "version", description = "Display compiler version")
public boolean version;
+ @Argument(value = "help", alias = "h", description = "show help")
+ public boolean help;
public String getClasspath() {
return classpath;
@@ -88,6 +86,7 @@ public class K2JVMCompilerArguments {
this.classpath = classpath;
}
+ @Override
public boolean isHelp() {
return help;
}
@@ -144,22 +143,17 @@ public class K2JVMCompilerArguments {
this.stdlib = stdlib;
}
+ @Override
public boolean isTags() {
return tags;
}
+ @Override
+ public boolean isVersion() {
+ return version;
+ }
+
public void setTags(boolean tags) {
this.tags = tags;
}
-
- public List getCompilerPlugins() {
- return compilerPlugins;
- }
-
- /**
- * Sets the compiler plugins to be used when working with the {@link K2JVMCompiler}
- */
- public void setCompilerPlugins(List compilerPlugins) {
- this.compilerPlugins = compilerPlugins;
- }
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java
index 344fa99cd59..448ffd76bbb 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java
@@ -24,6 +24,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Processor;
import jet.modules.AllModules;
import jet.modules.Module;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
import org.jetbrains.jet.codegen.ClassFileFactory;
@@ -61,7 +62,7 @@ public class CompileEnvironmentUtil {
@Nullable
public static File getUnpackedRuntimePath() {
- URL url = CompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
+ URL url = K2JVMCompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
if (url != null && url.getProtocol().equals("file")) {
return new File(url.getPath()).getParentFile().getParentFile();
}
@@ -70,7 +71,7 @@ public class CompileEnvironmentUtil {
@Nullable
public static File getRuntimeJarPath() {
- URL url = CompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
+ URL url = K2JVMCompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
if (url != null && url.getProtocol().equals("jar")) {
String path = url.getPath();
return new File(path.substring(path.indexOf(":") + 1, path.indexOf("!/")));
@@ -157,12 +158,12 @@ public class CompileEnvironmentUtil {
}
};
CompilerDependencies dependencies = CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.REGULAR);
- JetCoreEnvironment scriptEnvironment = new JetCoreEnvironment(disposable, dependencies);
+ JetCoreEnvironment scriptEnvironment = JetCoreEnvironment.getCoreEnvironmentForJVM(disposable, dependencies);
ensureRuntime(scriptEnvironment, dependencies);
scriptEnvironment.addSources(moduleScriptFile);
GenerationState generationState = KotlinToJVMBytecodeCompiler
- .analyzeAndGenerate(new CompileEnvironmentConfiguration(scriptEnvironment, dependencies, messageCollector), false);
+ .analyzeAndGenerate(new K2JVMCompileEnvironmentConfiguration(scriptEnvironment, messageCollector), false);
if (generationState == null) {
return null;
}
@@ -194,7 +195,7 @@ public class CompileEnvironmentUtil {
}
}
else {
- loader = new GeneratedClassLoader(factory, CompileEnvironmentConfiguration.class.getClassLoader());
+ loader = new GeneratedClassLoader(factory, K2JVMCompileEnvironmentConfiguration.class.getClassLoader());
}
try {
Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS);
@@ -337,4 +338,21 @@ public class CompileEnvironmentUtil {
addToClasspath(environment, new File(path));
}
}
+
+ public static void addSourcesFromModuleToEnvironment(@NotNull JetCoreEnvironment environment,
+ @NotNull Module module,
+ @NotNull File moduleDirectory) {
+ for (String sourceFile : module.getSourceFiles()) {
+ File source = new File(sourceFile);
+ if (!source.isAbsolute()) {
+ source = new File(moduleDirectory, sourceFile);
+ }
+
+ if (!source.exists()) {
+ throw new CompileEnvironmentException("'" + source + "' does not exist");
+ }
+
+ environment.addSources(source.getPath());
+ }
+ }
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java
index 14e5111f06b..fafde19fca9 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java
@@ -47,8 +47,24 @@ import java.util.List;
public class JetCoreEnvironment extends JavaCoreEnvironment {
private final List sourceFiles = new ArrayList();
+ @NotNull
+ public static JetCoreEnvironment getCoreEnvironmentForJS(Disposable disposable) {
+ return new JetCoreEnvironment(disposable, CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.JS));
+ }
+
+ @NotNull
+ public static JetCoreEnvironment getCoreEnvironmentForJVM(Disposable disposable, @NotNull CompilerDependencies dependencies) {
+ return new JetCoreEnvironment(disposable, dependencies);
+ }
+
+ @NotNull
+ private final CompilerDependencies compilerDependencies;
+
public JetCoreEnvironment(Disposable parentDisposable, @NotNull CompilerDependencies compilerDependencies) {
super(parentDisposable);
+
+ this.compilerDependencies = compilerDependencies;
+
registerFileType(JetFileType.INSTANCE, "kt");
registerFileType(JetFileType.INSTANCE, "kts");
registerFileType(JetFileType.INSTANCE, "ktm");
@@ -72,9 +88,7 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
}
}
if (compilerSpecialMode.includeKotlinRuntime()) {
- for (VirtualFile root : compilerDependencies.getRuntimeRoots()) {
- addLibraryRoot(root);
- }
+ addToClasspath(compilerDependencies.getRuntimeJar());
}
JetStandardLibrary.initialize(getProject());
@@ -85,7 +99,7 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
}
private void addSources(File file) {
- if(file.isDirectory()) {
+ if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File child : files) {
@@ -97,15 +111,15 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
VirtualFile fileByPath = getLocalFileSystem().findFileByPath(file.getAbsolutePath());
if (fileByPath != null) {
PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(fileByPath);
- if(psiFile instanceof JetFile) {
- sourceFiles.add((JetFile)psiFile);
+ if (psiFile instanceof JetFile) {
+ sourceFiles.add((JetFile) psiFile);
}
}
}
}
public void addSources(VirtualFile vFile) {
- if (vFile.isDirectory()) {
+ if (vFile.isDirectory()) {
for (VirtualFile virtualFile : vFile.getChildren()) {
addSources(virtualFile);
}
@@ -114,15 +128,16 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
if (vFile.getFileType() == JetFileType.INSTANCE) {
PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(vFile);
if (psiFile instanceof JetFile) {
- sourceFiles.add((JetFile)psiFile);
+ sourceFiles.add((JetFile) psiFile);
}
}
}
}
public void addSources(String path) {
- if(path == null)
+ if (path == null) {
return;
+ }
VirtualFile vFile = getLocalFileSystem().findFileByPath(path);
if (vFile == null) {
@@ -141,15 +156,22 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
public void addToClasspathFromClassLoader(ClassLoader loader) {
ClassLoader parent = loader.getParent();
- if(parent != null)
+ if (parent != null) {
addToClasspathFromClassLoader(parent);
+ }
- if(loader instanceof URLClassLoader) {
+ if (loader instanceof URLClassLoader) {
for (URL url : ((URLClassLoader) loader).getURLs()) {
File file = new File(url.getPath());
- if(file.exists() && (!file.isFile() || file.getPath().endsWith(".jar")))
+ if (file.exists() && (!file.isFile() || file.getPath().endsWith(".jar"))) {
addToClasspath(file);
+ }
}
}
}
+
+ @NotNull
+ public CompilerDependencies getCompilerDependencies() {
+ return compilerDependencies;
+ }
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/K2JVMCompileEnvironmentConfiguration.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/K2JVMCompileEnvironmentConfiguration.java
new file mode 100644
index 00000000000..97dc704fd99
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/K2JVMCompileEnvironmentConfiguration.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.cli.jvm.compiler;
+
+import com.intellij.openapi.util.Disposer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.cli.common.CompileEnvironmentConfiguration;
+import org.jetbrains.jet.cli.common.messages.MessageCollector;
+
+/**
+ * @author abreslav
+ */
+public class K2JVMCompileEnvironmentConfiguration extends CompileEnvironmentConfiguration {
+ private final JetCoreEnvironment environment;
+
+ /**
+ * NOTE: It's very important to call dispose for every object of this class or there will be memory leaks.
+ *
+ * @see Disposer
+ */
+ public K2JVMCompileEnvironmentConfiguration(@NotNull JetCoreEnvironment environment,
+ @NotNull MessageCollector messageCollector) {
+ super(messageCollector);
+ this.environment = environment;
+ }
+
+ public JetCoreEnvironment getEnvironment() {
+ return environment;
+ }
+}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java
index af98cf42dc6..2605ad66056 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java
@@ -59,7 +59,7 @@ public class KotlinToJVMBytecodeCompiler {
@Nullable
public static ClassFileFactory compileModule(
- CompileEnvironmentConfiguration configuration,
+ K2JVMCompileEnvironmentConfiguration configuration,
Module moduleBuilder,
File directory
) {
@@ -67,23 +67,12 @@ public class KotlinToJVMBytecodeCompiler {
throw new CompileEnvironmentException("No source files where defined");
}
- for (String sourceFile : moduleBuilder.getSourceFiles()) {
- File source = new File(sourceFile);
- if (!source.isAbsolute()) {
- source = new File(directory, sourceFile);
- }
-
- if (!source.exists()) {
- throw new CompileEnvironmentException("'" + source + "' does not exist");
- }
-
- configuration.getEnvironment().addSources(source.getPath());
- }
+ CompileEnvironmentUtil.addSourcesFromModuleToEnvironment(configuration.getEnvironment(), moduleBuilder, directory);
for (String classpathRoot : moduleBuilder.getClasspathRoots()) {
configuration.getEnvironment().addToClasspath(new File(classpathRoot));
}
- CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getCompilerDependencies());
+ CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getEnvironment().getCompilerDependencies());
GenerationState generationState = analyzeAndGenerate(configuration);
if (generationState == null) {
@@ -93,7 +82,7 @@ public class KotlinToJVMBytecodeCompiler {
}
public static boolean compileModules(
- CompileEnvironmentConfiguration configuration,
+ K2JVMCompileEnvironmentConfiguration configuration,
@NotNull List modules,
@@ -104,9 +93,9 @@ public class KotlinToJVMBytecodeCompiler {
for (Module moduleBuilder : modules) {
// TODO: this should be done only once for the environment
- if (configuration.getCompilerDependencies().getRuntimeJar() != null) {
+ if (configuration.getEnvironment().getCompilerDependencies().getRuntimeJar() != null) {
CompileEnvironmentUtil
- .addToClasspath(configuration.getEnvironment(), configuration.getCompilerDependencies().getRuntimeJar());
+ .addToClasspath(configuration.getEnvironment(), configuration.getEnvironment().getCompilerDependencies().getRuntimeJar());
}
ClassFileFactory moduleFactory = compileModule(configuration, moduleBuilder, directory);
if (moduleFactory == null) {
@@ -129,7 +118,7 @@ public class KotlinToJVMBytecodeCompiler {
}
private static boolean compileBunchOfSources(
- CompileEnvironmentConfiguration configuration,
+ K2JVMCompileEnvironmentConfiguration configuration,
String jar,
String outputDir,
boolean includeRuntime
@@ -143,7 +132,7 @@ public class KotlinToJVMBytecodeCompiler {
}
}
- CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getCompilerDependencies());
+ CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getEnvironment().getCompilerDependencies());
GenerationState generationState = analyzeAndGenerate(configuration);
if (generationState == null) {
@@ -174,7 +163,7 @@ public class KotlinToJVMBytecodeCompiler {
}
public static boolean compileBunchOfSources(
- CompileEnvironmentConfiguration configuration,
+ K2JVMCompileEnvironmentConfiguration configuration,
String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
configuration.getEnvironment().addSources(sourceFileOrDir);
@@ -183,7 +172,7 @@ public class KotlinToJVMBytecodeCompiler {
}
public static boolean compileBunchOfSourceDirectories(
- CompileEnvironmentConfiguration configuration,
+ K2JVMCompileEnvironmentConfiguration configuration,
List sources, String jar, String outputDir, boolean includeRuntime) {
for (String source : sources) {
@@ -195,7 +184,7 @@ public class KotlinToJVMBytecodeCompiler {
@Nullable
public static ClassLoader compileText(
- CompileEnvironmentConfiguration configuration,
+ K2JVMCompileEnvironmentConfiguration configuration,
String code) {
configuration.getEnvironment()
.addSources(new LightVirtualFile("script" + LocalTimeCounter.currentTime() + ".kt", JetLanguage.INSTANCE, code));
@@ -208,13 +197,13 @@ public class KotlinToJVMBytecodeCompiler {
}
@Nullable
- public static GenerationState analyzeAndGenerate(CompileEnvironmentConfiguration configuration) {
- return analyzeAndGenerate(configuration, configuration.getCompilerDependencies().getCompilerSpecialMode().isStubs());
+ public static GenerationState analyzeAndGenerate(K2JVMCompileEnvironmentConfiguration configuration) {
+ return analyzeAndGenerate(configuration, configuration.getEnvironment().getCompilerDependencies().getCompilerSpecialMode().isStubs());
}
@Nullable
public static GenerationState analyzeAndGenerate(
- CompileEnvironmentConfiguration configuration,
+ K2JVMCompileEnvironmentConfiguration configuration,
boolean stubs
) {
AnalyzeExhaust exhaust = analyze(configuration, stubs);
@@ -230,7 +219,7 @@ public class KotlinToJVMBytecodeCompiler {
@Nullable
private static AnalyzeExhaust analyze(
- final CompileEnvironmentConfiguration configuration,
+ final K2JVMCompileEnvironmentConfiguration configuration,
boolean stubs) {
final JetCoreEnvironment environment = configuration.getEnvironment();
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(configuration.getMessageCollector());
@@ -244,7 +233,7 @@ public class KotlinToJVMBytecodeCompiler {
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory.EMPTY,
- configuration.getCompilerDependencies());
+ configuration.getEnvironment().getCompilerDependencies());
}
}, environment.getSourceFiles()
);
@@ -254,7 +243,7 @@ public class KotlinToJVMBytecodeCompiler {
@NotNull
private static GenerationState generate(
- final CompileEnvironmentConfiguration configuration,
+ final K2JVMCompileEnvironmentConfiguration configuration,
AnalyzeExhaust exhaust,
boolean stubs) {
JetCoreEnvironment environment = configuration.getEnvironment();
@@ -267,7 +256,7 @@ public class KotlinToJVMBytecodeCompiler {
};
GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs), backendProgress,
exhaust, environment.getSourceFiles(),
- configuration.getCompilerDependencies().getCompilerSpecialMode());
+ configuration.getEnvironment().getCompilerDependencies().getCompilerSpecialMode());
generationState.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
List plugins = configuration.getCompilerPlugins();
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java
index a92c9abb47f..032682e5bbc 100644
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/CompilerSpecialMode.java
@@ -24,6 +24,7 @@ public enum CompilerSpecialMode {
BUILTINS,
JDK_HEADERS,
STDLIB,
+ JS
;
public boolean includeJdkHeaders() {
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java
index 556323eed38..8844466d01e 100644
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java
@@ -92,11 +92,7 @@ import org.jetbrains.jet.lang.resolve.constants.NullValue;
import org.jetbrains.jet.lang.resolve.constants.ShortValue;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
-import org.jetbrains.jet.lang.types.ErrorUtils;
-import org.jetbrains.jet.lang.types.JetType;
-import org.jetbrains.jet.lang.types.TypeSubstitutor;
-import org.jetbrains.jet.lang.types.TypeUtils;
-import org.jetbrains.jet.lang.types.Variance;
+import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
@@ -222,14 +218,14 @@ public class JavaDescriptorResolver {
throw new IllegalStateException("both psiClass and psiPackage cannot be null");
}
- if (fqName.lastSegmentIs(JvmAbi.PACKAGE_CLASS)) {
- throw new IllegalStateException("identified cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName);
- }
-
this.staticMembers = staticMembers;
this.kotlin = psiClass != null &&
(new PsiClassWrapper(psiClass).getJetClass().isDefined() || psiClass.getName().equals(JvmAbi.PACKAGE_CLASS));
classOrNamespaceDescriptor = descriptor;
+
+ if (fqName.lastSegmentIs(JvmAbi.PACKAGE_CLASS) && psiClass != null && kotlin) {
+ throw new IllegalStateException("Kotlin namespace cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName);
+ }
}
protected ResolverScopeData(boolean negative) {
@@ -356,6 +352,15 @@ public class JavaDescriptorResolver {
+ @Nullable
+ private ClassDescriptor resolveJavaLangObject() {
+ ClassDescriptor clazz = resolveClass(JdkNames.JL_OBJECT.getFqName(), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
+ if (clazz == null) {
+ // TODO: warning
+ }
+ return clazz;
+ }
+
@Nullable
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
List tasks = Lists.newArrayList();
@@ -466,7 +471,7 @@ public class JavaDescriptorResolver {
"class " + psiClass.getQualifiedName());
// TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
- supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData.classDescriptor, classData.getTypeParameters()));
+ supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData, classData.getTypeParameters()));
PsiMethod[] psiConstructors = psiClass.getConstructors();
@@ -530,28 +535,7 @@ public class JavaDescriptorResolver {
}
else {
for (PsiMethod psiConstructor : psiConstructors) {
- PsiMethodWrapper constructor = new PsiMethodWrapper(psiConstructor);
-
- if (constructor.getJetConstructor().hidden()) {
- continue;
- }
-
- ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
- classData.classDescriptor,
- Collections.emptyList(), // TODO
- false);
- String context = "constructor of class " + psiClass.getQualifiedName();
- ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
- constructor.getParameters(),
- TypeVariableResolvers.classTypeVariableResolver(classData.classDescriptor, context));
- if (valueParameterDescriptors.receiverType != null) {
- throw new IllegalStateException();
- }
- constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors,
- resolveVisibilityFromPsiModifiers(psiConstructor), isStatic);
- constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
- classData.classDescriptor.addConstructor(constructorDescriptor, null);
- trace.record(BindingContext.CONSTRUCTOR, psiConstructor, constructorDescriptor);
+ resolveConstructor(psiClass, classData, isStatic, psiConstructor);
}
}
@@ -565,6 +549,32 @@ public class JavaDescriptorResolver {
return classData;
}
+ private void resolveConstructor(PsiClass psiClass, ResolverBinaryClassData classData, boolean aStatic, PsiMethod psiConstructor) {
+ PsiMethodWrapper constructor = new PsiMethodWrapper(psiConstructor);
+
+ if (constructor.getJetConstructor().hidden()) {
+ return;
+ }
+
+ ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
+ classData.classDescriptor,
+ Collections.emptyList(), // TODO
+ false);
+ String context = "constructor of class " + psiClass.getQualifiedName();
+ ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
+ constructor.getParameters(),
+ TypeVariableResolvers.classTypeVariableResolver(classData.classDescriptor, context));
+ if (valueParameterDescriptors.receiverType != null) {
+ throw new IllegalStateException();
+ }
+ constructorDescriptor.initialize(classData.classDescriptor.getTypeConstructor().getParameters(),
+ valueParameterDescriptors.descriptors,
+ resolveVisibilityFromPsiModifiers(psiConstructor), aStatic);
+ constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
+ classData.classDescriptor.addConstructor(constructorDescriptor, null);
+ trace.record(BindingContext.CONSTRUCTOR, psiConstructor, constructorDescriptor);
+ }
+
static void checkPsiClassIsNotJet(PsiClass psiClass) {
if (psiClass instanceof JetJavaMirrorMarker) {
throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName());
@@ -599,7 +609,7 @@ public class JavaDescriptorResolver {
classDescriptorCache.put(fqName, classData);
- classData.classDescriptor.setSupertypes(getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData.classDescriptor, new ArrayList(0)));
+ classData.classDescriptor.setSupertypes(getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData, new ArrayList(0)));
classData.classDescriptor.setName(JetPsiUtil.NO_NAME_PROVIDED); // TODO
classData.classDescriptor.setModality(Modality.FINAL);
classData.classDescriptor.setVisibility(containing.getVisibility());
@@ -855,14 +865,22 @@ public class JavaDescriptorResolver {
private void initializeTypeParameters(List typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) {
List prevTypeParameters = new ArrayList();
+
+ List typeParameters = Lists.newArrayList();
+ for (TypeParameterDescriptorInitialization typeParameterDescriptor : typeParametersInitialization) {
+ typeParameters.add(typeParameterDescriptor.descriptor);
+ }
+
for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) {
prevTypeParameters.add(psiTypeParameter.descriptor);
initializeTypeParameter(psiTypeParameter,
- TypeVariableResolvers.typeVariableResolverFromTypeParameters(prevTypeParameters, typeParametersOwner, context));
+ TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, typeParametersOwner, context));
}
}
- private Collection getSupertypes(PsiClassWrapper psiClass, ClassDescriptor classDescriptor, List typeParameters) {
+ private Collection getSupertypes(PsiClassWrapper psiClass, ResolverBinaryClassData classData, List typeParameters) {
+ ClassDescriptor classDescriptor = classData.classDescriptor;
+
final List result = new ArrayList();
String context = "class " + psiClass.getQualifiedName();
@@ -908,7 +926,21 @@ public class JavaDescriptorResolver {
}
if (result.isEmpty()) {
- result.add(JetStandardClasses.getAnyType());
+ if (classData.kotlin
+ || psiClass.getQualifiedName().equals(JdkNames.JL_OBJECT.getFqName().getFqName())
+ // TODO: annotations
+ || classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
+ result.add(JetStandardClasses.getAnyType());
+ }
+ else {
+ ClassDescriptor object = resolveJavaLangObject();
+ if (object != null) {
+ result.add(object.getDefaultType());
+ }
+ else {
+ result.add(JetStandardClasses.getAnyType());
+ }
+ }
}
return result;
}
@@ -923,7 +955,7 @@ public class JavaDescriptorResolver {
continue;
}
- JetType transform = semanticServices.getTypeTransformer().transformToType(type, typeVariableResolver);
+ JetType transform = semanticServices.getTypeTransformer().transformToType(type, JavaTypeTransformer.TypeUsage.SUPERTYPE, typeVariableResolver);
result.add(TypeUtils.makeNotNullable(transform));
}
@@ -1120,7 +1152,7 @@ public class JavaDescriptorResolver {
JetType varargElementType;
if (psiType instanceof PsiEllipsisType) {
- varargElementType = JetStandardLibrary.getInstance().getArrayElementType(outType);
+ varargElementType = JetStandardLibrary.getInstance().getArrayElementType(TypeUtils.makeNotNullable(outType));
}
else {
varargElementType = null;
@@ -1239,8 +1271,6 @@ public class JavaDescriptorResolver {
namedMembers.propertyAccessors = Collections.emptyList();
}
- TypeVariableResolver typeVariableResolver = TypeVariableResolvers.classTypeVariableResolver(owner, context);
-
class GroupingValue {
PropertyAccessorData getter;
PropertyAccessorData setter;
@@ -1381,14 +1411,14 @@ public class JavaDescriptorResolver {
PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember();
if (anyMember == members.setter) {
- typeParameters = resolveMethodTypeParameters(method, propertyDescriptor, typeVariableResolver);
+ typeParameters = resolveMethodTypeParameters(method, propertyDescriptor);
}
}
if (members.getter != null) {
PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember();
if (anyMember == members.getter) {
- typeParameters = resolveMethodTypeParameters(method, propertyDescriptor, typeVariableResolver);
+ typeParameters = resolveMethodTypeParameters(method, propertyDescriptor);
}
}
@@ -1549,7 +1579,7 @@ public class JavaDescriptorResolver {
private TypeSubstitutor createSubstitutorForGenericSupertypes(@Nullable ClassDescriptor classDescriptor) {
TypeSubstitutor typeSubstitutor;
if (classDescriptor != null) {
- typeSubstitutor = TypeUtils.buildDeepSubstitutor(classDescriptor.getDefaultType());
+ typeSubstitutor = SubstitutionUtils.buildDeepSubstitutor(classDescriptor.getDefaultType());
}
else {
typeSubstitutor = TypeSubstitutor.EMPTY;
@@ -1617,9 +1647,7 @@ public class JavaDescriptorResolver {
String context = "method " + method.getName() + " in class " + psiClass.getQualifiedName();
- final TypeVariableResolver typeVariableResolverForParameters = TypeVariableResolvers.classTypeVariableResolver(scopeData.classOrNamespaceDescriptor, context);
-
- final List methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters);
+ final List methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl);
TypeVariableResolver methodTypeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(methodTypeParameters, functionDescriptorImpl, context);
@@ -1760,8 +1788,7 @@ public class JavaDescriptorResolver {
private List resolveMethodTypeParameters(
@NotNull PsiMethodWrapper method,
- @NotNull DeclarationDescriptor functionDescriptor,
- @NotNull TypeVariableResolver classTypeVariableResolver) {
+ @NotNull DeclarationDescriptor functionDescriptor) {
List typeParametersIntialization;
if (method.getJetMethod().typeParameters().length() > 0) {
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java
index d005ef30040..9afa41e38ff 100644
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -25,16 +26,16 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.types.*;
+import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
import org.jetbrains.jet.rt.signature.JetSignatureReader;
import javax.inject.Inject;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+
+import static org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer.TypeUsage.*;
/**
* @author abreslav
@@ -63,9 +64,11 @@ public class JavaTypeTransformer {
@NotNull
- public TypeProjection transformToTypeProjection(@NotNull final PsiType javaType,
+ private TypeProjection transformToTypeProjection(@NotNull final PsiType javaType,
@NotNull final TypeParameterDescriptor typeParameterDescriptor,
- @NotNull final TypeVariableResolver typeVariableByPsiResolver) {
+ @NotNull final TypeVariableResolver typeVariableByPsiResolver,
+ @NotNull final TypeUsage howThisTypeIsUsed
+ ) {
TypeProjection result = javaType.accept(new PsiTypeVisitor() {
@Override
@@ -76,18 +79,18 @@ public class JavaTypeTransformer {
@Override
public TypeProjection visitWildcardType(PsiWildcardType wildcardType) {
if (!wildcardType.isBounded()) {
- return TypeUtils.makeStarProjection(typeParameterDescriptor);
+ return SubstitutionUtils.makeStarProjection(typeParameterDescriptor);
}
Variance variance = wildcardType.isExtends() ? Variance.OUT_VARIANCE : Variance.IN_VARIANCE;
PsiType bound = wildcardType.getBound();
assert bound != null;
- return new TypeProjection(variance, transformToType(bound, TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
+ return new TypeProjection(variance, transformToType(bound, UPPER_BOUND, typeVariableByPsiResolver));
}
@Override
public TypeProjection visitType(PsiType type) {
- return new TypeProjection(transformToType(type, TypeUsage.TYPE_ARGUMENT, typeVariableByPsiResolver));
+ return new TypeProjection(transformToType(type, howThisTypeIsUsed, typeVariableByPsiResolver));
}
});
return result;
@@ -126,22 +129,39 @@ public class JavaTypeTransformer {
if (psiClass instanceof PsiTypeParameter) {
PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass;
+
+ PsiTypeParameterListOwner typeParameterListOwner = typeParameter.getOwner();
+ if (typeParameterListOwner instanceof PsiMethod) {
+ PsiMethod psiMethod = (PsiMethod) typeParameterListOwner;
+ if (psiMethod.isConstructor()) {
+ Set supertypesJet = Sets.newHashSet();
+ for (PsiClassType supertype : typeParameter.getExtendsListTypes()) {
+ supertypesJet.add(transformToType(supertype, UPPER_BOUND, typeVariableResolver));
+ }
+ return TypeUtils.intersect(JetTypeChecker.INSTANCE, supertypesJet);
+ }
+ }
+
TypeParameterDescriptor typeParameterDescriptor = typeVariableResolver.getTypeVariable(typeParameter.getName());
- if (howThisTypeIsUsed == TypeUsage.TYPE_ARGUMENT || howThisTypeIsUsed == TypeUsage.UPPER_BOUND) {
- // In Java: ArrayList
- // In Kotlin: ArrayList, not ArrayList
- // nullability will be taken care of in individual member signatures
- return typeParameterDescriptor.getDefaultType();
+ // In Java: ArrayList
+ // In Kotlin: ArrayList, not ArrayList
+ // nullability will be taken care of in individual member signatures
+ boolean nullable = !EnumSet.of(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT).contains(howThisTypeIsUsed);
+ if (nullable) {
+ return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
}
else {
- return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
+ return typeParameterDescriptor.getDefaultType();
}
}
else {
+ // 'L extends List' in Java is a List in Kotlin, not a List
+ boolean nullable = !EnumSet.of(SUPERTYPE_ARGUMENT, SUPERTYPE).contains(howThisTypeIsUsed);
+
JetType jetAnalog = getKotlinAnalog(new FqName(psiClass.getQualifiedName()));
if (jetAnalog != null) {
- return jetAnalog;
+ return TypeUtils.makeNullableAsSpecified(jetAnalog, nullable);
}
final ClassDescriptor classData =
@@ -154,7 +174,7 @@ public class JavaTypeTransformer {
if (classType.isRaw()) {
List parameters = classData.getTypeConstructor().getParameters();
for (TypeParameterDescriptor parameter : parameters) {
- arguments.add(TypeUtils.makeStarProjection(parameter));
+ arguments.add(SubstitutionUtils.makeStarProjection(parameter));
}
}
else {
@@ -171,13 +191,15 @@ public class JavaTypeTransformer {
PsiType psiArgument = psiArguments[i];
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
- arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor, typeVariableResolver));
+ TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT;
+ arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor, typeVariableResolver, howTheProjectionIsUsed));
}
}
+
return new JetTypeImpl(
Collections.emptyList(),
classData.getTypeConstructor(),
- true,
+ nullable,
arguments,
classData.getMemberScope(arguments));
}
@@ -275,6 +297,7 @@ public class JavaTypeTransformer {
MEMBER_SIGNATURE_COVARIANT,
MEMBER_SIGNATURE_CONTRAVARIANT,
MEMBER_SIGNATURE_INVARIANT,
- SUPERTYPE
+ SUPERTYPE,
+ SUPERTYPE_ARGUMENT
}
}
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JdkNames.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JdkNames.java
new file mode 100644
index 00000000000..7e28b65fa27
--- /dev/null
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JdkNames.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.lang.resolve.java;
+
+/**
+ * @author Stepan Koltsov
+ */
+public class JdkNames {
+
+ public static final JvmClassName JL_OBJECT = new JvmClassName("java.lang.Object");
+
+}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java
index 562836b11cf..a30b1de310f 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java
@@ -41,7 +41,7 @@ import org.jetbrains.jet.plugin.JetMainDetector;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
-import static org.jetbrains.jet.lang.resolve.BindingContext.MUST_BE_WRAPPED_IN_A_REF;
+import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
/**
@@ -599,7 +599,7 @@ public class JetFlowInformationProvider {
!DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return;
VariableStatus variableStatus = enterData.get(variableDescriptor);
if (instruction instanceof WriteValueInstruction) {
- if (trace.get(MUST_BE_WRAPPED_IN_A_REF, variableDescriptor)) return;
+ if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor)) return;
JetElement element = ((WriteValueInstruction) instruction).getElement();
if (variableStatus != VariableStatus.READ) {
if (element instanceof JetBinaryExpression && ((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java
index 5929c950711..58b821afa3f 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java
@@ -97,7 +97,8 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
if (typeConstructor.getParameters().isEmpty()) {
return memberDeclarations;
}
- Map substitutionContext = TypeUtils.buildSubstitutionContext(typeConstructor.getParameters(), typeArguments);
+ Map substitutionContext = SubstitutionUtils
+ .buildSubstitutionContext(typeConstructor.getParameters(), typeArguments);
return new SubstitutingScope(memberDeclarations, TypeSubstitutor.create(substitutionContext));
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java
index 96c7cae015e..b71c09f28b6 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java
@@ -21,6 +21,7 @@ import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
+import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
@@ -47,7 +48,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
protected Modality modality;
protected Visibility visibility;
- protected final Set overriddenFunctions = Sets.newLinkedHashSet();
+ protected final Set overriddenFunctions = Sets.newLinkedHashSet(); // LinkedHashSet is essential here
private final FunctionDescriptor original;
private final Kind kind;
@@ -230,7 +231,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
);
if (copyOverrides) {
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
- substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor));
+ OverridingUtil.bindOverride(substitutedDescriptor, overriddenFunction.substitute(substitutor));
}
}
return substitutedDescriptor;
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java
index 95b0446da29..e1cd4083a61 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java
@@ -119,18 +119,30 @@ public class FunctionDescriptorUtil {
return parameterScope;
}
- public static void initializeFromFunctionType(@NotNull FunctionDescriptorImpl functionDescriptor, @NotNull JetType functionType, @NotNull ReceiverDescriptor expectedThisObject) {
+ public static void initializeFromFunctionType(@NotNull FunctionDescriptorImpl functionDescriptor, @NotNull JetType functionType, @NotNull ReceiverDescriptor expectedThisObject,
+ @NotNull Modality modality, @NotNull Visibility visibility) {
+
assert JetStandardClasses.isFunctionType(functionType);
functionDescriptor.initialize(JetStandardClasses.getReceiverType(functionType),
expectedThisObject,
Collections.emptyList(),
JetStandardClasses.getValueParameters(functionDescriptor, functionType),
JetStandardClasses.getReturnTypeFromFunctionType(functionType),
- Modality.FINAL,
- Visibilities.LOCAL);
+ modality,
+ visibility);
}
public static D alphaConvertTypeParameters(D candidate) {
return (D) candidate.substitute(MAKE_TYPE_PARAMETERS_FRESH);
}
+
+ public static FunctionDescriptor getInvokeFunction(@NotNull JetType functionType) {
+ assert JetStandardClasses.isFunctionType(functionType);
+
+ ClassifierDescriptor classDescriptorForFunction = functionType.getConstructor().getDeclarationDescriptor();
+ assert classDescriptorForFunction instanceof ClassDescriptor;
+ Set invokeFunctions = ((ClassDescriptor) classDescriptorForFunction).getMemberScope(functionType.getArguments()).getFunctions("invoke");
+ assert invokeFunctions.size() == 1;
+ return invokeFunctions.iterator().next();
+ }
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java
index 2339f09d162..6854bf0777d 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java
@@ -33,7 +33,8 @@ import java.util.Set;
* @author abreslav
*/
public class MutableClassDescriptor extends MutableClassDescriptorLite {
- private final Set callableMembers = Sets.newHashSet();
+ private final Set declaredCallableMembers = Sets.newHashSet();
+ private final Set allCallableMembers = Sets.newHashSet(); // includes fake overrides
private final Set properties = Sets.newHashSet();
private final Set functions = Sets.newHashSet();
@@ -104,7 +105,10 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
super.addPropertyDescriptor(propertyDescriptor);
properties.add(propertyDescriptor);
- callableMembers.add(propertyDescriptor);
+ if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
+ declaredCallableMembers.add(propertyDescriptor);
+ }
+ allCallableMembers.add(propertyDescriptor);
scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor);
}
@@ -112,7 +116,10 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
super.addFunctionDescriptor(functionDescriptor);
functions.add(functionDescriptor);
- callableMembers.add(functionDescriptor);
+ if (functionDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
+ declaredCallableMembers.add(functionDescriptor);
+ }
+ allCallableMembers.add(functionDescriptor);
scopeForMemberResolution.addFunctionDescriptor(functionDescriptor);
}
@@ -127,8 +134,13 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
}
@NotNull
- public Set getCallableMembers() {
- return callableMembers;
+ public Set getDeclaredCallableMembers() {
+ return declaredCallableMembers;
+ }
+
+ @NotNull
+ public Set getAllCallableMembers() {
+ return allCallableMembers;
}
@Override
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java
index 100305afe9e..ef24b557129 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java
@@ -127,7 +127,7 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
}
}
- public WritableScope getScopeForMemberLookupAsWritableScope() {
+ private WritableScope getScopeForMemberLookupAsWritableScope() {
// hack
return (WritableScope) scopeForMemberLookup;
}
@@ -139,7 +139,7 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
if (typeArguments.isEmpty()) return scopeForMemberLookup;
List typeParameters = getTypeConstructor().getParameters();
- Map substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments);
+ Map substitutionContext = SubstitutionUtils.buildSubstitutionContext(typeParameters, typeArguments);
return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext));
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java
index a7edd5d4ea5..fc8a496610d 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/PropertyDescriptor.java
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
+import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
@@ -42,7 +43,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
private Visibility visibility;
private final boolean isVar;
private final boolean isObject;
- private final Set overriddenProperties = Sets.newLinkedHashSet();
+ private final Set overriddenProperties = Sets.newLinkedHashSet(); // LinkedHashSet is essential here
private final PropertyDescriptor original;
private final Kind kind;
@@ -268,7 +269,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
if (copyOverrides) {
for (PropertyDescriptor propertyDescriptor : overriddenProperties) {
- substitutedDescriptor.addOverriddenDescriptor(propertyDescriptor.substitute(substitutor));
+ OverridingUtil.bindOverride(substitutedDescriptor, propertyDescriptor.substitute(substitutor));
}
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java
index 5a3c4a17c52..f66d37994dc 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java
@@ -21,6 +21,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.types.JetType;
+import java.util.Set;
+
/**
* @author abreslav
*/
@@ -31,8 +33,22 @@ public interface ValueParameterDescriptor extends VariableDescriptor, Annotated
* @return the parameter index
*/
int getIndex();
+
+ /**
+ * The font-end relies on this property when resolving function calls
+ *
+ * @return {@code true} iff the parameter has a default value, i.e. declares it or inherits
+ * by overriding a parameter in an overridden function.
+ */
boolean hasDefaultValue();
- boolean isRef();
+
+ /**
+ * The back-end should relies on this property when generating function signatures
+ *
+ * @return {@code true} iff the parameter declares a default value, i.e. explicitly specifies it in the function header
+ */
+ boolean declaresDefaultValue();
+
@Nullable JetType getVarargElementType();
@Override
@@ -46,4 +62,14 @@ public interface ValueParameterDescriptor extends VariableDescriptor, Annotated
@NotNull
ValueParameterDescriptor copy(DeclarationDescriptor newOwner);
+ /**
+ * Parameter p1 overrides p2 iff
+ * a) their respective owners (function declarations) f1 override f2
+ * b) p1 and p2 have the same indices in the owners' parameter lists
+ */
+ @NotNull
+ @Override
+ Set extends ValueParameterDescriptor> getOverriddenDescriptors();
+
+ void addOverriddenDescriptor(@NotNull ValueParameterDescriptor overridden);
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java
index 09ff2883b3f..d6757f6924a 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptorImpl.java
@@ -17,24 +17,33 @@
package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
*/
public class ValueParameterDescriptorImpl extends VariableDescriptorImpl implements MutableValueParameterDescriptor {
- private final boolean hasDefaultValue;
+ private Boolean hasDefaultValue;
+ private final boolean declaresDefaultValue;
+
private final JetType varargElementType;
private final boolean isVar;
private final int index;
private final ValueParameterDescriptor original;
+ private final Set overriddenDescriptors = Sets.newLinkedHashSet(); // Linked is essential
+ private boolean overriddenDescriptorsLocked = false;
+ private final Set extends ValueParameterDescriptor> readOnlyOverriddenDescriptors = Collections.unmodifiableSet(overriddenDescriptors);
+
public ValueParameterDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
int index,
@@ -42,12 +51,12 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
@NotNull String name,
boolean isVar,
@NotNull JetType outType,
- boolean hasDefaultValue,
+ boolean declaresDefaultValue,
@Nullable JetType varargElementType) {
super(containingDeclaration, annotations, name, outType);
this.original = this;
this.index = index;
- this.hasDefaultValue = hasDefaultValue;
+ this.declaresDefaultValue = declaresDefaultValue;
this.varargElementType = varargElementType;
this.isVar = isVar;
}
@@ -59,11 +68,11 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
boolean isVar,
@NotNull JetType outType,
@Nullable JetType varargElementType
- ) {
+ ) {
super(containingDeclaration, annotations, original.getName(), outType);
this.original = original;
this.index = original.getIndex();
- this.hasDefaultValue = original.hasDefaultValue();
+ this.declaresDefaultValue = original.declaresDefaultValue();
this.varargElementType = varargElementType;
this.isVar = isVar;
}
@@ -80,12 +89,30 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
@Override
public boolean hasDefaultValue() {
+ computeDefaultValuePresence();
return hasDefaultValue;
}
@Override
- public boolean isRef() {
- throw new UnsupportedOperationException(); // TODO
+ public boolean declaresDefaultValue() {
+ return declaresDefaultValue && ((CallableMemberDescriptor) getContainingDeclaration()).getKind().isReal();
+ }
+
+ private void computeDefaultValuePresence() {
+ if (hasDefaultValue != null) return;
+ overriddenDescriptorsLocked = true;
+ if (declaresDefaultValue) {
+ hasDefaultValue = true;
+ }
+ else {
+ for (ValueParameterDescriptor descriptor : overriddenDescriptors) {
+ if (descriptor.hasDefaultValue()) {
+ hasDefaultValue = true;
+ return;
+ }
+ }
+ hasDefaultValue = false;
+ }
}
@Nullable
@@ -131,4 +158,17 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme
public Visibility getVisibility() {
return Visibilities.LOCAL;
}
+
+ @NotNull
+ @Override
+ public Set extends ValueParameterDescriptor> getOverriddenDescriptors() {
+ return readOnlyOverriddenDescriptors;
+ }
+
+ @Override
+ public void addOverriddenDescriptor(@NotNull ValueParameterDescriptor overridden) {
+ assert !overriddenDescriptorsLocked : "Adding more overridden descriptors is not allowed at this point: " +
+ "the presence of the default value has already been calculated";
+ overriddenDescriptors.add(overridden);
+ }
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableAsFunctionDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableAsFunctionDescriptor.java
deleted file mode 100644
index 860d23f5d68..00000000000
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/VariableAsFunctionDescriptor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2010-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.jet.lang.descriptors;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
-import org.jetbrains.jet.lang.types.JetType;
-
-import java.util.Collections;
-
-/**
- * @author abreslav
- */
-public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl {
- public static VariableAsFunctionDescriptor create(@NotNull VariableDescriptor variableDescriptor) {
- JetType outType = variableDescriptor.getType();
- assert outType != null;
- VariableAsFunctionDescriptor result = new VariableAsFunctionDescriptor(variableDescriptor);
- FunctionDescriptorUtil.initializeFromFunctionType(result, outType, variableDescriptor.getExpectedThisObject());
- return result;
- }
-
- private final VariableDescriptor variableDescriptor;
-
- private VariableAsFunctionDescriptor(VariableDescriptor variableDescriptor) {
- super(variableDescriptor.getContainingDeclaration(), Collections.emptyList(), variableDescriptor.getName(), Kind.DECLARATION);
- this.variableDescriptor = variableDescriptor;
- }
-
- public VariableDescriptor getVariableDescriptor() {
- return variableDescriptor;
- }
-
- @NotNull
- @Override
- public VariableAsFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
- throw new UnsupportedOperationException("Should not be copied for overriding");
- }
-
- @Override
- protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind) {
- throw new IllegalStateException();
- }
-}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
index 929f1350017..997ef40c1fb 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
@@ -51,7 +51,7 @@ public interface Errors {
//Elements with "INVISIBLE_REFERENCE" error are marked as unresolved, unlike elements with "INVISIBLE_MEMBER" error
DiagnosticFactory2 INVISIBLE_REFERENCE =
DiagnosticFactory2.create(ERROR);
- DiagnosticFactory2 INVISIBLE_MEMBER = DiagnosticFactory2.create(ERROR);
+ DiagnosticFactory2 INVISIBLE_MEMBER = DiagnosticFactory2.create(ERROR, PositioningStrategies.CALL_ELEMENT);
RedeclarationDiagnosticFactory REDECLARATION = new RedeclarationDiagnosticFactory(ERROR);
RedeclarationDiagnosticFactory NAME_SHADOWING = new RedeclarationDiagnosticFactory(WARNING);
@@ -247,12 +247,12 @@ public interface Errors {
public List mark(@NotNull JetDeclarationWithBody element) {
JetExpression bodyExpression = element.getBodyExpression();
if (!(bodyExpression instanceof JetBlockExpression)) {
- return Collections.emptyList();
+ return markElement(element);
}
JetBlockExpression blockExpression = (JetBlockExpression)bodyExpression;
TextRange lastBracketRange = blockExpression.getLastBracketRange();
if (lastBracketRange == null) {
- return Collections.emptyList();
+ return markElement(element);
}
return markRange(lastBracketRange);
}
@@ -288,7 +288,6 @@ public interface Errors {
@NotNull
@Override
public List mark(@NotNull JetWhenExpression element) {
- if (hasSyntaxError(element)) return Collections.emptyList();
return markElement(element.getWhenKeywordElement());
}
});
@@ -380,6 +379,12 @@ public interface Errors {
DiagnosticFactory2 MANY_IMPL_MEMBER_NOT_IMPLEMENTED =
DiagnosticFactory2.create(ERROR);
+ SimpleDiagnosticFactory DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE = SimpleDiagnosticFactory.create(ERROR, PositioningStrategies.PARAMETER_DEFAULT_VALUE);
+ DiagnosticFactory1 MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES = DiagnosticFactory1.create(ERROR, PositioningStrategies.POSITION_NAME_IDENTIFIER);
+ DiagnosticFactory1 MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE = DiagnosticFactory1.create(ERROR, PositioningStrategies.POSITION_NAME_IDENTIFIER);
+ DiagnosticFactory2 PARAMETER_NAME_CHANGED_ON_OVERRIDE = DiagnosticFactory2.create(WARNING, PositioningStrategies.POSITION_NAME_IDENTIFIER);
+ DiagnosticFactory2, Integer> DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES = DiagnosticFactory2.create(WARNING, PositioningStrategies.POSITION_NAME_IDENTIFIER);
+
DiagnosticFactory2 CONFLICTING_OVERLOADS =
DiagnosticFactory2.create(ERROR, new PositioningStrategy() {
@NotNull
@@ -397,7 +402,7 @@ public interface Errors {
JetClass klass = (JetClass)jetDeclaration;
PsiElement nameAsDeclaration = klass.getNameIdentifier();
if (nameAsDeclaration == null) {
- return markRange(klass.getTextRange());
+ return markElement(klass);
}
PsiElement primaryConstructorParameterList = klass.getPrimaryConstructorParameterList();
if (primaryConstructorParameterList == null) {
@@ -410,7 +415,7 @@ public interface Errors {
}
else {
// safe way
- return markRange(jetDeclaration.getTextRange());
+ return markElement(jetDeclaration);
}
}
});
@@ -443,7 +448,7 @@ public interface Errors {
class Initializer {
static {
for (Field field : Errors.class.getFields()) {
- if ((field.getModifiers() & Modifier.STATIC) != 0) {
+ if (Modifier.isStatic(field.getModifiers())) {
try {
Object value = field.get(null);
if (value instanceof AbstractDiagnosticFactory) {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java
index 21746e40652..0f9f14ac019 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java
@@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.lexer.JetTokens;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -60,10 +59,9 @@ public class PositioningStrategies {
returnTypeRef = accessor.getReturnTypeReference();
nameNode = accessor.getNamePlaceholder().getNode();
}
- if (returnTypeRef != null) return Collections.singletonList(returnTypeRef.getTextRange());
- if (nameNode != null) return Collections.singletonList(nameNode.getTextRange());
- return super.mark(declaration);
-
+ if (returnTypeRef != null) return markElement(returnTypeRef);
+ if (nameNode != null) return markNode(nameNode);
+ return markElement(declaration);
}
private ASTNode getNameNode(JetNamedDeclaration function) {
@@ -76,14 +74,11 @@ public class PositioningStrategies {
@NotNull
@Override
public List mark(@NotNull PsiNameIdentifierOwner element) {
- if (element.getLastChild() instanceof PsiErrorElement) {
- return Collections.emptyList();
- }
PsiElement nameIdentifier = element.getNameIdentifier();
if (nameIdentifier != null) {
return markElement(nameIdentifier);
}
- return Collections.emptyList();
+ return markElement(element);
}
};
@@ -101,9 +96,9 @@ public class PositioningStrategies {
assert modifierList != null;
ASTNode node = modifierList.getModifierNode(token);
assert node != null;
- return Collections.singletonList(node.getTextRange());
+ return markNode(node);
}
- return Collections.emptyList();
+ return markElement(modifierListOwner);
}
};
}
@@ -144,4 +139,26 @@ public class PositioningStrategies {
return markNode(element.getProjectionNode());
}
};
+
+ public static PositioningStrategy PARAMETER_DEFAULT_VALUE = new PositioningStrategy() {
+ @NotNull
+ @Override
+ public List mark(@NotNull JetParameter element) {
+ return markNode(element.getDefaultValue().getNode());
+ }
+ };
+
+ public static PositioningStrategy CALL_ELEMENT = new PositioningStrategy() {
+ @NotNull
+ @Override
+ public List mark(@NotNull PsiElement callElement) {
+ if (callElement instanceof JetCallElement) {
+ JetExpression calleeExpression = ((JetCallElement) callElement).getCalleeExpression();
+ if (calleeExpression != null) {
+ return markElement(calleeExpression);
+ }
+ }
+ return markElement(callElement);
+ }
+ };
}
\ No newline at end of file
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnosticFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnosticFactory.java
index fd80049556d..992f4317ad6 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnosticFactory.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnosticFactory.java
@@ -34,7 +34,10 @@ public class UnresolvedReferenceDiagnosticFactory extends DiagnosticFactory1 mark(@NotNull JetReferenceExpression element) {
if (element instanceof JetArrayAccessExpression) {
- return ((JetArrayAccessExpression) element).getBracketRanges();
+ List ranges = ((JetArrayAccessExpression) element).getBracketRanges();
+ if (!ranges.isEmpty()) {
+ return ranges;
+ }
}
return Collections.singletonList(element.getTextRange());
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java
index fd304e115d7..bd148492f1f 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java
@@ -17,7 +17,9 @@
package org.jetbrains.jet.lang.diagnostics.rendering;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.diagnostics.AbstractDiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
+import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.psi.JetTypeConstraint;
@@ -25,6 +27,8 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.resolve.DescriptorRenderer;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Iterator;
@@ -385,7 +389,38 @@ public class DefaultErrorMessages {
MAP.put(NOT_AN_ANNOTATION_CLASS, "''{0}'' is not an annotation class", TO_STRING);
+ MAP.put(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE, "An overriding function is not allowed to specify default values for its parameters");
+
+
+ String multipleDefaultsMessage = "More than one overridden descriptor declares a default value for ''{0}''. " +
+ "As the compiler can not make sure these values agree, this is not allowed.";
+ MAP.put(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES, multipleDefaultsMessage, TO_STRING);
+ MAP.put(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE, multipleDefaultsMessage, TO_STRING);
+
+ MAP.put(PARAMETER_NAME_CHANGED_ON_OVERRIDE, "The corresponding parameter in the supertype ''{0}'' is named ''{1}''. " +
+ "This may cause problems when calling this function with named arguments.", NAME, NAME);
+
+ MAP.put(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES,
+ "Names of the parameter #{1} conflict in the following members of supertypes: ''{0}''" +
+ "This may cause problems when calling this function with named arguments.", commaSeparated(TO_STRING), TO_STRING);
+
MAP.setImmutable();
+
+ for (Field field : Errors.class.getFields()) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ try {
+ Object fieldValue = field.get(null);
+ if (fieldValue instanceof AbstractDiagnosticFactory) {
+ if (MAP.get((AbstractDiagnosticFactory) fieldValue) == null) {
+ throw new IllegalStateException("No default diagnostic renderer is provided for " + ((AbstractDiagnosticFactory)fieldValue).getName());
+ }
+ }
+ }
+ catch (IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
}
private DefaultErrorMessages() {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java
index 16527b27a30..48a39fc518e 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.Collection;
+import java.util.Iterator;
/**
* @author svtk
@@ -98,6 +99,24 @@ public class Renderers {
}
};
+ public static Renderer> commaSeparated(final Renderer itemRenderer) {
+ return new Renderer>() {
+ @NotNull
+ @Override
+ public String render(@NotNull Collection extends T> object) {
+ StringBuilder result = new StringBuilder();
+ for (Iterator extends T> iterator = object.iterator(); iterator.hasNext(); ) {
+ T next = iterator.next();
+ result.append(itemRenderer.render(next));
+ if (iterator.hasNext()) {
+ result.append(", ");
+ }
+ }
+ return result.toString();
+ }
+ };
+ }
+
private Renderers() {
}
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/Call.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/Call.java
index 4d5a1fa5937..d3c46683dbb 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/Call.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/Call.java
@@ -36,6 +36,9 @@ public interface Call {
@NotNull
ReceiverDescriptor getExplicitReceiver();
+ @NotNull
+ ReceiverDescriptor getThisObject();
+
@Nullable
JetExpression getCalleeExpression();
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java
index 1110c6630b4..42e0d6d1239 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNameIdentifierOwner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -25,7 +26,7 @@ import java.util.List;
/**
* @author max
*/
-public interface JetClassOrObject extends PsiElement {
+public interface JetClassOrObject extends PsiElement, PsiNameIdentifierOwner {
List getDeclarations();
@Nullable
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
index e0ba360e177..cde638bb6a7 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
@@ -16,6 +16,7 @@
package org.jetbrains.jet.lang.psi;
+import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
@@ -308,4 +309,9 @@ public class JetPsiUtil {
return "Unit".equals(typeReference.getText());
}
+
+ public static boolean isSafeCall(@NotNull Call call) {
+ ASTNode callOperationNode = call.getCallOperationNode();
+ return callOperationNode != null && callOperationNode.getElementType() == JetTokens.SAFE_ACCESS;
+ }
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java
index 5ebff0f781e..674b7b5fbd4 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java
@@ -61,6 +61,7 @@ public interface BindingContext {
WritableSlice AUTOCAST = Slices.createSimpleSlice();
/** A scope where type of expression has been resolved */
+ WritableSlice TYPE_RESOLUTION_SCOPE = Slices.createSimpleSlice();
WritableSlice RESOLUTION_SCOPE = Slices.createSimpleSlice();
/** Collected during analyze, used in IDE in auto-cast completion */
@@ -75,7 +76,7 @@ public interface BindingContext {
WritableSlice STATEMENT = Slices.createRemovableSetSlice();
WritableSlice DELEGATED = Slices.createRemovableSetSlice();
- WritableSlice MUST_BE_WRAPPED_IN_A_REF = Slices.createSimpleSetSlice();
+ WritableSlice CAPTURED_IN_CLOSURE = Slices.createSimpleSetSlice();
// enum DeferredTypeKey {DEFERRED_TYPE_KEY}
// WritableSlice> DEFERRED_TYPES = Slices.createSimpleSlice();
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java
index e33be6780f7..389a3fa1486 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java
@@ -20,14 +20,10 @@ import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
-import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
-import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
-import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.VariableAsFunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
+import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
+import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
+import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.Slices;
@@ -53,12 +49,12 @@ public class BindingContextUtils {
throw new IllegalStateException("non-declaration descriptors should be filtered out earler: " + callable);
}
}
- if (declarationDescriptor instanceof VariableAsFunctionDescriptor) {
- VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) declarationDescriptor;
- if (descriptor.getOriginal() != descriptor) {
- throw new IllegalStateException("original should be resolved earlier: " + descriptor);
- }
- }
+ //if (declarationDescriptor instanceof VariableAsFunctionDescriptor) {
+ // VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) declarationDescriptor;
+ // if (descriptor.getOriginal() != descriptor) {
+ // throw new IllegalStateException("original should be resolved earlier: " + descriptor);
+ // }
+ //}
return declarationDescriptor.getOriginal();
}
};
@@ -68,7 +64,7 @@ public class BindingContextUtils {
@Nullable
public static PsiElement resolveToDeclarationPsiElement(@NotNull BindingContext bindingContext, @Nullable JetReferenceExpression referenceExpression) {
- DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression);
+ DeclarationDescriptor declarationDescriptor = referenceToDescriptor(bindingContext, referenceExpression);
if (declarationDescriptor == null) {
return bindingContext.get(BindingContext.LABEL_TARGET, referenceExpression);
}
@@ -88,7 +84,7 @@ public class BindingContextUtils {
@NotNull
public static List resolveToDeclarationPsiElements(@NotNull BindingContext bindingContext, @Nullable JetReferenceExpression referenceExpression) {
- DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression);
+ DeclarationDescriptor declarationDescriptor = referenceToDescriptor(bindingContext, referenceExpression);
if (declarationDescriptor == null) {
return Lists.newArrayList(bindingContext.get(BindingContext.LABEL_TARGET, referenceExpression));
}
@@ -114,7 +110,7 @@ public class BindingContextUtils {
descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
}
else if (element instanceof JetSimpleNameExpression) {
- descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
+ descriptor = referenceToDescriptor(bindingContext, (JetSimpleNameExpression) element);
}
else if (element instanceof JetQualifiedExpression) {
descriptor = extractVariableDescriptorIfAny(bindingContext, ((JetQualifiedExpression) element).getSelectorExpression(), onlyReference);
@@ -122,12 +118,19 @@ public class BindingContextUtils {
if (descriptor instanceof VariableDescriptor) {
return (VariableDescriptor) descriptor;
}
- if (descriptor instanceof VariableAsFunctionDescriptor) {
- return ((VariableAsFunctionDescriptor) descriptor).getVariableDescriptor();
- }
return null;
}
+ @Nullable
+ public static DeclarationDescriptor referenceToDescriptor(@NotNull BindingContext bindingContext, @Nullable JetReferenceExpression element) {
+ DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, element);
+ ResolvedCall extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, element);
+ if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
+ descriptor = ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall().getResultingDescriptor();
+ }
+ return descriptor;
+ }
+
// TODO these helper methods are added as a workaround to some compiler bugs in Kotlin...
// NOTE this is used by KDoc
@@ -178,7 +181,7 @@ public class BindingContextUtils {
// TODO evil code
throw new IllegalStateException(
"cannot find declaration: fake descriptor" +
- " has more then one overriden descriptor: " + callable);
+ " has more then one overridden descriptor: " + callable);
}
return callableDescriptorToDeclaration(context, overriddenDescriptors.iterator().next());
@@ -190,9 +193,9 @@ public class BindingContextUtils {
private static List callableDescriptorToDeclarations(@NotNull BindingContext context, @NotNull CallableMemberDescriptor callable) {
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
List r = new ArrayList();
- Set extends CallableMemberDescriptor> overridenDescriptors = callable.getOverriddenDescriptors();
- for (CallableMemberDescriptor overriden : overridenDescriptors) {
- r.addAll(callableDescriptorToDeclarations(context, overriden));
+ Set extends CallableMemberDescriptor> overriddenDescriptors = callable.getOverriddenDescriptors();
+ for (CallableMemberDescriptor overridden : overriddenDescriptors) {
+ r.addAll(callableDescriptorToDeclarations(context, overridden));
}
return r;
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ChainedTemporaryBindingTrace.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ChainedTemporaryBindingTrace.java
new file mode 100644
index 00000000000..b168498bb7e
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ChainedTemporaryBindingTrace.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.lang.resolve;
+
+/**
+ * @author svtk
+ */
+public class ChainedTemporaryBindingTrace extends TemporaryBindingTrace {
+
+ public static ChainedTemporaryBindingTrace create(TemporaryBindingTrace trace) {
+ return new ChainedTemporaryBindingTrace(trace);
+ }
+
+ private ChainedTemporaryBindingTrace(TemporaryBindingTrace trace) {
+ super(trace);
+ }
+
+ @Override
+ public void commit() {
+ super.commit();
+ ((TemporaryBindingTrace) trace).commit();
+ }
+}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java
index c3108cb8bcc..3e5b789e9e5 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java
@@ -21,10 +21,8 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Pair;
-import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.inject.Inject;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
@@ -34,6 +32,7 @@ import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
+import javax.inject.Inject;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -132,8 +131,7 @@ public class DeclarationsChecker {
}
private void checkOpenMembers(MutableClassDescriptor classDescriptor) {
- for (CallableMemberDescriptor memberDescriptor : classDescriptor.getCallableMembers()) {
-
+ for (CallableMemberDescriptor memberDescriptor : classDescriptor.getDeclaredCallableMembers()) {
JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), memberDescriptor);
if (member != null && classDescriptor.getModality() == Modality.FINAL && member.hasModifier(JetTokens.OPEN_KEYWORD)) {
trace.report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member));
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java
index 5fae6c49bcf..bde9faee6cb 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java
@@ -332,16 +332,33 @@ public class DescriptorResolver {
return typeParameterDescriptor;
}
+ final class UpperBoundCheckerTask {
+ JetTypeReference upperBound;
+ JetType upperBoundType;
+ boolean isClassObjectConstraint;
+
+ private UpperBoundCheckerTask(JetTypeReference upperBound, JetType upperBoundType, boolean classObjectConstraint) {
+ this.upperBound = upperBound;
+ this.upperBoundType = upperBoundType;
+ isClassObjectConstraint = classObjectConstraint;
+ }
+ }
public void resolveGenericBounds(@NotNull JetTypeParameterListOwner declaration, JetScope scope, List parameters, BindingTrace trace) {
+ List deferredUpperBoundCheckerTasks = Lists.newArrayList();
+
List typeParameters = declaration.getTypeParameters();
Map parameterByName = Maps.newHashMap();
- for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
+ for (int i = 0; i < typeParameters.size(); i++) {
JetTypeParameter jetTypeParameter = typeParameters.get(i);
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
+
parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
+
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
if (extendsBound != null) {
- typeParameterDescriptor.addUpperBound(resolveAndCheckUpperBoundType(extendsBound, scope, false, trace));
+ JetType type = typeResolver.resolveType(scope, extendsBound, trace, false);
+ typeParameterDescriptor.addUpperBound(type);
+ deferredUpperBoundCheckerTasks.add(new UpperBoundCheckerTask(extendsBound, type, false));
}
}
for (JetTypeConstraint constraint : declaration.getTypeConstaints()) {
@@ -355,7 +372,12 @@ public class DescriptorResolver {
}
TypeParameterDescriptor typeParameterDescriptor = parameterByName.get(referencedName);
JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
- JetType bound = boundTypeReference != null ? resolveAndCheckUpperBoundType(boundTypeReference, scope, constraint.isClassObjectContraint(), trace) : null;
+ JetType bound = null;
+ if (boundTypeReference != null) {
+ bound = typeResolver.resolveType(scope, boundTypeReference, trace, false);
+ deferredUpperBoundCheckerTasks.add(new UpperBoundCheckerTask(boundTypeReference, bound, constraint.isClassObjectContraint()));
+ }
+
if (typeParameterDescriptor == null) {
// To tell the user that we look only for locally defined type parameters
ClassifierDescriptor classifier = scope.getClassifier(referencedName);
@@ -400,19 +422,21 @@ public class DescriptorResolver {
}
}
}
+
+ for (UpperBoundCheckerTask checkerTask : deferredUpperBoundCheckerTasks) {
+ checkUpperBoundType(checkerTask.upperBound, checkerTask.upperBoundType, checkerTask.isClassObjectConstraint, trace);
+ }
}
- private JetType resolveAndCheckUpperBoundType(@NotNull JetTypeReference upperBound, @NotNull JetScope scope, boolean classObjectConstaint, BindingTrace trace) {
- JetType jetType = typeResolver.resolveType(scope, upperBound, trace, false);
- if (!TypeUtils.canHaveSubtypes(JetTypeChecker.INSTANCE, jetType)) {
- if (classObjectConstaint) {
- trace.report(FINAL_CLASS_OBJECT_UPPER_BOUND.on(upperBound, jetType));
+ private static void checkUpperBoundType(JetTypeReference upperBound, JetType upperBoundType, boolean isClassObjectConstraint, BindingTrace trace) {
+ if (!TypeUtils.canHaveSubtypes(JetTypeChecker.INSTANCE, upperBoundType)) {
+ if (isClassObjectConstraint) {
+ trace.report(FINAL_CLASS_OBJECT_UPPER_BOUND.on(upperBound, upperBoundType));
}
else {
- trace.report(FINAL_UPPER_BOUND.on(upperBound, jetType));
+ trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType));
}
}
- return jetType;
}
@NotNull
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java
index 3ef25b43833..661969e7550 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java
@@ -45,6 +45,11 @@ public final class ImportPath {
return fqName.getFqName() + (isAllUnder ? ".*" : "");
}
+ @Override
+ public String toString() {
+ return getPathStr();
+ }
+
@NotNull
public FqName fqnPart() {
return fqName;
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java
index 3368e4d784e..a5aee72f7b4 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java
@@ -163,7 +163,7 @@ public class OverloadResolver {
) {
MultiMap functionsByName = MultiMap.create();
- for (CallableMemberDescriptor function : classDescriptor.getCallableMembers()) {
+ for (CallableMemberDescriptor function : classDescriptor.getDeclaredCallableMembers()) {
functionsByName.putValue(function.getName(), function);
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java
index cb1e794bf8c..8a8a521cc7a 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java
@@ -16,7 +16,10 @@
package org.jetbrains.jet.lang.resolve;
-import com.google.common.collect.*;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.LinkedMultiMap;
@@ -36,7 +39,6 @@ import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
-import static org.jetbrains.jet.lang.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR;
import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED;
/**
@@ -81,6 +83,7 @@ public class OverrideResolver {
checkVisibility();
checkOverrides(invisibleOverriddenDescriptors);
+ checkParameterOverridesForAllClasses();
}
/**
@@ -120,7 +123,7 @@ public class OverrideResolver {
MultiMap functionsFromSupertypesByName = groupDescriptorsByName(functionsFromSupertypes);
- MultiMap functionsFromCurrentByName = groupDescriptorsByName(classDescriptor.getCallableMembers());
+ MultiMap functionsFromCurrentByName = groupDescriptorsByName(classDescriptor.getDeclaredCallableMembers());
Set functionNames = new LinkedHashSet();
functionNames.addAll(functionsFromSupertypesByName.keySet());
@@ -135,10 +138,10 @@ public class OverrideResolver {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
if (fakeOverride instanceof PropertyDescriptor) {
- classDescriptor.getScopeForMemberLookupAsWritableScope().addPropertyDescriptor((PropertyDescriptor) fakeOverride);
+ classDescriptor.addPropertyDescriptor((PropertyDescriptor) fakeOverride);
}
else if (fakeOverride instanceof SimpleFunctionDescriptor) {
- classDescriptor.getScopeForMemberLookupAsWritableScope().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
+ classDescriptor.addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
}
else {
throw new IllegalStateException(fakeOverride.getClass().getName());
@@ -176,7 +179,7 @@ public class OverrideResolver {
for (CallableMemberDescriptor functionFromCurrent : functionsFromCurrent) {
OverridingUtil.OverrideCompatibilityInfo.Result result = OverridingUtil.isOverridableBy(functionFromSupertype, functionFromCurrent).getResult();
if (result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) {
- functionFromCurrent.addOverriddenDescriptor(functionFromSupertype);
+ OverridingUtil.bindOverride(functionFromCurrent, functionFromSupertype);
overrides = true;
}
else if (result == OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT) {
@@ -186,14 +189,14 @@ public class OverrideResolver {
for (CallableMemberDescriptor fakeOverride : fakeOverrideList) {
if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) {
- fakeOverride.addOverriddenDescriptor(functionFromSupertype);
+ OverridingUtil.bindOverride(fakeOverride, functionFromSupertype);
overrides = true;
}
}
if (!overrides) {
CallableMemberDescriptor fakeOverride = functionFromSupertype.copy(current, false, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
- fakeOverride.addOverriddenDescriptor(functionFromSupertype);
+ OverridingUtil.bindOverride(fakeOverride, functionFromSupertype);
fakeOverrideList.add(fakeOverride);
if (fakeOverrides != null) {
fakeOverrides.add(fakeOverride);
@@ -203,7 +206,6 @@ public class OverrideResolver {
}
}
-
private static MultiMap groupDescriptorsByName(Collection properties) {
MultiMap r = new LinkedMultiMap();
for (T property : properties) {
@@ -246,7 +248,7 @@ public class OverrideResolver {
if (topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) return;
// Check overrides for internal consistency
- for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) {
+ for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
checkOverrideForMember(member, invisibleOverriddenDescriptors);
}
@@ -258,10 +260,10 @@ public class OverrideResolver {
PsiElement nameIdentifier = null;
if (klass instanceof JetClass) {
- nameIdentifier = ((JetClass) klass).getNameIdentifier();
+ nameIdentifier = klass.getNameIdentifier();
}
else if (klass instanceof JetObjectDeclaration) {
- nameIdentifier = ((JetObjectDeclaration) klass).getNameIdentifier();
+ nameIdentifier = klass.getNameIdentifier();
if (nameIdentifier == null) {
nameIdentifier = ((JetObjectDeclaration) klass).getObjectKeyword();
}
@@ -285,24 +287,16 @@ public class OverrideResolver {
}
public static void collectMissingImplementations(MutableClassDescriptor classDescriptor, Set abstractNoImpl, Set manyImpl) {
-
- for (DeclarationDescriptor descriptor : classDescriptor.getScopeForMemberLookup().getAllDescriptors()) {
- if (descriptor instanceof CallableMemberDescriptor) {
- collectMissingImplementations((CallableMemberDescriptor) descriptor, abstractNoImpl, manyImpl);
- }
+ for (CallableMemberDescriptor descriptor : classDescriptor.getAllCallableMembers()) {
+ collectMissingImplementations(descriptor, abstractNoImpl, manyImpl);
}
}
private static void collectMissingImplementations(CallableMemberDescriptor descriptor, Set abstractNoImpl, Set manyImpl) {
- if (descriptor.getKind().isReal()) {
- if (descriptor.getModality() == Modality.ABSTRACT) {
- //abstractNoImpl.add(descriptor);
- }
- }
- else {
- Collection overriddenDeclarations = OverridingUtil.getOverridenDeclarations(descriptor);
+ if (!descriptor.getKind().isReal()) {
+ Collection overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(descriptor);
if (overriddenDeclarations.size() == 0) {
- throw new IllegalStateException();
+ throw new IllegalStateException("A 'fake override' must override something");
}
else if (overriddenDeclarations.size() == 1) {
CallableMemberDescriptor single = overriddenDeclarations.iterator().next();
@@ -312,7 +306,8 @@ public class OverrideResolver {
}
else {
List nonAbstractManyImpl = Lists.newArrayList();
- for (CallableMemberDescriptor overridden : overriddenDeclarations) {
+ Set filteredOverriddenDeclarations = OverridingUtil.filterOverrides(Sets.newHashSet(overriddenDeclarations));
+ for (CallableMemberDescriptor overridden : filteredOverriddenDeclarations) {
if (overridden.getModality() != Modality.ABSTRACT) {
nonAbstractManyImpl.add(overridden);
}
@@ -393,6 +388,7 @@ public class OverrideResolver {
}
}
}
+
if (hasOverrideModifier && declared.getOverriddenDescriptors().size() == 0) {
if (!invisibleOverriddenDescriptors.get(declared).isEmpty()) {
CallableDescriptor descriptor = invisibleOverriddenDescriptors.values().iterator().next();
@@ -409,6 +405,74 @@ public class OverrideResolver {
}
}
+ private void checkParameterOverridesForAllClasses() {
+ List allClasses = Lists.newArrayList(context.getClasses().values());
+ allClasses.addAll(context.getObjects().values());
+ for (MutableClassDescriptor classDescriptor : allClasses) {
+ Collection members = classDescriptor.getAllCallableMembers();
+ for (CallableMemberDescriptor member : members) {
+ checkOverridesForParameters(member);
+ }
+ }
+ }
+
+ private void checkOverridesForParameters(CallableMemberDescriptor declared) {
+ boolean fakeOverride = declared.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
+ if (!fakeOverride) {
+ // No check if the function is not marked as 'override'
+ JetModifierListOwner declaration =
+ (JetModifierListOwner) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
+ if (!declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
+ return;
+ }
+ }
+
+ // Let p1 be a parameter of the overriding function
+ // Let p2 be a parameter of the function being overridden
+ // Then
+ // a) p1 is not allowed to have a default value declared
+ // b) p1 must have the same name as p2
+ for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
+ JetParameter parameter =
+ fakeOverride ? null :
+ (JetParameter) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), parameterFromSubclass);
+
+ JetClassOrObject classElement = fakeOverride ? (JetClassOrObject) BindingContextUtils
+ .descriptorToDeclaration(trace.getBindingContext(), declared.getContainingDeclaration()) : null;
+
+ if (parameterFromSubclass.declaresDefaultValue() && !fakeOverride) {
+ trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
+ }
+
+ boolean superWithDefault = false;
+ for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
+ if (parameterFromSuperclass.declaresDefaultValue()) {
+ if (!superWithDefault) {
+ superWithDefault = true;
+ }
+ else {
+ if (fakeOverride) {
+ trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, parameterFromSubclass));
+ }
+ else {
+ trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, parameterFromSubclass));
+ }
+ break;
+ }
+ }
+
+ if (!parameterFromSuperclass.getName().equals(parameterFromSubclass.getName())) {
+ if (fakeOverride) {
+ trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(classElement, declared.getOverriddenDescriptors(), parameterFromSuperclass.getIndex() + 1));
+ }
+ else {
+ trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(parameter, (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(), parameterFromSuperclass));
+ }
+ }
+ }
+ }
+ }
+
private boolean checkPropertyKind(CallableMemberDescriptor descriptor, boolean isVar) {
if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java
index 4a3872c6945..8c7fe2bbe18 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java
@@ -244,17 +244,17 @@ public class OverridingUtil {
}
/**
- * Get overriden descriptors that are declarations or delegations.
+ * Get overridden descriptors that are declarations or delegations.
*
* @see CallableMemberDescriptor.Kind#isReal()
*/
- public static Collection getOverridenDeclarations(CallableMemberDescriptor descriptor) {
+ public static Collection getOverriddenDeclarations(CallableMemberDescriptor descriptor) {
Map result = Maps.newHashMap();
- getOverridenDeclarations(descriptor, result);
+ getOverriddenDeclarations(descriptor, result);
return result.values();
}
- private static void getOverridenDeclarations(CallableMemberDescriptor descriptor, Map r) {
+ private static void getOverriddenDeclarations(CallableMemberDescriptor descriptor, Map r) {
if (descriptor.getKind().isReal()) {
r.put((ClassDescriptor) descriptor.getContainingDeclaration(), descriptor);
}
@@ -262,12 +262,23 @@ public class OverridingUtil {
if (descriptor.getOverriddenDescriptors().isEmpty()) {
throw new IllegalStateException();
}
- for (CallableMemberDescriptor overriden : descriptor.getOverriddenDescriptors()) {
- getOverridenDeclarations(overriden, r);
+ for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
+ getOverriddenDeclarations(overridden, r);
}
}
}
+ public static void bindOverride(CallableMemberDescriptor fromCurrent, CallableMemberDescriptor fromSupertype) {
+ fromCurrent.addOverriddenDescriptor(fromSupertype);
+
+ for (ValueParameterDescriptor parameterFromCurrent : fromCurrent.getValueParameters()) {
+ assert parameterFromCurrent.getIndex() < fromSupertype.getValueParameters().size()
+ : "An override relation between functions implies that they have the same number of value parameters";
+ ValueParameterDescriptor parameterFromSupertype = fromSupertype.getValueParameters().get(parameterFromCurrent.getIndex());
+ parameterFromCurrent.addOverriddenDescriptor(parameterFromSupertype);
+ }
+ }
+
public static class OverrideCompatibilityInfo {
public enum Result {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java
index e8c3425c812..3122f54397d 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java
@@ -25,10 +25,9 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
return new TemporaryBindingTrace(trace);
}
- private final BindingTrace trace;
+ protected final BindingTrace trace;
-
- private TemporaryBindingTrace(BindingTrace trace) {
+ protected TemporaryBindingTrace(BindingTrace trace) {
super(trace.getBindingContext());
this.trace = trace;
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java
index f168cf409a9..6135ed5a0a0 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java
@@ -29,10 +29,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope;
-import org.jetbrains.jet.lang.types.JetType;
-import org.jetbrains.jet.lang.types.TypeConstructor;
-import org.jetbrains.jet.lang.types.TypeProjection;
-import org.jetbrains.jet.lang.types.TypeUtils;
+import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lexer.JetTokens;
@@ -379,7 +376,8 @@ public class TypeHierarchyResolver {
private void checkSupertypesForConsistency() {
for (MutableClassDescriptor mutableClassDescriptor : topologicalOrder) {
- Multimap multimap = TypeUtils.buildDeepSubstitutionMultimap(mutableClassDescriptor.getDefaultType());
+ Multimap multimap = SubstitutionUtils
+ .buildDeepSubstitutionMultimap(mutableClassDescriptor.getDefaultType());
for (Map.Entry> entry : multimap.asMap().entrySet()) {
Collection projections = entry.getValue();
if (projections.size() > 1) {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java
index 8c17ffb46ba..e27a69392b9 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java
@@ -69,6 +69,7 @@ public class TypeResolver {
JetTypeElement typeElement = typeReference.getTypeElement();
JetType type = resolveTypeElement(scope, annotations, typeElement, false, trace, checkBounds);
trace.record(BindingContext.TYPE, typeReference, type);
+ trace.record(BindingContext.TYPE_RESOLUTION_SCOPE, typeReference, scope);
return type;
}
@@ -243,7 +244,7 @@ public class TypeResolver {
List parameters = constructor.getParameters();
if (parameters.size() > i) {
TypeParameterDescriptor parameterDescriptor = parameters.get(i);
- arguments.add(TypeUtils.makeStarProjection(parameterDescriptor));
+ arguments.add(SubstitutionUtils.makeStarProjection(parameterDescriptor));
}
else {
arguments.add(new TypeProjection(Variance.OUT_VARIANCE, ErrorUtils.createErrorType("*")));
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallMaker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallMaker.java
index abdb02465b6..98e42503e85 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallMaker.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallMaker.java
@@ -98,6 +98,12 @@ public class CallMaker {
return explicitReceiver;
}
+ @NotNull
+ @Override
+ public ReceiverDescriptor getThisObject() {
+ return ReceiverDescriptor.NO_RECEIVER;
+ }
+
@Override
public JetExpression getCalleeExpression() {
return calleeExpression;
@@ -199,6 +205,12 @@ public class CallMaker {
return explicitReceiver;
}
+ @NotNull
+ @Override
+ public ReceiverDescriptor getThisObject() {
+ return ReceiverDescriptor.NO_RECEIVER;
+ }
+
@Nullable
public JetExpression getCalleeExpression() {
return callElement.getCalleeExpression();
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java
index 03c5013330a..e5f8c356056 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java
@@ -20,21 +20,27 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.Call;
import org.jetbrains.jet.lang.resolve.BindingTrace;
+import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
/**
* @author svtk
*/
-public final class CallResolutionContext extends ResolutionContext {
+public final class CallResolutionContext extends ResolutionContext {
/*package*/ final ResolvedCallImpl candidateCall;
/*package*/ final TracingStrategy tracing;
+ /*package*/ ReceiverDescriptor receiverForVariableAsFunctionSecondCall = ReceiverDescriptor.NO_RECEIVER;
- public CallResolutionContext(@NotNull ResolvedCallImpl candidateCall, @NotNull ResolutionTask task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) {
+ private CallResolutionContext(@NotNull ResolvedCallImpl candidateCall, @NotNull ResolutionTask task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) {
super(trace, task.scope, call, task.expectedType, task.dataFlowInfo);
this.candidateCall = candidateCall;
this.tracing = tracing;
}
- public CallResolutionContext(@NotNull ResolvedCallImpl candidateCall, @NotNull ResolutionTask task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing) {
- this(candidateCall, task, trace, tracing, task.call);
+ public static CallResolutionContext create(@NotNull ResolvedCallImpl candidateCall, @NotNull ResolutionTask task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) {
+ return new CallResolutionContext(candidateCall, task, trace, tracing, call);
+ }
+
+ public static CallResolutionContext create(@NotNull ResolvedCallImpl candidateCall, @NotNull ResolutionTask task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing) {
+ return create(candidateCall, task, trace, tracing, task.call);
}
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
index 219f06d9156..222d0143e38 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
@@ -102,16 +102,16 @@ public class CallResolver {
if (referencedName == null) {
return OverloadResolutionResultsImpl.nameNotFound();
}
- List> memberPrioritizers = Lists.newArrayList();
+ List> callableDescriptorCollectors = Lists.newArrayList();
if (nameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
referencedName = referencedName.substring(1);
- memberPrioritizers.add(MemberPrioritizers.PROPERTY_TASK_PRIORITIZER);
+ callableDescriptorCollectors.add(CallableDescriptorCollectors.PROPERTIES);
}
else {
- memberPrioritizers.add(MemberPrioritizers.VARIABLE_TASK_PRIORITIZER);
+ callableDescriptorCollectors.add(CallableDescriptorCollectors.VARIABLES);
}
- List> prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, memberPrioritizers);
- return doResolveCall(context, prioritizedTasks, CallTransformationStrategy.PROPERTY_CALL_TRANSFORMATION_STRATEGY, nameExpression);
+ List> prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, callableDescriptorCollectors);
+ return doResolveCall(context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression);
}
@NotNull
@@ -119,9 +119,8 @@ public class CallResolver {
@NotNull BasicResolutionContext context,
@NotNull final JetReferenceExpression functionReference,
@NotNull String name) {
- List> tasks = TaskPrioritizer.computePrioritizedTasks(
- context, name, functionReference, Collections.singletonList(MemberPrioritizers.FUNCTION_TASK_PRIORITIZER));
- return doResolveCall(context, tasks, CallTransformationStrategy.FUNCTION_CALL_TRANSFORMATION_STRATEGY, functionReference);
+ List> tasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
+ return doResolveCall(context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference);
}
@NotNull
@@ -131,7 +130,7 @@ public class CallResolver {
@NotNull
public OverloadResolutionResults resolveFunctionCall(@NotNull BasicResolutionContext context) {
- List> prioritizedTasks;
+ List> prioritizedTasks;
JetExpression calleeExpression = context.call.getCalleeExpression();
final JetReferenceExpression functionReference;
@@ -142,7 +141,7 @@ public class CallResolver {
String name = expression.getReferencedName();
if (name == null) return checkArgumentTypesAndFail(context);
- prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, Collections.singletonList(MemberPrioritizers.FUNCTION_TASK_PRIORITIZER));
+ prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() {
@Override
public boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
@@ -184,8 +183,11 @@ public class CallResolver {
context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(context);
}
- Collection> candidates = TaskPrioritizer.convertWithImpliedThis(context.scope, Collections.singletonList(NO_RECEIVER), constructors);
- prioritizedTasks.add(new ResolutionTask(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
+ Collection> candidates = TaskPrioritizer.convertWithImpliedThis(context.scope, Collections.singletonList(NO_RECEIVER), constructors);
+ for (ResolutionCandidate candidate : candidates) {
+ candidate.setSafeCall(JetPsiUtil.isSafeCall(context.call));
+ }
+ prioritizedTasks.add(new ResolutionTask(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
}
else {
context.trace.report(NOT_A_CLASS.on(calleeExpression));
@@ -206,8 +208,8 @@ public class CallResolver {
context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(context);
}
- List> candidates = ResolutionCandidate.convertCollection(constructors);
- prioritizedTasks = Collections.singletonList(new ResolutionTask(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
+ List> candidates = ResolutionCandidate.convertCollection(constructors, JetPsiUtil.isSafeCall(context.call));
+ prioritizedTasks = Collections.singletonList(new ResolutionTask(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
}
else if (calleeExpression != null) {
// Here we handle the case where the callee expression must be something of type function, e.g. (foo.bar())(1, 2)
@@ -222,16 +224,17 @@ public class CallResolver {
}
FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(context.scope.getContainingDeclaration(), "[for expression " + calleeExpression.getText() + "]");
- FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType, NO_RECEIVER);
- ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(functionDescriptor);
+ FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType, NO_RECEIVER, Modality.FINAL, Visibilities.LOCAL);
+ ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(functionDescriptor, JetPsiUtil.isSafeCall(context.call));
resolutionCandidate.setReceiverArgument(context.call.getExplicitReceiver());
+ resolutionCandidate.setExplicitReceiverKind(ExplicitReceiverKind.RECEIVER_ARGUMENT);
// strictly speaking, this is a hack:
// we need to pass a reference, but there's no reference in the PSI,
// so we wrap what we have into a fake reference and pass it on (unwrap on the other end)
functionReference = new JetFakeReference(calleeExpression);
- prioritizedTasks = Collections.singletonList(new ResolutionTask(Collections.singleton(resolutionCandidate), functionReference, context));
+ prioritizedTasks = Collections.singletonList(new ResolutionTask(Collections.singleton(resolutionCandidate), functionReference, context));
}
else {
// checkTypesWithNoCallee(trace, scope, call);
@@ -239,7 +242,7 @@ public class CallResolver {
}
}
- return doResolveCall(context, prioritizedTasks, CallTransformationStrategy.FUNCTION_CALL_TRANSFORMATION_STRATEGY, functionReference);
+ return doResolveCall(context, prioritizedTasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference);
}
private OverloadResolutionResults checkArgumentTypesAndFail(BasicResolutionContext context) {
@@ -248,10 +251,10 @@ public class CallResolver {
}
@NotNull
- private OverloadResolutionResults doResolveCall(
+ private OverloadResolutionResults doResolveCall(
@NotNull final BasicResolutionContext context,
- @NotNull final List> prioritizedTasks, // high to low priority
- @NotNull CallTransformationStrategy callTransformationStrategy,
+ @NotNull final List> prioritizedTasks, // high to low priority
+ @NotNull CallTransformer callTransformer,
@NotNull final JetReferenceExpression reference) {
ResolutionDebugInfo.Data debugInfo = ResolutionDebugInfo.create();
@@ -265,10 +268,11 @@ public class CallResolver {
debugInfo.set(ResolutionDebugInfo.TASKS, prioritizedTasks);
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
- OverloadResolutionResultsImpl resultsForFirstNonemptyCandidateSet = null;
- for (ResolutionTask task : prioritizedTasks) {
+ OverloadResolutionResultsImpl resultsForFirstNonemptyCandidateSet = null;
+ for (ResolutionTask task : prioritizedTasks) {
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
- OverloadResolutionResultsImpl results = performResolutionGuardedForExtraFunctionLiteralArguments(task.withTrace(temporaryTrace), callTransformationStrategy);
+ OverloadResolutionResultsImpl results = performResolutionGuardedForExtraFunctionLiteralArguments(task.withTrace(temporaryTrace),
+ callTransformer);
if (results.isSuccess() || results.isAmbiguity()) {
temporaryTrace.commit();
@@ -294,15 +298,15 @@ public class CallResolver {
context.trace.report(UNRESOLVED_REFERENCE.on(reference));
checkTypesWithNoCallee(context);
}
- return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.nameNotFound();
+ return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.nameNotFound();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
- private OverloadResolutionResultsImpl performResolutionGuardedForExtraFunctionLiteralArguments(@NotNull ResolutionTask task,
- @NotNull CallTransformationStrategy callTransformationStrategy) {
- OverloadResolutionResultsImpl results = performResolution(task, callTransformationStrategy);
+ private OverloadResolutionResultsImpl performResolutionGuardedForExtraFunctionLiteralArguments(@NotNull ResolutionTask task,
+ @NotNull CallTransformer callTransformer) {
+ OverloadResolutionResultsImpl results = performResolution(task, callTransformer);
// If resolution fails, we should check for some of the following situations:
// class A {
@@ -327,16 +331,16 @@ public class CallResolver {
// Now, we try to remove this argument and see if it helps
Collection> newCandidates = Lists.newArrayList();
for (ResolutionCandidate candidate : task.getCandidates()) {
- newCandidates.add(ResolutionCandidate.create(candidate.getDescriptor()));
+ newCandidates.add(ResolutionCandidate.create(candidate.getDescriptor(), candidate.isSafeCall())); //todo check receivers are not necessary
}
- ResolutionTask newContext = new ResolutionTask(newCandidates, task.reference, TemporaryBindingTrace.create(task.trace), task.scope, new DelegatingCall(task.call) {
+ ResolutionTask newContext = new ResolutionTask(newCandidates, task.reference, TemporaryBindingTrace.create(task.trace), task.scope, new DelegatingCall(task.call) {
@NotNull
@Override
public List getFunctionLiteralArguments() {
return Collections.emptyList();
}
}, task.expectedType, task.dataFlowInfo);
- OverloadResolutionResultsImpl resultsWithFunctionLiteralsStripped = performResolution(newContext, callTransformationStrategy);
+ OverloadResolutionResultsImpl resultsWithFunctionLiteralsStripped = performResolution(newContext, callTransformer);
if (resultsWithFunctionLiteralsStripped.isSuccess() || resultsWithFunctionLiteralsStripped.isAmbiguity()) {
task.tracing.danglingFunctionLiteralArgumentSuspected(task.trace, task.call.getFunctionLiteralArguments());
}
@@ -346,23 +350,28 @@ public class CallResolver {
}
@NotNull
- private OverloadResolutionResultsImpl performResolution(@NotNull ResolutionTask task,
- @NotNull CallTransformationStrategy callTransformationStrategy) {
+ private OverloadResolutionResultsImpl performResolution(@NotNull ResolutionTask task,
+ @NotNull CallTransformer callTransformer) {
for (ResolutionCandidate