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/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..212ce07014f 100644
--- a/TeamCityBuild.xml
+++ b/TeamCityBuild.xml
@@ -14,7 +14,7 @@
-
+
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 b8944f95dba..79611687b46 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
@@ -51,8 +51,8 @@ public class BytecodeCompiler {
*/
private CompileEnvironmentConfiguration env( String stdlib, String[] classpath ) {
CompilerDependencies dependencies = CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.REGULAR);
- JetCoreEnvironment environment = JetCoreEnvironment.getCoreEnvironmentForJVM(CompileEnvironmentUtil.createMockDisposable(), dependencies);
- CompileEnvironmentConfiguration env = new CompileEnvironmentConfiguration(environment, dependencies, MessageCollector.PLAIN_TEXT_TO_SYSTEM_ERR);
+ JetCoreEnvironment environment = new JetCoreEnvironment(CompileEnvironmentUtil.createMockDisposable(), dependencies);
+ CompileEnvironmentConfiguration env = new CompileEnvironmentConfiguration(environment, MessageCollector.PLAIN_TEXT_TO_SYSTEM_ERR);
if (( stdlib != null ) && ( stdlib.trim().length() > 0 )) {
File file = new File(stdlib);
diff --git a/build.xml b/build.xml
index 99b8c4a2b8b..e772fe4ef7d 100644
--- a/build.xml
+++ b/build.xml
@@ -170,9 +170,12 @@
-
+
+
-
+
+
+
@@ -180,7 +183,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -193,11 +213,13 @@
+
-
-
+
-
+
+
+
@@ -217,8 +239,57 @@
-
+
+
+
+
+
+ (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/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
index e497db59abb..174511076d0 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);
}
}
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 234191b7749..8c3c821e1f7 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java
@@ -179,8 +179,8 @@ public class K2JVMCompiler extends CLICompiler sourceFiles = Lists.newArrayList();
-
+ private final List sourceFiles = new ArrayList();
@NotNull
- public static JetCoreEnvironment getCoreEnvironmentForJVM(@NotNull Disposable disposable,
- @NotNull CompilerDependencies compilerDependencies) {
- JetCoreEnvironment coreEnvironment = new JetCoreEnvironment(disposable);
+ private final CompilerDependencies compilerDependencies;
- CompilerSpecialMode compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
-
- coreEnvironment.addToClasspath(compilerDependencies.getJdkJar());
-
- if (compilerSpecialMode.includeJdkHeaders()) {
- for (VirtualFile root : compilerDependencies.getJdkHeaderRoots()) {
- coreEnvironment.addLibraryRoot(root);
- }
- }
- if (compilerSpecialMode.includeKotlinRuntime()) {
- for (VirtualFile root : compilerDependencies.getRuntimeRoots()) {
- coreEnvironment.addLibraryRoot(root);
- }
- }
- return coreEnvironment;
- }
-
- @NotNull
- public static JetCoreEnvironment getCoreEnvironmentForJS(@NotNull Disposable disposable) {
- return new JetCoreEnvironment(disposable);
- }
-
- private JetCoreEnvironment(Disposable parentDisposable) {
+ public JetCoreEnvironment(Disposable parentDisposable, @NotNull CompilerDependencies compilerDependencies) {
super(parentDisposable);
+
+ this.compilerDependencies = compilerDependencies;
+
registerFileType(JetFileType.INSTANCE, "kt");
registerFileType(JetFileType.INSTANCE, "kts");
registerFileType(JetFileType.INSTANCE, "ktm");
@@ -90,6 +68,19 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
.getExtensionPoint(PsiElementFinder.EP_NAME)
.registerExtension(new JavaElementFinder(myProject));
+ CompilerSpecialMode compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
+
+ addToClasspath(compilerDependencies.getJdkJar());
+
+ if (compilerSpecialMode.includeJdkHeaders()) {
+ for (VirtualFile root : compilerDependencies.getJdkHeaderRoots()) {
+ addLibraryRoot(root);
+ }
+ }
+ if (compilerSpecialMode.includeKotlinRuntime()) {
+ addToClasspath(compilerDependencies.getRuntimeJar());
+ }
+
JetStandardLibrary.initialize(getProject());
}
@@ -98,7 +89,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) {
@@ -110,7 +101,7 @@ 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) {
+ if(psiFile instanceof JetFile) {
sourceFiles.add((JetFile)psiFile);
}
}
@@ -118,7 +109,7 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
}
public void addSources(VirtualFile vFile) {
- if (vFile.isDirectory()) {
+ if (vFile.isDirectory()) {
for (VirtualFile virtualFile : vFile.getChildren()) {
addSources(virtualFile);
}
@@ -134,9 +125,8 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
}
public void addSources(String path) {
- if (path == null) {
+ if(path == null)
return;
- }
VirtualFile vFile = getLocalFileSystem().findFileByPath(path);
if (vFile == null) {
@@ -155,17 +145,20 @@ 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) {
- for (URL url : ((URLClassLoader)loader).getURLs()) {
+ 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/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java
index 436f60bc28a..57082240c07 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
@@ -72,7 +72,7 @@ public class KotlinToJVMBytecodeCompiler {
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,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) {
@@ -132,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) {
@@ -198,7 +198,7 @@ public class KotlinToJVMBytecodeCompiler {
@Nullable
public static GenerationState analyzeAndGenerate(CompileEnvironmentConfiguration configuration) {
- return analyzeAndGenerate(configuration, configuration.getCompilerDependencies().getCompilerSpecialMode().isStubs());
+ return analyzeAndGenerate(configuration, configuration.getEnvironment().getCompilerDependencies().getCompilerSpecialMode().isStubs());
}
@Nullable
@@ -233,7 +233,7 @@ public class KotlinToJVMBytecodeCompiler {
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory.EMPTY,
- configuration.getCompilerDependencies());
+ configuration.getEnvironment().getCompilerDependencies());
}
}, environment.getSourceFiles()
);
@@ -256,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/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java
index c47411575c4..8ce7e33559e 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
@@ -959,7 +959,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));
}
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 0da95ba01fc..8b853b146f9 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
@@ -33,11 +33,9 @@ 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.Set;
+import java.util.*;
+
+import static org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer.TypeUsage.*;
/**
* @author abreslav
@@ -66,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
@@ -85,12 +85,12 @@ public class JavaTypeTransformer {
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;
@@ -136,7 +136,7 @@ public class JavaTypeTransformer {
if (psiMethod.isConstructor()) {
Set supertypesJet = Sets.newHashSet();
for (PsiClassType supertype : typeParameter.getExtendsListTypes()) {
- supertypesJet.add(transformToType(supertype, TypeUsage.UPPER_BOUND, typeVariableResolver));
+ supertypesJet.add(transformToType(supertype, UPPER_BOUND, typeVariableResolver));
}
return TypeUtils.intersect(JetTypeChecker.INSTANCE, supertypesJet);
}
@@ -144,20 +144,24 @@ public class JavaTypeTransformer {
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 =
@@ -187,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));
}
@@ -291,6 +297,7 @@ public class JavaTypeTransformer {
MEMBER_SIGNATURE_COVARIANT,
MEMBER_SIGNATURE_CONTRAVARIANT,
MEMBER_SIGNATURE_INVARIANT,
- SUPERTYPE
+ SUPERTYPE,
+ SUPERTYPE_ARGUMENT
}
}
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..3e5650d8ee6 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java
@@ -127,10 +127,20 @@ public class FunctionDescriptorUtil {
JetStandardClasses.getValueParameters(functionDescriptor, functionType),
JetStandardClasses.getReturnTypeFromFunctionType(functionType),
Modality.FINAL,
- Visibilities.LOCAL);
+ Visibilities.PUBLIC);
}
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/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
index 189655ec333..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());
}
});
@@ -403,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) {
@@ -416,7 +415,7 @@ public interface Errors {
}
else {
// safe way
- return markRange(jetDeclaration.getTextRange());
+ return markElement(jetDeclaration);
}
}
});
@@ -449,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 eb98b2857c4..0f9f14ac019 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java
@@ -59,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) {
@@ -75,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);
}
};
@@ -100,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);
}
};
}
@@ -151,4 +147,18 @@ public class PositioningStrategies {
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 dc96f771033..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;
@@ -401,6 +405,22 @@ public class DefaultErrorMessages {
"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/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/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java
index b9479f4766a..c4cac2803cd 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;
@@ -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);
@@ -128,6 +124,16 @@ public class BindingContextUtils {
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
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/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/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/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..1e699b0ca63 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,8 @@ 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);
+ prioritizedTasks.add(new ResolutionTask(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
}
else {
context.trace.report(NOT_A_CLASS.on(calleeExpression));
@@ -206,8 +205,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);
+ 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)
@@ -223,7 +222,7 @@ 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);
+ ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(functionDescriptor);
resolutionCandidate.setReceiverArgument(context.call.getExplicitReceiver());
// strictly speaking, this is a hack:
@@ -231,7 +230,7 @@ public class CallResolver {
// 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 +238,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 +247,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 +264,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 +294,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 {
@@ -329,14 +329,14 @@ public class CallResolver {
for (ResolutionCandidate candidate : task.getCandidates()) {
newCandidates.add(ResolutionCandidate.create(candidate.getDescriptor()));
}
- 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 +346,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 resolutionCandidate : task.getCandidates()) {
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(task.trace);
- CallResolutionContext context = callTransformationStrategy.createCallContext(resolutionCandidate, task, temporaryTrace, task.tracing);
- performResolutionForCandidateCall(context, task, temporaryTrace);
+ Collection> contexts = callTransformer.createCallContexts(resolutionCandidate, task, temporaryTrace);
+ Collection> calls = Lists.newArrayList();
+ for (CallResolutionContext context : contexts) {
- Collection> calls = callTransformationStrategy.transformResultCall(context, this, task);
- for (ResolvedCallImpl call : calls) {
- task.getResolvedCallMap().put(resolutionCandidate, call);
+ performResolutionForCandidateCall(context, task);
+ calls.addAll(callTransformer.transformCall(context, this, task));
+ }
+ for (ResolvedCallWithTrace call : calls) {
+
+ task.tracing.bindResolvedCall(call.getTrace(), call);
+ task.getResolvedCalls().add(call);
}
}
- Set> successfulCandidates = Sets.newLinkedHashSet();
- Set> failedCandidates = Sets.newLinkedHashSet();
- for (ResolvedCallImpl candidateCall : task.getResolvedCallMap().values()) {
+ Set> successfulCandidates = Sets.newLinkedHashSet();
+ Set> failedCandidates = Sets.newLinkedHashSet();
+ for (ResolvedCallWithTrace candidateCall : task.getResolvedCalls()) {
ResolutionStatus status = candidateCall.getStatus();
if (status.isSuccess()) {
successfulCandidates.add(candidateCall);
@@ -373,23 +378,19 @@ public class CallResolver {
}
}
- OverloadResolutionResultsImpl results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates, failedCandidates);
+ OverloadResolutionResultsImpl results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates, failedCandidates);
if (!results.isSingleResult()) {
checkTypesWithNoCallee(task.toBasic());
}
return results;
}
- private void performResolutionForCandidateCall(@NotNull CallResolutionContext context,
- @NotNull ResolutionTask task,
- @NotNull TemporaryBindingTrace temporaryTrace) {
+ private void performResolutionForCandidateCall(@NotNull CallResolutionContext context,
+ @NotNull ResolutionTask task) {
+
ResolvedCallImpl candidateCall = context.candidateCall;
-
- candidateCall.setTrace(temporaryTrace);
D candidate = candidateCall.getCandidateDescriptor();
- context.tracing.bindReference(context.trace, candidateCall);
-
if (ErrorUtils.isError(candidate)) {
candidateCall.addStatus(SUCCESS);
checkTypesWithNoCallee(context.toBasic());
@@ -477,7 +478,7 @@ public class CallResolver {
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
}
- private ResolutionStatus inferTypeArguments(CallResolutionContext context) {
+ private ResolutionStatus inferTypeArguments(CallResolutionContext context) {
ResolvedCallImpl candidateCall = context.candidateCall;
D candidate = candidateCall.getCandidateDescriptor();
@@ -624,7 +625,7 @@ public class CallResolver {
}
}
- private ResolutionStatus checkAllValueArguments(CallResolutionContext context) {
+ private ResolutionStatus checkAllValueArguments(CallResolutionContext context) {
ResolutionStatus result = checkValueArgumentTypes(context);
ResolvedCall candidateCall = context.candidateCall;
result = result.combine(checkReceiver(context, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument()));
@@ -632,7 +633,7 @@ public class CallResolver {
return result;
}
- private ResolutionStatus checkReceiver(CallResolutionContext context, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument) {
+ private ResolutionStatus checkReceiver(CallResolutionContext context, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument) {
ResolutionStatus result = SUCCESS;
if (receiverParameter.exists() && receiverArgument.exists()) {
ASTNode callOperationNode = context.call.getCallOperationNode();
@@ -660,7 +661,7 @@ public class CallResolver {
return result;
}
- private ResolutionStatus checkValueArgumentTypes(CallResolutionContext context) {
+ private ResolutionStatus checkValueArgumentTypes(CallResolutionContext context) {
ResolutionStatus result = SUCCESS;
for (Map.Entry entry : context.candidateCall.getValueArguments().entrySet()) {
ValueParameterDescriptor parameterDescriptor = entry.getKey();
@@ -734,8 +735,8 @@ public class CallResolver {
private OverloadResolutionResultsImpl computeResultAndReportErrors(
BindingTrace trace,
TracingStrategy tracing,
- Set> successfulCandidates,
- Set> failedCandidates) {
+ Set> successfulCandidates,
+ Set> failedCandidates) {
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
if (successfulCandidates.size() > 0) {
@@ -756,8 +757,8 @@ public class CallResolver {
// and some are not OK at all. In this case we'd like to say "unsafe call" rather than "none applicable"
// Used to be: weak errors. Generalized for future extensions
for (EnumSet severityLevel : SEVERITY_LEVELS) {
- Set> thisLevel = Sets.newLinkedHashSet();
- for (ResolvedCallImpl candidate : failedCandidates) {
+ Set> thisLevel = Sets.newLinkedHashSet();
+ for (ResolvedCallWithTrace candidate : failedCandidates) {
if (severityLevel.contains(candidate.getStatus())) {
thisLevel.add(candidate);
}
@@ -777,7 +778,7 @@ public class CallResolver {
assert false : "Should not be reachable, cause every status must belong to some level";
- Set> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
+ Set> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
if (noOverrides.size() != 1) {
tracing.noneApplicable(trace, noOverrides);
tracing.recordAmbiguity(trace, noOverrides);
@@ -787,7 +788,7 @@ public class CallResolver {
failedCandidates = noOverrides;
}
- ResolvedCallImpl failed = failedCandidates.iterator().next();
+ ResolvedCallWithTrace failed = failedCandidates.iterator().next();
failed.getTrace().commit();
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
}
@@ -797,18 +798,18 @@ public class CallResolver {
}
}
- private static boolean allClean(Collection> results) {
- for (ResolvedCallImpl result : results) {
+ private static boolean allClean(Collection> results) {
+ for (ResolvedCallWithTrace result : results) {
if (result.isDirty()) return false;
}
return true;
}
- private OverloadResolutionResultsImpl chooseAndReportMaximallySpecific(Set> candidates, boolean discriminateGenerics) {
+ private OverloadResolutionResultsImpl chooseAndReportMaximallySpecific(Set> candidates, boolean discriminateGenerics) {
if (candidates.size() != 1) {
- Set> cleanCandidates = Sets.newLinkedHashSet(candidates);
- for (Iterator> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
- ResolvedCallImpl candidate = iterator.next();
+ Set> cleanCandidates = Sets.newLinkedHashSet(candidates);
+ for (Iterator> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
+ ResolvedCallWithTrace candidate = iterator.next();
if (candidate.isDirty()) {
iterator.remove();
}
@@ -817,27 +818,31 @@ public class CallResolver {
if (cleanCandidates.isEmpty()) {
cleanCandidates = candidates;
}
- ResolvedCallImpl maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false);
+ ResolvedCallWithTrace maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false);
if (maximallySpecific != null) {
return OverloadResolutionResultsImpl.success(maximallySpecific);
}
if (discriminateGenerics) {
- ResolvedCallImpl maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true);
+ ResolvedCallWithTrace maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true);
if (maximallySpecificGenericsDiscriminated != null) {
return OverloadResolutionResultsImpl.success(maximallySpecificGenericsDiscriminated);
}
}
- Set> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
+ Set> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
return OverloadResolutionResultsImpl.ambiguity(noOverrides);
}
else {
- ResolvedCallImpl result = candidates.iterator().next();
+ ResolvedCallWithTrace result = candidates.iterator().next();
TemporaryBindingTrace temporaryTrace = result.getTrace();
temporaryTrace.commit();
+
+ if (result instanceof VariableAsFunctionResolvedCall) {
+ ((VariableAsFunctionResolvedCall)result).getVariableCall().getTrace().commit();
+ }
return OverloadResolutionResultsImpl.success(result);
}
}
@@ -868,13 +873,12 @@ public class CallResolver {
BindingTraceContext trace = new BindingTraceContext();
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(trace);
- Set> calls = Sets.newLinkedHashSet();
+ Set> calls = Sets.newLinkedHashSet();
for (ResolutionCandidate candidate : candidates) {
- ResolvedCallImpl call = ResolvedCallImpl.create(candidate);
- call.setTrace(temporaryBindingTrace);
+ ResolvedCallImpl call = ResolvedCallImpl.create(candidate, temporaryBindingTrace);
calls.add(call);
}
- return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, calls, Collections.>emptySet());
+ return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, calls, Collections.>emptySet());
}
private List> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver,
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformationStrategy.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformationStrategy.java
deleted file mode 100644
index 5fc68364ae5..00000000000
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformationStrategy.java
+++ /dev/null
@@ -1,118 +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.resolve.calls;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
-import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
-import org.jetbrains.jet.lang.psi.*;
-import org.jetbrains.jet.lang.resolve.BindingTrace;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author svtk
- */
-public interface CallTransformationStrategy {
-
- @NotNull
- CallResolutionContext createCallContext(@NotNull ResolutionCandidate candidate,
- @NotNull ResolutionTask task,
- @NotNull BindingTrace trace,
- @NotNull TracingStrategy tracing);
-
- @NotNull
- Collection> transformResultCall(@NotNull CallResolutionContext callResolutionContext,
- @NotNull CallResolver callResolver,
- @NotNull ResolutionTask task);
-
- CallTransformationStrategy
- PROPERTY_CALL_TRANSFORMATION_STRATEGY = new CallTransformationStrategy() {
- @NotNull
- @Override
- public CallResolutionContext createCallContext(@NotNull ResolutionCandidate candidate,
- @NotNull ResolutionTask task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing) {
- ResolvedCallImpl candidateCall = ResolvedCallImpl.create(candidate);
- return new CallResolutionContext(candidateCall, task, trace, tracing);
- }
-
- @NotNull
- @Override
- public Collection> transformResultCall(@NotNull CallResolutionContext context,
- @NotNull CallResolver callResolver, @NotNull ResolutionTask task) {
- return Collections.singleton(context.candidateCall);
- }
- };
-
- CallTransformationStrategy
- FUNCTION_CALL_TRANSFORMATION_STRATEGY = new CallTransformationStrategy() {
- @NotNull
- @Override
- public CallResolutionContext createCallContext(@NotNull ResolutionCandidate candidate,
- @NotNull ResolutionTask task,
- @NotNull BindingTrace trace,
- @NotNull TracingStrategy tracing) {
- if (candidate.getDescriptor() instanceof FunctionDescriptor) {
- return new CallResolutionContext(ResolvedCallImpl.create(candidate), task, trace, tracing);
- }
- assert candidate.getDescriptor() instanceof VariableDescriptor;
- Call propertyCall = new DelegatingCall(task.call) {
- @Override
- public JetValueArgumentList getValueArgumentList() {
- return null;
- }
-
- @NotNull
- @Override
- public List getFunctionLiteralArguments() {
- return Collections.emptyList();
- }
-
- @NotNull
- @Override
- public List getTypeArguments() {
- return Collections.emptyList();
- }
-
- @Override
- public JetTypeArgumentList getTypeArgumentList() {
- return null;
- }
- };
- return new CallResolutionContext(ResolvedCallImpl.create(candidate), task, trace, tracing, propertyCall);
- }
-
- @NotNull
- @Override
- public Collection> transformResultCall(@NotNull CallResolutionContext context,
- @NotNull CallResolver callResolver, @NotNull ResolutionTask task) {
- FunctionDescriptor descriptor = context.candidateCall.getCandidateDescriptor();
- if (descriptor instanceof FunctionDescriptor) {
- return Collections.singleton(context.candidateCall);
- }
- assert descriptor instanceof VariableDescriptor;
- BasicResolutionContext basicResolutionContext =
- BasicResolutionContext.create(context.trace, context.scope, task.call, context.expectedType, context.dataFlowInfo);
- OverloadResolutionResults results =
- callResolver.resolveCallWithGivenName(basicResolutionContext, task.reference, "invoke");
- return ((OverloadResolutionResultsImpl)results).getResultingCalls();
- }
- };
-}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java
new file mode 100644
index 00000000000..63486dee599
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java
@@ -0,0 +1,239 @@
+/*
+ * 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.calls;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
+import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
+import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
+import org.jetbrains.jet.lang.psi.*;
+import org.jetbrains.jet.lang.resolve.*;
+import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
+import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
+import org.jetbrains.jet.lang.types.JetType;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * CallTransformer treats specially 'variable as function' call case, other cases keeps unchanged (base realization).
+ *
+ * For the call 'b.foo(1)' where foo is a variable that has method 'invoke' (for example of function type)
+ * CallTransformer creates two contexts, two calls in each, and performs second ('invoke') call resolution:
+ *
+ * context#1. calls: 'b.foo' 'invoke(1)'
+ * context#2. calls: 'foo' 'b.invoke(1)'
+ *
+ * If success VariableAsFunctionResolvedCall is created.
+ *
+ * @author svtk
+ */
+public class CallTransformer {
+ private CallTransformer() {}
+
+ /**
+ * Returns two contexts for 'variable as function' case (in FUNCTION_CALL_TRANSFORMER), one context otherwise
+ */
+ @NotNull
+ public Collection> createCallContexts(@NotNull ResolutionCandidate candidate,
+ @NotNull ResolutionTask task,
+ @NotNull TemporaryBindingTrace temporaryTrace) {
+
+ ResolvedCallImpl candidateCall = ResolvedCallImpl.create(candidate, temporaryTrace);
+ return Collections.singleton(CallResolutionContext.create(candidateCall, task, temporaryTrace, task.tracing));
+ }
+
+ /**
+ * Returns collection of resolved calls for 'invoke' for 'variable as function' case (in FUNCTION_CALL_TRANSFORMER),
+ * the resolved call from callResolutionContext otherwise
+ */
+ @NotNull
+ public Collection> transformCall(@NotNull CallResolutionContext callResolutionContext,
+ @NotNull CallResolver callResolver,
+ @NotNull ResolutionTask task) {
+
+ return Collections.singleton((ResolvedCallWithTrace