diff --git a/.gitignore b/.gitignore
index 38f4c43e310..8648ec99ad4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ confluence/target
out
dist
ideaSDK
+PluginVerifier
.idea/dictionaries/yozh.xml
.idea/codeStyleSettings.xml
.idea/workspace.xml
diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 1dfe9e84ad8..4402d4e932c 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -49,6 +49,10 @@
+
+
+
+
diff --git a/.idea/libraries/asm.xml b/.idea/libraries/asm.xml
index afc4bcc3b62..d343b26b416 100644
--- a/.idea/libraries/asm.xml
+++ b/.idea/libraries/asm.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/.idea/libraries/js_libs.xml b/.idea/libraries/js_libs.xml
index e42ca339692..e8a4874bfc6 100644
--- a/.idea/libraries/js_libs.xml
+++ b/.idea/libraries/js_libs.xml
@@ -3,6 +3,9 @@
+
+
+
diff --git a/.idea/runConfigurations/Js_backend_tests.xml b/.idea/runConfigurations/Js_backend_tests.xml
new file mode 100644
index 00000000000..011469a460a
--- /dev/null
+++ b/.idea/runConfigurations/Js_backend_tests.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TeamCityBuild.xml b/TeamCityBuild.xml
index 8cdc6ea5f09..8b0f795a793 100644
--- a/TeamCityBuild.xml
+++ b/TeamCityBuild.xml
@@ -2,10 +2,15 @@
+
+
+
+
+
@@ -55,13 +60,22 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java
index 64ff3cd9c77..81d7de736da 100644
--- a/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java
+++ b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java
@@ -25,29 +25,21 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
-import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.psi.JetNamespaceHeader;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
-import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener;
-import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
-import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
-import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
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 org.jetbrains.jet.lang.types.NamespaceType;
-import org.jetbrains.jet.lang.types.TypeUtils;
-import org.jetbrains.jet.lang.types.Variance;
+import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import java.util.*;
-import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER;
-
/**
* @author Nikolay Krasko, Alefas
*/
@@ -146,7 +138,9 @@ public final class TipsManager {
return false;
}
for (ReceiverDescriptor receiverDescriptor : result) {
- if (checkReceiverResolution(receiverDescriptor, callableDescriptor)) return false;
+ if (ExpressionTypingUtils.checkIsExtensionCallable(receiverDescriptor, callableDescriptor)) {
+ return false;
+ }
}
return true;
}
@@ -183,51 +177,10 @@ public final class TipsManager {
new Predicate() {
@Override
public boolean apply(CallableDescriptor callableDescriptor) {
- return checkReceiverResolution(receiverDescriptor, callableDescriptor);
+ return ExpressionTypingUtils.checkIsExtensionCallable(receiverDescriptor, callableDescriptor);
}
}));
return descriptorsSet;
}
-
- /*
- * Checks if receiver declaration could be resolved to call expected receiver.
- */
- private static boolean checkReceiverResolution (
- @NotNull ReceiverDescriptor expectedReceiver,
- @NotNull CallableDescriptor receiverArgument
- ) {
- JetType type = expectedReceiver.getType();
- if (checkReceiverResolution(expectedReceiver, type, receiverArgument)) return true;
- if (type.isNullable()) {
- JetType notNullableType = TypeUtils.makeNotNullable(type);
- if (checkReceiverResolution(expectedReceiver, notNullableType, receiverArgument)) return true;
- }
- return false;
- }
-
- private static boolean checkReceiverResolution (
- @NotNull ReceiverDescriptor expectedReceiver,
- @NotNull JetType receiverType,
- @NotNull CallableDescriptor receiverArgument
- ) {
- ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
- for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
- constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
- }
-
- ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
- if (expectedReceiver.exists() && receiverParameter.exists()) {
- constraintSystem.addSubtypingConstraint(
- RECEIVER.assertSubtyping(receiverType, receiverParameter.getType()));
- }
- else if (expectedReceiver.exists() || receiverParameter.exists()) {
- // Only one of receivers exist
- return false;
- }
-
- ConstraintSystemSolution solution = constraintSystem.solve();
- return solution.getStatus().isSuccessful();
- }
-
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
index 62d0e459c6b..9738e1958e2 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
@@ -19,12 +19,8 @@ package org.jetbrains.jet.cli;
import com.sampullara.cli.Args;
import com.sampullara.cli.Argument;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.compiler.CompileEnvironment;
-import org.jetbrains.jet.compiler.CompileEnvironmentException;
-import org.jetbrains.jet.compiler.CompilerPlugin;
-import org.jetbrains.jet.compiler.FileNameTransformer;
+import org.jetbrains.jet.compiler.*;
-import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
/**
@@ -72,6 +68,9 @@ public class KotlinCompiler {
@Argument(value = "stubs", description = "Compile stubs: ignore function bodies")
public boolean stubs;
+ @Argument(value = "tags", description = "Demarcate each compilation message (error, warning, etc) with an open and close tag")
+ public boolean tags;
+
@Argument(value = "transformNamesToJava", description = "Transform Kotlin file names to *.java. This option is needed for compiling kotlinized Java library headers")
public boolean transformNamesToJava;
}
@@ -108,7 +107,8 @@ public class KotlinCompiler {
return 1;
}
catch (Throwable t) {
- t.printStackTrace();
+ // Always use tags
+ errStream.println(MessageRenderer.TAGS.renderException(t));
return 1;
}
@@ -117,7 +117,11 @@ public class KotlinCompiler {
return 0;
}
- CompileEnvironment environment = new CompileEnvironment(arguments.transformNamesToJava ? ANY_EXTENSION_TO_JAVA : FileNameTransformer.IDENTITY);
+ FileNameTransformer fileNameTransformer = arguments.transformNamesToJava
+ ? ANY_EXTENSION_TO_JAVA
+ : FileNameTransformer.IDENTITY;
+ MessageRenderer messageRenderer = arguments.tags ? MessageRenderer.TAGS : MessageRenderer.PLAIN;
+ CompileEnvironment environment = new CompileEnvironment(fileNameTransformer, messageRenderer);
try {
environment.setIgnoreErrors(false);
environment.setErrorStream(errStream);
@@ -138,16 +142,18 @@ public class KotlinCompiler {
if (arguments.module != null) {
environment.compileModuleScript(arguments.module, arguments.jar, arguments.outputDir, arguments.includeRuntime);
- return 0;
}
else {
- if (!environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime)) {
- return 1;
- }
+ environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime);
}
return 0;
- } finally {
+ }
+ catch (Throwable t) {
+ errStream.println(messageRenderer.renderException(t));
+ return 1;
+ }
+ finally {
environment.dispose();
}
}
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java
index a1dd8251b17..833bbf8a885 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java
@@ -55,7 +55,9 @@ import java.util.jar.*;
public class CompileEnvironment {
private JetCoreEnvironment myEnvironment;
private final Disposable myRootDisposable;
- private PrintStream myErrorStream = System.out;
+ private final MessageRenderer myMessageRenderer;
+ private PrintStream myErrorStream = System.err;
+
private final FileNameTransformer myFileNameTransformer;
private URL myStdlib;
@@ -63,10 +65,10 @@ public class CompileEnvironment {
private boolean stubs = false;
public CompileEnvironment() {
- this(FileNameTransformer.IDENTITY);
+ this(FileNameTransformer.IDENTITY, MessageRenderer.PLAIN);
}
- public CompileEnvironment(FileNameTransformer fileNameTransformer) {
+ public CompileEnvironment(FileNameTransformer fileNameTransformer, MessageRenderer messageRenderer) {
myRootDisposable = new Disposable() {
@Override
public void dispose() {
@@ -74,6 +76,7 @@ public class CompileEnvironment {
};
myEnvironment = new JetCoreEnvironment(myRootDisposable);
myFileNameTransformer = fileNameTransformer;
+ myMessageRenderer = messageRenderer;
}
public void setErrorStream(PrintStream errorStream) {
@@ -145,7 +148,7 @@ public class CompileEnvironment {
File rtJar = findRtJar(javaHome);
if (rtJar == null || !rtJar.exists()) {
- throw new CompileEnvironmentException("No JDK rt.jar found under" + javaHome);
+ throw new CompileEnvironmentException("No JDK rt.jar found under " + javaHome);
}
return rtJar;
@@ -164,8 +167,8 @@ public class CompileEnvironment {
return null;
}
- public void compileModuleScript(String moduleFile, @Nullable String jarPath, @Nullable String outputDir, boolean jarRuntime) {
- final List modules = loadModuleScript(moduleFile);
+ public boolean compileModuleScript(String moduleFile, @Nullable String jarPath, @Nullable String outputDir, boolean jarRuntime) {
+ List modules = loadModuleScript(moduleFile);
if (modules == null) {
throw new CompileEnvironmentException("Module script " + moduleFile + " compilation failed");
@@ -178,20 +181,22 @@ public class CompileEnvironment {
final String directory = new File(moduleFile).getParent();
for (Module moduleBuilder : modules) {
ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory);
- if (moduleFactory != null) {
- if (outputDir != null) {
- writeToOutputDirectory(moduleFactory, outputDir);
- }
- else {
- String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
- try {
- writeToJar(moduleFactory, new FileOutputStream(path), null, jarRuntime);
- } catch (FileNotFoundException e) {
- throw new CompileEnvironmentException("Invalid jar path " + path, e);
- }
+ if (moduleFactory == null) {
+ return false;
+ }
+ if (outputDir != null) {
+ writeToOutputDirectory(moduleFactory, outputDir);
+ }
+ else {
+ String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
+ try {
+ writeToJar(moduleFactory, new FileOutputStream(path), null, jarRuntime);
+ } catch (FileNotFoundException e) {
+ throw new CompileEnvironmentException("Invalid jar path " + path, e);
}
}
}
+ return true;
}
public List loadModuleScript(String moduleFile) {
@@ -199,7 +204,7 @@ public class CompileEnvironment {
scriptCompileSession.addSources(moduleFile);
ensureRuntime();
- if (!scriptCompileSession.analyze(myErrorStream)) {
+ if (!scriptCompileSession.analyze(myErrorStream, myMessageRenderer)) {
return null;
}
final ClassFileFactory factory = scriptCompileSession.generate();
@@ -258,7 +263,7 @@ public class CompileEnvironment {
ensureRuntime();
- if (!moduleCompileSession.analyze(myErrorStream) && !ignoreErrors) {
+ if (!moduleCompileSession.analyze(myErrorStream, myMessageRenderer) && !ignoreErrors) {
return null;
}
return moduleCompileSession.generate();
@@ -345,7 +350,7 @@ public class CompileEnvironment {
CompileSession session = new CompileSession(myEnvironment, myFileNameTransformer);
session.addSources(new LightVirtualFile("script" + LocalTimeCounter.currentTime() + ".kt", JetLanguage.INSTANCE, code));
- if (!session.analyze(myErrorStream) && !ignoreErrors) {
+ if (!session.analyze(myErrorStream, myMessageRenderer) && !ignoreErrors) {
return null;
}
@@ -370,7 +375,7 @@ public class CompileEnvironment {
ensureRuntime();
- if (!session.analyze(myErrorStream) && !ignoreErrors) {
+ if (!session.analyze(myErrorStream, myMessageRenderer) && !ignoreErrors) {
return false;
}
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
index 641376b40b4..7a63ab18823 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
+import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.diagnostics.Severity;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -41,8 +42,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.plugin.JetFileType;
-import java.io.File;
-import java.io.PrintStream;
+import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -84,11 +84,11 @@ public class CompileSession {
VirtualFile vFile = myEnvironment.getLocalFileSystem().findFileByPath(path);
if (vFile == null) {
- myErrors.add("ERROR: File/directory not found: " + path);
+ myErrors.add("File/directory not found: " + path);
return;
}
if (!vFile.isDirectory() && vFile.getFileType() != JetFileType.INSTANCE) {
- myErrors.add("ERROR: Not a Kotlin file: " + path);
+ myErrors.add("Not a Kotlin file: " + path);
return;
}
@@ -135,40 +135,26 @@ public class CompileSession {
return mySourceFiles;
}
- public boolean analyze(final PrintStream out) {
- if (!myErrors.isEmpty()) {
- for (String error : myErrors) {
- out.println(error);
- }
- return false;
+ public boolean analyze(@NotNull PrintStream out, @NotNull MessageRenderer renderer) {
+ MessageCollector collector = new MessageCollector(renderer);
+
+ for (String error : myErrors) {
+ collector.report(Severity.ERROR, error, null, -1, -1);
}
- final ErrorCollector errorCollector = new ErrorCollector();
+ reportSyntaxErrors(collector);
+ analyzeAndReportSemanticErrors(collector);
- reportSyntaxErrors(errorCollector);
- analyzeAndReportSemanticErrors(errorCollector);
+ collector.printTo(out);
-
- boolean hasIncompleteHierarchyErrors;
- Collection incompletes = myBindingContext.getKeys(BindingContext.INCOMPLETE_HIERARCHY);
- if (!incompletes.isEmpty()) {
- out.println(Severity.ERROR + ":: The following classes have incomplete hierarchies:");
- for (ClassDescriptor incomplete : incompletes) {
- out.println(Severity.ERROR + ":: " + fqName(incomplete));
- }
- hasIncompleteHierarchyErrors = true;
- } else {
- hasIncompleteHierarchyErrors = false;
- }
-
- errorCollector.flushTo(out);
- return !errorCollector.hasErrors() && !hasIncompleteHierarchyErrors;
+ return !collector.hasErrors();
}
/**
* @see JetTypeMapper#getFQName(DeclarationDescriptor)
+ * TODO possibly duplicates DescriptorUtils#getFQName(DeclarationDescriptor)
*/
- private String fqName(ClassOrNamespaceDescriptor descriptor) {
+ private static String fqName(ClassOrNamespaceDescriptor descriptor) {
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration == null || containingDeclaration instanceof ModuleDescriptor || containingDeclaration.getName().equals(JavaDescriptorResolver.JAVA_ROOT)) {
return descriptor.getName();
@@ -177,18 +163,31 @@ public class CompileSession {
}
}
- private void analyzeAndReportSemanticErrors(ErrorCollector errorCollector) {
+ private void analyzeAndReportSemanticErrors(MessageCollector collector) {
Predicate filesToAnalyzeCompletely =
stubs ? Predicates.alwaysFalse() : Predicates.alwaysTrue();
myBindingContext = AnalyzerFacade.analyzeFilesWithJavaIntegration(
myEnvironment.getProject(), mySourceFiles, filesToAnalyzeCompletely, JetControlFlowDataTraceFactory.EMPTY);
for (Diagnostic diagnostic : myBindingContext.getDiagnostics()) {
- errorCollector.report(diagnostic);
+ reportDiagnostic(collector, diagnostic);
+ }
+
+ reportIncompleteHierarchies(collector);
+ }
+
+ private void reportIncompleteHierarchies(MessageCollector collector) {
+ Collection incompletes = myBindingContext.getKeys(BindingContext.INCOMPLETE_HIERARCHY);
+ if (!incompletes.isEmpty()) {
+ StringBuilder message = new StringBuilder("The following classes have incomplete hierarchies:\n");
+ for (ClassDescriptor incomplete : incompletes) {
+ message.append(" ").append(fqName(incomplete)).append("\n");
+ }
+ collector.report(Severity.ERROR, message.toString(), null, -1, -1);
}
}
- private void reportSyntaxErrors(final ErrorCollector errorCollector) {
+ private void reportSyntaxErrors(final MessageCollector messageCollector) {
for (JetFile file : mySourceFiles) {
file.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
@@ -196,12 +195,19 @@ public class CompileSession {
String description = element.getErrorDescription();
String message = StringUtil.isEmpty(description) ? "Syntax error" : description;
Diagnostic diagnostic = DiagnosticFactory.create(Severity.ERROR, message).on(element);
- errorCollector.report(diagnostic);
+ reportDiagnostic(messageCollector, diagnostic);
}
});
}
}
+ private static void reportDiagnostic(MessageCollector collector, Diagnostic diagnostic) {
+ DiagnosticUtils.LineAndColumn lineAndColumn = DiagnosticUtils.getLineAndColumn(diagnostic);
+ VirtualFile virtualFile = diagnostic.getPsiFile().getVirtualFile();
+ String path = virtualFile == null ? null : virtualFile.getPath();
+ collector.report(diagnostic.getSeverity(), diagnostic.getMessage(), path, lineAndColumn.getLine(), lineAndColumn.getColumn());
+ }
+
@NotNull
public ClassFileFactory generate() {
Project project = myEnvironment.getProject();
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/ErrorCollector.java b/compiler/cli/src/org/jetbrains/jet/compiler/MessageCollector.java
similarity index 51%
rename from compiler/cli/src/org/jetbrains/jet/compiler/ErrorCollector.java
rename to compiler/cli/src/org/jetbrains/jet/compiler/MessageCollector.java
index 8bf506a613b..397716a7c59 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/ErrorCollector.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/MessageCollector.java
@@ -18,9 +18,8 @@ package org.jetbrains.jet.compiler;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
-import com.intellij.psi.PsiFile;
-import org.jetbrains.jet.lang.diagnostics.Diagnostic;
-import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.diagnostics.Severity;
import java.io.PrintStream;
@@ -29,27 +28,28 @@ import java.util.Collection;
/**
* @author alex.tkachman
*/
-class ErrorCollector {
- private final Multimap maps = LinkedHashMultimap.create();
+/*package*/ class MessageCollector {
+ // File path (nullable) -> error message
+ private final Multimap groupedMessages = LinkedHashMultimap.create();
+ private final MessageRenderer renderer;
private boolean hasErrors;
- public ErrorCollector() {
+ public MessageCollector(@NotNull MessageRenderer renderer) {
+ this.renderer = renderer;
}
- public void report(Diagnostic diagnostic) {
- hasErrors |= diagnostic.getSeverity() == Severity.ERROR;
- maps.put(diagnostic.getPsiFile(), diagnostic);
+ public void report(@NotNull Severity severity, @NotNull String message, @Nullable String path, int line, int column) {
+ hasErrors |= severity == Severity.ERROR;
+ groupedMessages.put(path, renderer.render(severity, message, path, line, column));
}
- public void flushTo(final PrintStream out) {
- if(!maps.isEmpty()) {
- for (PsiFile psiFile : maps.keySet()) {
- String path = psiFile.getVirtualFile().getPath();
- Collection diagnostics = maps.get(psiFile);
- for (Diagnostic diagnostic : diagnostics) {
- String position = DiagnosticUtils.formatPosition(diagnostic);
- out.println(diagnostic.getSeverity().toString() + ": " + path + ":" + position + " " + diagnostic.getMessage());
+ public void printTo(@NotNull PrintStream out) {
+ if (!groupedMessages.isEmpty()) {
+ for (String path : groupedMessages.keySet()) {
+ Collection diagnostics = groupedMessages.get(path);
+ for (String diagnostic : diagnostics) {
+ out.println(diagnostic);
}
}
}
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/MessageRenderer.java b/compiler/cli/src/org/jetbrains/jet/compiler/MessageRenderer.java
new file mode 100644
index 00000000000..4573f3d77eb
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/MessageRenderer.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2000-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.compiler;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.diagnostics.Severity;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * @author abreslav
+ */
+public interface MessageRenderer {
+
+ MessageRenderer TAGS = new MessageRenderer() {
+ private String renderWithStringSeverity(String severityString, String message, String path, int line, int column) {
+ StringBuilder out = new StringBuilder();
+ out.append("<").append(severityString);
+ if (path != null) {
+ out.append(" path=\"").append(path).append("\"");
+ out.append(" line=\"").append(line).append("\"");
+ out.append(" column=\"").append(column).append("\"");
+ }
+ out.append(">\n");
+
+ out.append(message);
+
+ out.append("").append(severityString).append(">\n");
+ return out.toString();
+ }
+
+ @Override
+ public String render(@NotNull Severity severity, @NotNull String message, @Nullable String path, int line, int column) {
+ return renderWithStringSeverity(severity.toString(), message, path, line, column);
+ }
+
+ @Override
+ public String renderException(@NotNull Throwable e) {
+ return renderWithStringSeverity("EXCEPTION", PLAIN.renderException(e), null, -1, -1);
+ }
+ };
+
+ MessageRenderer PLAIN = new MessageRenderer() {
+ @Override
+ public String render(@NotNull Severity severity, @NotNull String message, @Nullable String path, int line, int column) {
+ String position = path == null ? "" : path + ": (" + (line + ", " + column) + ") ";
+ return severity + ": " + position + message;
+ }
+
+ @Override
+ public String renderException(@NotNull Throwable e) {
+ StringWriter out = new StringWriter();
+ e.printStackTrace(new PrintWriter(out));
+ return out.toString();
+ }
+ };
+
+ String render(@NotNull Severity severity, @NotNull String message, @Nullable String path, int line, int column);
+ String renderException(@NotNull Throwable e);
+}
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 37c13801cc0..f5063500f7f 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
@@ -419,7 +419,7 @@ public class JavaDescriptorResolver {
static void checkPsiClassIsNotJet(PsiClass psiClass) {
if (psiClass instanceof JetJavaMirrorMarker) {
- throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass");
+ throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass);
}
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java
index a06b0c9a3a0..1a1a6b655ad 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java
@@ -43,7 +43,7 @@ public class DiagnosticUtils {
if (element != null) {
return atLocation(element.getContainingFile(), element.getTextRange());
}
- return "' at offset " + startOffset + " (line and file unknown)";
+ return "' at offset " + startOffset + " (line and file unknown: no PSI element)";
}
@Nullable
@@ -63,7 +63,7 @@ public class DiagnosticUtils {
@NotNull
public static String atLocation(@NotNull PsiFile file, @NotNull TextRange textRange) {
- Document document = file.getViewProvider().getDocument();//PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
+ Document document = file.getViewProvider().getDocument();
return atLocation(file, textRange, document);
}
@@ -72,31 +72,28 @@ public class DiagnosticUtils {
int offset = textRange.getStartOffset();
VirtualFile virtualFile = file.getVirtualFile();
String pathSuffix = virtualFile == null ? "" : " in " + virtualFile.getPath();
- if (document != null) {
- int lineNumber = document.getLineNumber(offset);
- int lineStartOffset = document.getLineStartOffset(lineNumber);
- int column = offset - lineStartOffset;
-
- return "' at line " + (lineNumber + 1) + ":" + (column + 1) + pathSuffix;
- }
- else {
- return "' at offset " + offset + " (line unknown)" + pathSuffix;
- }
+ return offsetToLineAndColumn(document, offset).toString() + pathSuffix;
}
- public static String formatPosition(Diagnostic diagnostic) {
+ @NotNull
+ public static LineAndColumn getLineAndColumn(@NotNull Diagnostic extends PsiElement> diagnostic) {
PsiFile file = diagnostic.getPsiFile();
Document document = file.getViewProvider().getDocument();
TextRange firstRange = diagnostic.getTextRanges().iterator().next();
- int offset = firstRange.getStartOffset();
- if (document != null) {
- int lineNumber = document.getLineNumber(offset);
- int lineStartOffset = document.getLineStartOffset(lineNumber);
- int column = offset - lineStartOffset;
+ return offsetToLineAndColumn(document, firstRange.getStartOffset());
+ }
- return "(" + (lineNumber + 1) + "," + (column + 1) + ")";
+ @NotNull
+ public static LineAndColumn offsetToLineAndColumn(Document document, int offset) {
+ if (document == null) {
+ return new LineAndColumn(-1, offset);
}
- return "(offset: " + offset + " line unknown)";
+
+ int lineNumber = document.getLineNumber(offset);
+ int lineStartOffset = document.getLineStartOffset(lineNumber);
+ int column = offset - lineStartOffset;
+
+ return new LineAndColumn(lineNumber + 1, column + 1);
}
public static void throwIfRunningOnServer(Throwable e) {
@@ -111,4 +108,31 @@ public class DiagnosticUtils {
throw new RuntimeException(e);
}
}
+
+ public static final class LineAndColumn {
+ private final int line;
+ private final int column;
+
+ public LineAndColumn(int line, int column) {
+ this.line = line;
+ this.column = column;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ // NOTE: This method is used for presenting positions to the user
+ @Override
+ public String toString() {
+ if (line < 0) {
+ return "(offset: " + column + " line unknown)";
+ }
+ return "(" + line + "," + column + ")";
+ }
+ }
}
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 aec915b4eff..bd0e8075768 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java
@@ -17,13 +17,13 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetTokens;
+import org.jetbrains.jet.util.QualifiedNamesUtil;
import java.util.Collection;
import java.util.HashSet;
@@ -37,6 +37,9 @@ public class JetPsiUtil {
public static final String NO_NAME_PROVIDED = "";
+ private JetPsiUtil() {
+ }
+
@Nullable
public static JetExpression deparenthesize(@NotNull JetExpression expression) {
if (expression instanceof JetBinaryExpressionWithTypeRHS) {
@@ -157,6 +160,32 @@ public class JetPsiUtil {
return jetClass.getName();
}
+ public static String getFQName(JetNamedFunction jetNamedFunction) {
+
+ String functionName = jetNamedFunction.getName();
+ if (functionName == null) {
+ return functionName;
+ }
+
+ @SuppressWarnings("unchecked")
+ PsiElement qualifiedElement = PsiTreeUtil.getParentOfType(
+ jetNamedFunction,
+ JetFile.class, JetClassOrObject.class, JetNamedFunction.class);
+
+ String firstPart = "";
+ if (qualifiedElement instanceof JetFile) {
+ firstPart = getFQName((JetFile) qualifiedElement);
+ }
+ else if (qualifiedElement instanceof JetClassOrObject) {
+ firstPart = getFQName((JetClassOrObject) qualifiedElement);
+ }
+ else if (qualifiedElement instanceof JetNamedFunction) {
+ firstPart = getFQName((JetNamedFunction) qualifiedElement);
+ }
+
+ return QualifiedNamesUtil.combine(firstPart, functionName);
+ }
+
@Nullable @JetElement.IfNotParsed
public static String getImportPath(JetImportDirective importDirective) {
final JetExpression importedReference = importDirective.getImportedReference();
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java
index 7d95fd82c2d..3916d795dd1 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java
@@ -68,7 +68,7 @@ public class ImportsResolver {
List importDirectives = file.getImportDirectives();
for (JetImportDirective importDirective : importDirectives) {
Collection extends DeclarationDescriptor> descriptors = importResolver.processImportReference(importDirective, namespaceScope, delayedImporter);
- if (descriptors != null && descriptors.size() == 1) {
+ if (descriptors.size() == 1) {
resolvedDirectives.put(importDirective, descriptors.iterator().next());
}
}
@@ -144,14 +144,15 @@ public class ImportsResolver {
this.firstPhase = firstPhase;
}
- @Nullable
+ @NotNull
public Collection extends DeclarationDescriptor> processImportReference(@NotNull JetImportDirective importDirective, @NotNull JetScope scope, @NotNull Importer importer) {
if (importDirective.isAbsoluteInRootNamespace()) {
trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
- return null;
+ return Collections.emptyList();
}
JetExpression importedReference = importDirective.getImportedReference();
- if (importedReference == null) return null;
+ if (importedReference == null) return Collections.emptyList();
+
Collection extends DeclarationDescriptor> descriptors;
if (importedReference instanceof JetQualifiedExpression) {
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) importedReference, scope);
@@ -163,19 +164,23 @@ public class ImportsResolver {
JetSimpleNameExpression referenceExpression = getLastReference(importedReference);
if (importDirective.isAllUnder()) {
- if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression)) return null;
+ if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression)) {
+ return Collections.emptyList();
+ }
+
for (DeclarationDescriptor descriptor : descriptors) {
importer.addAllUnderImport(descriptor);
}
- return null;
+ return Collections.emptyList();
}
String aliasName = getAliasName(importDirective);
- if (aliasName == null) return null;
+ if (aliasName == null) return Collections.emptyList();
for (DeclarationDescriptor descriptor : descriptors) {
importer.addAliasImport(descriptor, aliasName);
}
+
return descriptors;
}
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 d1d2ec9d373..83fe600bc22 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
@@ -140,7 +140,9 @@ public class CallMaker {
}
}
- public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverDescriptor explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression, @NotNull List argumentExpressions) {
+ public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverDescriptor explicitReceiver,
+ @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression,
+ @NotNull List argumentExpressions) {
List arguments = Lists.newArrayList();
for (JetExpression argumentExpression : argumentExpressions) {
arguments.add(makeValueArgument(argumentExpression, calleeExpression));
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 aace789cd3f..3d2fccd1e3c 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
@@ -366,7 +366,11 @@ public class CallResolver {
if (callElement instanceof JetBinaryExpression) {
JetBinaryExpression binaryExpression = (JetBinaryExpression) callElement;
JetSimpleNameExpression operationReference = binaryExpression.getOperationReference();
- String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ? operationReference.getText() : OperatorConventions.getNameForOperationSymbol((JetToken) operationReference.getReferencedNameElementType());
+
+ String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ?
+ operationReference.getText() :
+ OperatorConventions.getNameForOperationSymbol((JetToken) operationReference.getReferencedNameElementType());
+
JetExpression right = binaryExpression.getRight();
if (right != null) {
trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, right.getText()));
@@ -433,6 +437,7 @@ public class CallResolver {
@NotNull ResolutionTask task, @NotNull TracingStrategy tracing
) {
OverloadResolutionResultsImpl results = performResolution(trace, scope, expectedType, task, tracing);
+
// If resolution fails, we should check for some of the following situations:
// class A {
// val foo = Bar() // The following is intended to be an anonymous initializer,
@@ -448,7 +453,8 @@ public class CallResolver {
// {...} // intended to be a returned from the outer literal
// }
// }
- EnumSet someFailed = EnumSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES, OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
+ EnumSet someFailed = EnumSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES,
+ OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
if (someFailed.contains(results.getResultCode()) && !task.getCall().getFunctionLiteralArguments().isEmpty()) {
// We have some candidates that failed for some reason
// And we have a suspect: the function literal argument
@@ -658,7 +664,7 @@ public class CallResolver {
return results;
}
- private JetType getEffectiveExpectedType(ValueParameterDescriptor valueParameterDescriptor) {
+ private static JetType getEffectiveExpectedType(ValueParameterDescriptor valueParameterDescriptor) {
JetType effectiveExpectedType = valueParameterDescriptor.getVarargElementType();
if (effectiveExpectedType == null) {
effectiveExpectedType = valueParameterDescriptor.getType();
@@ -666,7 +672,7 @@ public class CallResolver {
return effectiveExpectedType;
}
- private void recordAutoCastIfNecessary(ReceiverDescriptor receiver, BindingTrace trace) {
+ private static void recordAutoCastIfNecessary(ReceiverDescriptor receiver, BindingTrace trace) {
if (receiver instanceof AutoCastReceiver) {
AutoCastReceiver autoCastReceiver = (AutoCastReceiver) receiver;
ReceiverDescriptor original = autoCastReceiver.getOriginal();
@@ -703,7 +709,9 @@ public class CallResolver {
}
}
- private void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl candidateCall, @NotNull D substitutedDescriptor) {
+ private static void replaceValueParametersWithSubstitutedOnes(
+ ResolvedCallImpl candidateCall, @NotNull D substitutedDescriptor) {
+
Map parameterMap = Maps.newHashMap();
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
@@ -726,7 +734,9 @@ public class CallResolver {
return result;
}
- private ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCallImpl candidateCall, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument, ResolutionTask task) {
+ private ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCallImpl candidateCall,
+ ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument,
+ ResolutionTask task) {
ResolutionStatus result = SUCCESS;
if (receiverParameter.exists() && receiverArgument.exists()) {
ASTNode callOperationNode = task.getCall().getCallOperationNode();
@@ -841,6 +851,7 @@ public class CallResolver {
return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls());
}
}
+
assert false : "Should not be reachable, cause every status must belong to some level";
Set> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
@@ -849,8 +860,10 @@ public class CallResolver {
tracing.recordAmbiguity(trace, noOverrides);
return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides);
}
+
failedCandidates = noOverrides;
}
+
ResolvedCallImpl failed = failedCandidates.iterator().next();
failed.getTrace().commit();
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
@@ -861,7 +874,7 @@ public class CallResolver {
}
}
- private boolean allClean(Collection> results) {
+ private static boolean allClean(Collection> results) {
for (ResolvedCallImpl result : results) {
if (result.isDirty()) return false;
}
@@ -939,7 +952,8 @@ public class CallResolver {
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.>emptySet());
}
- private List> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List parameterTypes) {
+ private List> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver,
+ String name, List parameterTypes) {
List> result = Lists.newArrayList();
if (receiver.exists()) {
Collection> extensionFunctionDescriptors = ResolvedCallImpl.convertCollection(scope.getFunctions(name));
@@ -966,7 +980,8 @@ public class CallResolver {
}
}
- private boolean lookupExactSignature(Collection> candidates, List parameterTypes, List> result) {
+ private static boolean lookupExactSignature(Collection> candidates, List parameterTypes,
+ List> result) {
boolean found = false;
for (ResolvedCallImpl resolvedCall : candidates) {
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
@@ -979,7 +994,8 @@ public class CallResolver {
return found;
}
- private boolean findExtensionFunctions(Collection> candidates, ReceiverDescriptor receiver, List parameterTypes, List> result) {
+ private boolean findExtensionFunctions(Collection> candidates, ReceiverDescriptor receiver,
+ List parameterTypes, List> result) {
boolean found = false;
for (ResolvedCallImpl resolvedCall : candidates) {
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
@@ -994,7 +1010,7 @@ public class CallResolver {
return found;
}
- private boolean checkValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull List parameterTypes) {
+ private static boolean checkValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull List parameterTypes) {
List valueParameters = functionDescriptor.getValueParameters();
if (valueParameters.size() != parameterTypes.size()) return false;
for (int i = 0; i < valueParameters.size(); i++) {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/DelegatingCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/DelegatingCall.java
index 6112c8e274a..17b50671f80 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/DelegatingCall.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/DelegatingCall.java
@@ -84,8 +84,8 @@ public class DelegatingCall implements Call {
return delegate.getTypeArgumentList();
}
+ @NotNull
@Override
- @Nullable
public PsiElement getCallElement() {
return delegate.getCallElement();
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java
index 595c11f8a22..f16bacc72fa 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java
@@ -168,7 +168,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
candidateCall.recordValueArgument(valueParameter, new VarargValueArgument());
}
else {
- // tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
+ // tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
tracing.noValueForParameter(temporaryTrace, valueParameter);
error = true;
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintType.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintType.java
index cccbe65b914..333e6c40a2a 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintType.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintType.java
@@ -22,6 +22,8 @@ import org.jetbrains.jet.lang.types.JetType;
import java.text.MessageFormat;
/**
+ * A specific type for subtype constraint of types.
+ *
* @author abreslav
*/
public enum ConstraintType implements Comparable {
@@ -33,7 +35,7 @@ public enum ConstraintType implements Comparable {
EXPECTED_TYPE("Resulting type is {0} but {1} was expected"),
PARAMETER_BOUND("Type parameter bound is not satisfied: {0} is not a subtype of {1}");
- private final String errorMessageTemplate; // {0} is subtype, {1} is supertye
+ private final String errorMessageTemplate; // {0} is subtype, {1} is supertype
private ConstraintType(@NotNull String errorMessageTemplate) {
this.errorMessageTemplate = errorMessageTemplate;
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java
index d2ae4d7f0c1..e62052e741f 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java
@@ -35,7 +35,7 @@ public final class JetScopeUtils {
/**
* Get receivers in order of locality, so that the closest (the most local) receiver goes first
- * A wrapper for {@link JetScope#getImplicitReceiversHierarchy(java.util.List)}
+ * A wrapper for {@link JetScope#getImplicitReceiversHierarchy(List)}
*
* @param scope Scope for getting receivers hierarchy.
* @return receivers hierarchy.
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java
index 1cd5fe7bc1f..9fcaa801c48 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java
@@ -347,7 +347,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
return null;
}
- private static OverloadResolutionResults resolveFakeCall(ExpressionReceiver receiver, ExpressionTypingContext context, String name) {
+ public static OverloadResolutionResults resolveFakeCall(ExpressionReceiver receiver,
+ ExpressionTypingContext context, String name) {
JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.getProject(), "fake");
BindingTrace fakeTrace = new BindingTraceContext();
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.emptyList());
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java
index 8f80cc88cc2..1576399b249 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java
@@ -42,6 +42,9 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.AUTOCAST;
* @author abreslav
*/
public class DataFlowUtils {
+ private DataFlowUtils() {
+ }
+
@NotNull
public static DataFlowInfo extractDataFlowInfoFromCondition(@Nullable JetExpression condition, final boolean conditionValue, @Nullable final WritableScope scopeToExtend, final ExpressionTypingContext context) {
if (condition == null) return context.dataFlowInfo;
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java
index 9e2ef4b0e3e..8d854b63269 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java
@@ -25,24 +25,22 @@ import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
-import org.jetbrains.jet.lang.psi.JetExpression;
-import org.jetbrains.jet.lang.psi.JetPattern;
-import org.jetbrains.jet.lang.psi.JetPsiFactory;
-import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
-import org.jetbrains.jet.lang.resolve.BindingContextUtils;
-import org.jetbrains.jet.lang.resolve.BindingTrace;
-import org.jetbrains.jet.lang.resolve.BindingTraceContext;
-import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler;
+import org.jetbrains.jet.lang.psi.*;
+import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
-import org.jetbrains.jet.lang.resolve.scopes.JetScope;
-import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
-import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
+import org.jetbrains.jet.lang.resolve.calls.inference.*;
+import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
+import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
+import org.jetbrains.jet.lang.types.Variance;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -53,7 +51,10 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*;
* @author abreslav
*/
public class ExpressionTypingUtils {
-
+
+ private ExpressionTypingUtils() {
+ }
+
@Nullable
protected static ExpressionReceiver getExpressionReceiver(@NotNull JetExpression expression, @Nullable JetType type) {
if (type == null) return null;
@@ -165,4 +166,84 @@ public class ExpressionTypingUtils {
);
return ControlStructureTypingVisitor.checkIterableConvention(expressionReceiver, context) != null;
}
+
+ /**
+ * Check that function or property with the given qualified name can be resolved in given scope and called on given receiver
+ *
+ * @param callableFQN
+ * @param project
+ * @param scope
+ * @return
+ */
+ public static List canFindSuitableCall(
+ @NotNull String callableFQN,
+ @NotNull Project project,
+ @NotNull JetExpression receiverExpression,
+ @NotNull JetType receiverType,
+ @NotNull JetScope scope) {
+
+ WritableScopeWithImports writableScopeWithImports = new WritableScopeImpl(
+ scope, scope.getContainingDeclaration(), RedeclarationHandler.DO_NOTHING);
+
+ JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, callableFQN);
+
+ ImportsResolver.ImportResolver importResolver = new ImportsResolver.ImportResolver(new BindingTraceContext(), false);
+ Collection extends DeclarationDescriptor> declarationDescriptors = importResolver.processImportReference(
+ importDirective, scope,
+ new Importer.StandardImporter(writableScopeWithImports, false));
+
+ List callableExtensionDescriptors = new ArrayList();
+ ReceiverDescriptor receiverDescriptor = new ExpressionReceiver(receiverExpression, receiverType);
+
+ for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
+ if (declarationDescriptor instanceof CallableDescriptor) {
+ CallableDescriptor callableDescriptor = (CallableDescriptor) declarationDescriptor;
+
+ if (checkIsExtensionCallable(receiverDescriptor, callableDescriptor)) {
+ callableExtensionDescriptors.add(callableDescriptor);
+ }
+ }
+ }
+
+ return callableExtensionDescriptors;
+ }
+
+ /*
+ * Checks if receiver declaration could be resolved to call expected receiver.
+ */
+ public static boolean checkIsExtensionCallable (
+ @NotNull ReceiverDescriptor expectedReceiver,
+ @NotNull CallableDescriptor receiverArgument
+ ) {
+ JetType type = expectedReceiver.getType();
+ if (checkReceiverResolution(expectedReceiver, type, receiverArgument)) return true;
+ if (type.isNullable()) {
+ JetType notNullableType = TypeUtils.makeNotNullable(type);
+ if (checkReceiverResolution(expectedReceiver, notNullableType, receiverArgument)) return true;
+ }
+ return false;
+ }
+
+ private static boolean checkReceiverResolution (
+ @NotNull ReceiverDescriptor expectedReceiver,
+ @NotNull JetType receiverType,
+ @NotNull CallableDescriptor receiverArgument
+ ) {
+ ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
+ for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
+ constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
+ }
+
+ ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
+ if (expectedReceiver.exists() && receiverParameter.exists()) {
+ constraintSystem.addSubtypingConstraint(ConstraintType.RECEIVER.assertSubtyping(receiverType, receiverParameter.getType()));
+ }
+ else if (expectedReceiver.exists() || receiverParameter.exists()) {
+ // Only one of receivers exist
+ return false;
+ }
+
+ ConstraintSystemSolution solution = constraintSystem.solve();
+ return solution.getStatus().isSuccessful();
+ }
}
diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java
index 2cc50f58962..234b001ecfe 100644
--- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java
+++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java
@@ -209,4 +209,13 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa
public Icon getElementIcon(final int flags) {
return PsiClassImplUtil.getClassIcon(flags, this);
}
+
+ @Override
+ public String toString() {
+ try {
+ return JetLightClass.class.getSimpleName() + ":" + getQualifiedName();
+ } catch (Throwable e) {
+ return JetLightClass.class.getSimpleName() + ":" + e.toString();
+ }
+ }
}
diff --git a/compiler/tests/compiler-tests.iml b/compiler/tests/compiler-tests.iml
index e3a58fc3f6e..eee45ec38be 100644
--- a/compiler/tests/compiler-tests.iml
+++ b/compiler/tests/compiler-tests.iml
@@ -13,6 +13,7 @@
+
diff --git a/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java b/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java
index 422c9720536..12c982495df 100644
--- a/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java
+++ b/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java
@@ -99,7 +99,7 @@ public class ForTestCompileStdlib {
private static void compileKotlinPartOfStdlib(File destdir) throws IOException {
// lame
- KotlinCompiler.exec("-output", destdir.getPath(), "-src", "./stdlib/ktSrc", "-stdlib", destdir.getAbsolutePath());
+ KotlinCompiler.exec(System.err, "-output", destdir.getPath(), "-src", "./stdlib/ktSrc", "-stdlib", destdir.getAbsolutePath());
}
private static List javaFilesInDir(File dir) {
diff --git a/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java
index c64bc07a62b..2336c3e013d 100644
--- a/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java
+++ b/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java
@@ -22,6 +22,7 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jetbrains.jet.compiler.CompileSession;
+import org.jetbrains.jet.compiler.MessageRenderer;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDeclaration;
@@ -84,7 +85,7 @@ public class TestlibTest extends CodegenTestCase {
session.addSources(localFileSystem.findFileByPath(JetParsingTest.getTestDataDir() + "/../../testlib/test"));
session.addSources(localFileSystem.findFileByPath(JetParsingTest.getTestDataDir() + "/../../kunit/src"));
- if (!session.analyze(System.err)) {
+ if (!session.analyze(System.err, MessageRenderer.PLAIN)) {
throw new RuntimeException("There were compilation errors");
}
diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JavaToJetCompletionResolver.java b/idea/src/org/jetbrains/jet/plugin/caches/JavaToJetCompletionResolver.java
deleted file mode 100644
index de587c0abbb..00000000000
--- a/idea/src/org/jetbrains/jet/plugin/caches/JavaToJetCompletionResolver.java
+++ /dev/null
@@ -1,72 +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.plugin.caches;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiModifier;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.PsiShortNamesCache;
-import com.intellij.xml.impl.schema.TypeDescriptor;
-import org.jetbrains.jet.lang.resolve.java.JvmAbi;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Get jet declarations from java that could be used in completion. Unlike the real jet resolver this helper is allowed
- * to return partially unresolved descriptors in exchange of execution speed.
- *
- * @author Nikolay Krasko
- */
-class JetFromJavaDescriptorHelper {
-
- private JetFromJavaDescriptorHelper() {
- }
-
- /**
- * Get java equivalents for jet top level classes.
- */
- static PsiClass[] getClassesForJetNamespaces(Project project, GlobalSearchScope scope) {
- return PsiShortNamesCache.getInstance(project).getClassesByName(JvmAbi.PACKAGE_CLASS, scope);
- }
-
- /**
- * Get names that could have jet descriptor equivalents. It could be inaccurate and return more results than necessary.
- */
- static Collection getPossiblePackageDeclarationsNames(Project project, GlobalSearchScope scope) {
- final ArrayList result = new ArrayList();
-
- for (PsiClass jetNamespaceClass : getClassesForJetNamespaces(project, scope)) {
- for (PsiMethod psiMethod : jetNamespaceClass.getMethods()) {
- if (psiMethod.getModifierList().hasModifierProperty(PsiModifier.STATIC)) {
- result.add(psiMethod.getName());
- }
- }
- }
-
- return result;
- }
-
- static Collection getTopExtensionFunctionNames(TypeDescriptor typeDescriptor, Project project,
- GlobalSearchScope scope) {
-
- return getPossiblePackageDeclarationsNames(project, scope);
- }
-
-}
diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java
new file mode 100644
index 00000000000..50f95fb2150
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java
@@ -0,0 +1,134 @@
+/*
+ * 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.plugin.caches;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
+import com.intellij.psi.impl.java.stubs.index.JavaMethodNameIndex;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.util.PsiTreeUtil;
+import jet.runtime.typeinfo.JetValueParameter;
+import org.jetbrains.jet.lang.resolve.java.JvmAbi;
+import org.jetbrains.jet.lang.resolve.java.kt.JetValueParameterAnnotation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Get jet declarations from java that could be used in completion. Unlike the real jet resolver this helper is allowed
+ * to return partially unresolved descriptors in exchange of execution speed.
+ *
+ * @author Nikolay Krasko
+ */
+class JetFromJavaDescriptorHelper {
+
+ private JetFromJavaDescriptorHelper() {
+ }
+
+ /**
+ * Get java equivalents for jet top level classes.
+ */
+ static PsiClass[] getClassesForJetNamespaces(Project project, GlobalSearchScope scope) {
+ return PsiShortNamesCache.getInstance(project).getClassesByName(JvmAbi.PACKAGE_CLASS, scope);
+ }
+
+ /**
+ * Get names that could have jet descriptor equivalents. It could be inaccurate and return more results than necessary.
+ */
+ static Collection getPossiblePackageDeclarationsNames(Project project, GlobalSearchScope scope) {
+ Collection result = new ArrayList();
+
+ for (PsiClass jetNamespaceClass : getClassesForJetNamespaces(project, scope)) {
+ for (PsiMethod psiMethod : jetNamespaceClass.getMethods()) {
+ if (psiMethod.getModifierList().hasModifierProperty(PsiModifier.STATIC)) {
+ result.add(psiMethod.getName());
+ }
+ }
+ }
+
+ return result;
+ }
+
+ static Collection getTopExtensionFunctionNames(Project project, GlobalSearchScope scope) {
+
+ // Extension function should have an parameter of type JetValueParameter with explicit receiver parameter.
+
+ Set extensionNames = new HashSet();
+
+ Collection valueParametersAnnotations = JavaAnnotationIndex.getInstance().get(
+ JetValueParameter.class.getSimpleName(), project, scope);
+
+ for (PsiAnnotation parameterAnnotation : valueParametersAnnotations) {
+ String qualifiedName = parameterAnnotation.getQualifiedName();
+
+ if (qualifiedName == null || !qualifiedName.equals(JetValueParameter.class.getCanonicalName())) {
+ continue;
+ }
+
+ if (!new JetValueParameterAnnotation(parameterAnnotation).receiver()) {
+ continue;
+ }
+
+ PsiMethod psiMethod = PsiTreeUtil.getParentOfType(parameterAnnotation, PsiMethod.class);
+ if (psiMethod != null) {
+ extensionNames.add(psiMethod.getName());
+ }
+ }
+
+ return extensionNames;
+ }
+
+ static Collection getTopExtensionFunctionByName(String name, Project project, GlobalSearchScope scope) {
+
+ Set selectedMethods = new HashSet();
+
+ Collection psiMethods = JavaMethodNameIndex.getInstance().get(name, project, scope);
+ for (PsiMethod psiMethod : psiMethods) {
+ if (psiMethod == null) {
+ continue;
+ }
+
+ // Check this is top level function
+ PsiClass containingClass = psiMethod.getContainingClass();
+ if (containingClass == null || !JvmAbi.PACKAGE_CLASS.equals(containingClass.getName())) {
+ continue;
+ }
+
+ // Should be parameter with JetValueParameter.receiver == true
+ for (PsiParameter parameter : psiMethod.getParameterList().getParameters()) {
+ PsiModifierList modifierList = parameter.getModifierList();
+ if (modifierList != null) {
+ for (PsiAnnotation psiAnnotation : modifierList.getAnnotations()) {
+ if (!JetValueParameter.class.getCanonicalName().equals(psiAnnotation.getQualifiedName())) {
+ continue;
+ }
+
+ if (new JetValueParameterAnnotation(psiAnnotation).receiver()) {
+ selectedMethods.add(psiMethod);
+ }
+ }
+ }
+ }
+ }
+
+ return selectedMethods;
+ }
+}
diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java
index 1a1ce427549..7daa7a2db95 100644
--- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java
+++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java
@@ -20,20 +20,20 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.asJava.JavaElementFinder;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.resolve.BindingContext;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
import org.jetbrains.jet.plugin.stubindex.JetExtensionFunctionNameIndex;
import org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex;
@@ -68,8 +68,8 @@ public class JetShortNamesCache extends PsiShortNamesCache {
@NotNull
@Override
public String[] getAllClassNames() {
- final Collection classNames = JetShortClassNameIndex.getInstance().getAllKeys(project);
- return classNames.toArray(new String[classNames.size()]);
+ Collection classNames = JetShortClassNameIndex.getInstance().getAllKeys(project);
+ return ArrayUtil.toStringArray(classNames);
}
/**
@@ -77,10 +77,10 @@ public class JetShortNamesCache extends PsiShortNamesCache {
*/
@NotNull
@Override
- public PsiClass[] getClassesByName(@NotNull @NonNls final String name, @NotNull GlobalSearchScope scope) {
+ public PsiClass[] getClassesByName(@NotNull @NonNls String name, @NotNull GlobalSearchScope scope) {
// Quick check for classes from getAllClassNames()
- final Collection classNames = JetShortClassNameIndex.getInstance().getAllKeys(project);
+ Collection classNames = JetShortClassNameIndex.getInstance().getAllKeys(project);
if (!classNames.contains(name)) {
return new PsiClass[0];
}
@@ -89,7 +89,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) {
if (QualifiedNamesUtil.fqnToShortName(fqName).equals(name)) {
- final PsiClass psiClass = javaElementFinder.findClass(fqName, scope);
+ PsiClass psiClass = javaElementFinder.findClass(fqName, scope);
if (psiClass != null) {
result.add(psiClass);
}
@@ -104,14 +104,14 @@ public class JetShortNamesCache extends PsiShortNamesCache {
// TODO: Implement it. Is it called somewhere?
}
- public Collection getALlJetClassFQNames() {
- final BindingContext context = getResolutionContext(GlobalSearchScope.allScope(project));
- return context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR);
- }
+// public Collection getALlJetClassFQNames() {
+// final BindingContext context = getResolutionContext(GlobalSearchScope.allScope(project));
+// return context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR);
+// }
@NotNull
public Collection getFQNamesByName(@NotNull final String name, @NotNull GlobalSearchScope scope) {
- final BindingContext context = getResolutionContext(scope);
+ BindingContext context = getResolutionContext(scope);
return Collections2.filter(context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR), new Predicate() {
@Override
public boolean apply(@Nullable String fqName) {
@@ -128,26 +128,24 @@ public class JetShortNamesCache extends PsiShortNamesCache {
*/
@NotNull
public Collection getAllTopLevelFunctionNames() {
- final HashSet functionNames = new HashSet();
+ Set functionNames = new HashSet();
functionNames.addAll(JetShortFunctionNameIndex.getInstance().getAllKeys(project));
functionNames.addAll(JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(project, GlobalSearchScope.allScope(project)));
return functionNames;
}
@NotNull
- public Collection getTopLevelFunctionDescriptorsByName(final @NotNull String name,
- final @NotNull GlobalSearchScope scope) {
+ public Collection getTopLevelFunctionDescriptorsByName(@NotNull String name,
+ @NotNull GlobalSearchScope scope) {
- // TODO: Add jet function in jar-dependencies (those functions are missing in BindingContext and stubs)
-
- final Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope);
+ Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope);
- final BindingContext context = getResolutionContext(scope);
+ BindingContext context = getResolutionContext(scope);
- final HashSet result = new HashSet();
+ HashSet result = new HashSet();
for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
- final SimpleFunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, jetNamedFunction);
+ SimpleFunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, jetNamedFunction);
if (functionDescriptor != null) {
result.add(functionDescriptor);
}
@@ -157,11 +155,11 @@ public class JetShortNamesCache extends PsiShortNamesCache {
}
@NotNull
- public BindingContext getResolutionContext(final @NotNull GlobalSearchScope scope) {
+ public BindingContext getResolutionContext(@NotNull GlobalSearchScope scope) {
return WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, scope);
}
- public Collection getTopLevelFunctionsByName(final @NotNull String name, @NotNull GlobalSearchScope scope) {
+ public Collection getTopLevelFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
return JetShortFunctionNameIndex.getInstance().get(name, project, scope);
}
@@ -173,35 +171,28 @@ public class JetShortNamesCache extends PsiShortNamesCache {
*/
@NotNull
public Collection getAllJetExtensionFunctionsNames(@NotNull GlobalSearchScope scope) {
- final Set extensionFunctionNames = new HashSet();
+ Set extensionFunctionNames = new HashSet();
extensionFunctionNames.addAll(JetExtensionFunctionNameIndex.getInstance().getAllKeys(project));
- extensionFunctionNames.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionNames(null, project, scope));
+ extensionFunctionNames.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionNames(project, scope));
return extensionFunctionNames;
}
- public Collection getAllJetExtensionFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
- // TODO: Add jet extension functions in jar-dependencies (those functions are missing in BindingContext and stubs)
+ public Collection getJetExtensionFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
+ HashSet functions = new HashSet();
+ functions.addAll(JetExtensionFunctionNameIndex.getInstance().get(name, project, scope));
+ functions.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionByName(name, project, scope));
- final Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope);
+ return functions;
+ }
- final BindingContext context = getResolutionContext(scope);
+ public Collection getJetFunctionsByName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope) {
+ return JetShortFunctionNameIndex.getInstance().get(name, project, scope);
+ }
- final HashSet result = new HashSet();
-
- for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
- final SimpleFunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, jetNamedFunction);
- if (functionDescriptor != null) {
- if (functionDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
- if (functionDescriptor.getExpectedThisObject() != ReceiverDescriptor.NO_RECEIVER) {
- result.add(functionDescriptor);
- }
- }
- }
- }
-
- return result;
+ public Collection getAllJetFunctionsNames() {
+ return JetShortFunctionNameIndex.getInstance().getAllKeys(project);
}
@NotNull
@@ -219,11 +210,12 @@ public class JetShortNamesCache extends PsiShortNamesCache {
@NotNull
@Override
public String[] getAllMethodNames() {
- return new String[0];
+ return ArrayUtil.EMPTY_STRING_ARRAY;
}
@Override
public void getAllMethodNames(@NotNull HashSet set) {
+ set.addAll(JetShortFunctionNameIndex.getInstance().getAllKeys(project));
}
@NotNull
@@ -235,7 +227,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
@NotNull
@Override
public String[] getAllFieldNames() {
- return new String[0];
+ return ArrayUtil.EMPTY_STRING_ARRAY;
}
@Override
diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java
index bd42098adec..04c0a6bebe7 100644
--- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java
+++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java
@@ -37,6 +37,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Chunk;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.diagnostics.Severity;
import org.jetbrains.jet.plugin.JetFileType;
import java.io.*;
@@ -199,10 +201,10 @@ public class JetCompiler implements TranslatingCompiler {
try {
String line = reader.readLine();
if (line == null) break;
- listener.onTextAvailable(new ProcessEvent(NullProcessHandler.INSTANCE, line), ProcessOutputTypes.STDOUT);
+ listener.onTextAvailable(new ProcessEvent(NullProcessHandler.INSTANCE, line + "\n"), ProcessOutputTypes.STDERR);
} catch (IOException e) {
// Can't be
- throw new RuntimeException(e);
+ throw new IllegalStateException(e);
}
}
@@ -218,7 +220,7 @@ public class JetCompiler implements TranslatingCompiler {
Class> kompiler = Class.forName(compilerClassName, true, loader);
Method exec = kompiler.getDeclaredMethod("exec", PrintStream.class, String[].class);
- String[] arguments = { "-module", scriptFile.getAbsolutePath(), "-output", path(outputDir) };
+ String[] arguments = { "-module", scriptFile.getAbsolutePath(), "-output", path(outputDir), "-tags" };
context.addMessage(INFORMATION, "Using kotlinHome=" + kotlinHome, "", -1, -1);
context.addMessage(INFORMATION, "Invoking in-process compiler " + compilerClassName + " with arguments " + Arrays.asList(arguments), "", -1, -1);
@@ -228,7 +230,7 @@ public class JetCompiler implements TranslatingCompiler {
return ((Integer) rc).intValue();
}
else {
- throw new RuntimeException("Unexpected return: " + rc);
+ throw new IllegalStateException("Unexpected return: " + rc);
}
} catch (Throwable e) {
LOG.error(e);
@@ -267,6 +269,7 @@ public class JetCompiler implements TranslatingCompiler {
params.setMainClass("org.jetbrains.jet.cli.KotlinCompiler");
params.getProgramParametersList().add("-module", scriptFile.getAbsolutePath());
params.getProgramParametersList().add("-output", path(outputDir));
+ params.getProgramParametersList().add("-tags");
for (File jar : kompilerClasspath(kotlinHome, compileContext)) {
params.getClassPath().add(jar);
@@ -302,77 +305,7 @@ public class JetCompiler implements TranslatingCompiler {
}
private static ProcessAdapter createProcessListener(final CompileContext compileContext) {
- return new ProcessAdapter() {
- StringBuilder stderr = null;
-
- @Override
- public void onTextAvailable(ProcessEvent event, Key outputType) {
- String text = event.getText();
- String levelCode = parsePrefix(text);
- if (outputType == ProcessOutputTypes.STDERR) {
- if (stderr == null) {
- stderr = new StringBuilder();
- }
- stderr.append(text);
- return;
- }
- if (levelCode != null) {
- CompilerMessageCategory category = categories.get(levelCode);
- text = text.substring(levelCode.length());
-
- String path = "";
- int line = -1;
- int column = -1;
- int colonIndex = text.indexOf(':');
- if (text.startsWith(":")) {
- text = text.substring(1);
- } else if (colonIndex > 0) {
- path = "file://" + text.substring(0, colonIndex).trim();
- text = text.substring(colonIndex + 1);
-
- Pattern position = Pattern.compile("\\((\\d+),\\s*(\\d+)\\)");
-
- Matcher matcher = position.matcher(text);
- if (matcher.find()) {
- line = Integer.parseInt(matcher.group(1));
- column = Integer.parseInt(matcher.group(2));
- text = text.substring(matcher.group(0).length());
- }
- }
-
- compileContext.addMessage(category, text, path, line, column);
- }
- else {
- compileContext.addMessage(INFORMATION, text, "", -1, -1);
- }
- }
-
- @Override
- public void processTerminated(ProcessEvent event) {
- if (event.getExitCode() != 0) {
- compileContext.addMessage(ERROR, "Compiler terminated with exit code: " + event.getExitCode(), "", -1, -1);
- }
- // By alex.tkachman:
- if (stderr != null) {
- compileContext.addMessage(ERROR, "stderr output:\r\n" + stderr.toString(), "", -1, -1);
- }
- }
- };
- }
-
- private static String[] messagePrefixes = new String[] {"ERROR:", "WARNING:", "INFO:"} ;
- private static Map categories = new HashMap();
- static {
- categories.put("ERROR:", ERROR);
- categories.put("WARNING:", WARNING);
- categories.put("INFORMATION:", INFORMATION);
- }
-
- private static String parsePrefix(String message) {
- for (String prefix : messagePrefixes) {
- if (message.startsWith(prefix)) return prefix;
- }
- return null;
+ return new CompilerProcessListener(compileContext);
}
private static String path(VirtualFile root) {
@@ -406,4 +339,167 @@ public class JetCompiler implements TranslatingCompiler {
throw new UnsupportedOperationException("getProcessInput is not implemented");
}
}
+
+ private static class CompilerProcessListener extends ProcessAdapter {
+ private static final Pattern DIAGNOSTIC_PATTERN = Pattern.compile("<(ERROR|WARNING|INFO|EXCEPTION)", Pattern.MULTILINE);
+ private static final Pattern OPEN_TAG_END_PATTERN = Pattern.compile(">", Pattern.MULTILINE | Pattern.DOTALL);
+ private static final Pattern ATTRIBUTE_PATTERN = Pattern.compile("\\s*(path|line|column)\\s*=\\s*\"(.*?)\"", Pattern.MULTILINE | Pattern.DOTALL);
+ private static final Pattern MESSAGE_PATTERN = Pattern.compile("(.*?)(ERROR|WARNING|INFO|EXCEPTION)>", Pattern.MULTILINE | Pattern.DOTALL);
+
+ private enum State {
+ WAITING, ATTRIBUTES, MESSAGE
+ }
+
+ private static class CompilerMessage {
+ private CompilerMessageCategory messageCategory;
+ private boolean isException;
+ private @Nullable String url;
+ private @Nullable Integer line;
+ private @Nullable Integer column;
+ private String message;
+
+ public void setMessageCategoryFromString(String tagName) {
+ boolean exception = "EXCEPTION".equals(tagName);
+ if (Severity.ERROR.toString().equals(tagName) || exception) {
+ messageCategory = ERROR;
+ isException = exception;
+ }
+ else if (Severity.WARNING.toString().equals(tagName)) {
+ messageCategory = WARNING;
+ }
+ else {
+ messageCategory = INFORMATION;
+ }
+ }
+
+ public void setAttributeFromStrings(String name, String value) {
+ if ("path".equals(name)) {
+ url = "file://" + value.trim();
+ }
+ else if ("line".equals(name)) {
+ line = safeParseInt(value);
+ }
+ else if ("column".equals(name)) {
+ column = safeParseInt(value);
+ }
+ }
+
+ @Nullable
+ private static Integer safeParseInt(String value) {
+ try {
+ return Integer.parseInt(value.trim());
+ }
+ catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public void reportTo(CompileContext compileContext) {
+ compileContext.addMessage(messageCategory, message, url == null ? "" : url, line == null ? -1 : line, column == null ? -1 : column);
+ if (isException) {
+ LOG.error(message);
+ }
+ }
+ }
+
+ private final CompileContext compileContext;
+ private final StringBuilder output = new StringBuilder();
+ private int firstUnprocessedIndex = 0;
+ private State state = State.WAITING;
+ private CompilerMessage currentCompilerMessage;
+
+ public CompilerProcessListener(CompileContext compileContext) {
+ this.compileContext = compileContext;
+ }
+
+ @Override
+ public void onTextAvailable(ProcessEvent event, Key outputType) {
+ String text = event.getText();
+ if (outputType == ProcessOutputTypes.STDERR) {
+ output.append(text);
+
+ // We loop until the state stabilizes
+ State lastState;
+ do {
+ lastState = state;
+ switch (state) {
+ case WAITING: {
+ Matcher matcher = matcher(DIAGNOSTIC_PATTERN);
+ if (find(matcher)) {
+ currentCompilerMessage = new CompilerMessage();
+ currentCompilerMessage.setMessageCategoryFromString(matcher.group(1));
+ state = State.ATTRIBUTES;
+ }
+ break;
+ }
+ case ATTRIBUTES: {
+ Matcher matcher = matcher(ATTRIBUTE_PATTERN);
+ int indexDelta = 0;
+ while (matcher.find()) {
+ handleSkippedOutput(output.subSequence(firstUnprocessedIndex + indexDelta, firstUnprocessedIndex + matcher.start()));
+ currentCompilerMessage.setAttributeFromStrings(matcher.group(1), matcher.group(2));
+ indexDelta = matcher.end();
+
+ }
+ firstUnprocessedIndex += indexDelta;
+
+ Matcher endMatcher = matcher(OPEN_TAG_END_PATTERN);
+ if (find(endMatcher)) {
+ state = State.MESSAGE;
+ }
+ break;
+ }
+ case MESSAGE: {
+ Matcher matcher = matcher(MESSAGE_PATTERN);
+ if (find(matcher)) {
+ currentCompilerMessage.setMessage(matcher.group(1));
+ currentCompilerMessage.reportTo(compileContext);
+ state = State.WAITING;
+ }
+ break;
+ }
+ }
+ }
+ while (state != lastState);
+
+ }
+ else {
+ compileContext.addMessage(INFORMATION, text, "", -1, -1);
+ }
+ }
+
+ private boolean find(Matcher matcher) {
+ boolean result = matcher.find();
+ if (result) {
+ handleSkippedOutput(output.subSequence(firstUnprocessedIndex, firstUnprocessedIndex + matcher.start()));
+ firstUnprocessedIndex += matcher.end();
+ }
+ return result;
+ }
+
+ private Matcher matcher(Pattern pattern) {
+ return pattern.matcher(output.subSequence(firstUnprocessedIndex, output.length()));
+ }
+
+ @Override
+ public void processTerminated(ProcessEvent event) {
+ if (firstUnprocessedIndex < output.length()) {
+ handleSkippedOutput(output.substring(firstUnprocessedIndex).trim());
+ }
+ if (event.getExitCode() != 0) {
+ compileContext.addMessage(ERROR, "Compiler terminated with exit code: " + event.getExitCode(), "", -1, -1);
+ }
+ }
+
+ private void handleSkippedOutput(CharSequence substring) {
+ String message = substring.toString();
+ if (!message.trim().isEmpty()) {
+ compileContext.addMessage(ERROR, message, "", -1, -1);
+ }
+ }
+ }
}
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java
index a7b90559619..e0417995695 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java
+++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java
@@ -21,7 +21,9 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.project.Project;
import com.intellij.patterns.PlatformPatterns;
+import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
@@ -29,19 +31,23 @@ import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
-import org.jetbrains.jet.lang.psi.JetFile;
-import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
-import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
-import org.jetbrains.jet.lang.psi.JetUserType;
+import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.lang.resolve.scopes.JetScope;
+import org.jetbrains.jet.lang.types.JetType;
+import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.caches.JetCacheManager;
import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
+import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
import org.jetbrains.jet.plugin.references.JetSimpleNameReference;
+import org.jetbrains.jet.util.QualifiedNamesUtil;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Set;
/**
* @author Nikolay Krasko
@@ -52,20 +58,20 @@ public class JetCompletionContributor extends CompletionContributor {
new CompletionProvider() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,
- final @NotNull CompletionResultSet result) {
+ @NotNull CompletionResultSet result) {
- final HashSet positions = new HashSet();
+ Set positions = new HashSet();
if (result.getPrefixMatcher().getPrefix().isEmpty()) {
return;
}
- final PsiElement position = parameters.getPosition();
+ PsiElement position = parameters.getPosition();
if (!(position.getContainingFile() instanceof JetFile)) {
return;
}
- final JetSimpleNameReference jetReference = getJetReference(parameters);
+ JetSimpleNameReference jetReference = getJetReference(parameters);
if (jetReference != null) {
for (Object variant : jetReference.getVariants()) {
addReferenceVariant(result, variant, positions);
@@ -74,6 +80,7 @@ public class JetCompletionContributor extends CompletionContributor {
if (shouldRunTopLevelCompletion(parameters)) {
addClasses(parameters, result, positions);
addJetTopLevelFunctions(result, position, positions);
+ addJetExtensionFunctions(jetReference.getExpression(), result, position);
}
result.stopHere();
@@ -82,10 +89,66 @@ public class JetCompletionContributor extends CompletionContributor {
});
}
+ // TODO: Make it work for properties
+ private static void addJetExtensionFunctions(JetSimpleNameExpression expression, CompletionResultSet result, PsiElement position) {
+
+ BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) position.getContainingFile());
+ JetExpression receiverExpression = expression.getReceiverExpression();
+
+
+ if (receiverExpression != null) {
+ JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
+ JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
+
+ if (expressionType != null && scope != null) {
+ JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache();
+ Collection extensionFunctionsNames = namesCache.getAllJetExtensionFunctionsNames(
+ GlobalSearchScope.allScope(position.getProject()));
+
+ Set functionFQNs = new HashSet();
+
+ // Collect all possible extension function qualified names
+ for (String name : extensionFunctionsNames) {
+ if (result.getPrefixMatcher().prefixMatches(name)) {
+ Collection extensionFunctions =
+ namesCache.getJetExtensionFunctionsByName(name, GlobalSearchScope.allScope(position.getProject()));
+
+ for (PsiElement extensionFunction : extensionFunctions) {
+ if (extensionFunction instanceof JetNamedFunction) {
+ functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction));
+ }
+ else if (extensionFunction instanceof PsiMethod) {
+ PsiMethod function = (PsiMethod) extensionFunction;
+ PsiClass containingClass = function.getContainingClass();
+
+ if (containingClass != null) {
+ String classFQN = containingClass.getQualifiedName();
+
+ if (classFQN != null) {
+ String classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN);
+ functionFQNs.add(QualifiedNamesUtil.combine(classParentFQN, function.getName()));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Iterate through the function with attempt to resolve found functions
+ for (String functionFQN : functionFQNs) {
+ for (CallableDescriptor functionDescriptor : ExpressionTypingUtils.canFindSuitableCall(
+ functionFQN, position.getProject(), receiverExpression, expressionType, scope)) {
+ result.addElement(DescriptorLookupConverter.createLookupElement(context, functionDescriptor));
+ }
+ }
+ }
+ }
+ }
+
private static void addReferenceVariant(
@NotNull CompletionResultSet result,
@NotNull Object variant,
- @NotNull final HashSet positions) {
+ @NotNull Set positions) {
if (variant instanceof LookupElement) {
addCompletionToResult(result, (LookupElement) variant, positions);
@@ -96,15 +159,15 @@ public class JetCompletionContributor extends CompletionContributor {
}
private static void addJetTopLevelFunctions(@NotNull CompletionResultSet result, @NotNull PsiElement position,
- @NotNull final HashSet positions) {
+ @NotNull Set positions) {
String actualPrefix = result.getPrefixMatcher().getPrefix();
- final Project project = position.getProject();
+ Project project = position.getProject();
- final JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache();
- final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
- final Collection functionNames = namesCache.getAllTopLevelFunctionNames();
+ JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache();
+ GlobalSearchScope scope = GlobalSearchScope.allScope(project);
+ Collection functionNames = namesCache.getAllTopLevelFunctionNames();
BindingContext resolutionContext = namesCache.getResolutionContext(scope);
@@ -121,9 +184,9 @@ public class JetCompletionContributor extends CompletionContributor {
* Jet classes will be added as java completions for unification
*/
private static void addClasses(
- @NotNull final CompletionParameters parameters,
+ @NotNull CompletionParameters parameters,
@NotNull final CompletionResultSet result,
- @NotNull final HashSet positions) {
+ @NotNull final Set positions) {
JetClassCompletionContributor.addClasses(parameters, result, new Consumer() {
@Override
@@ -134,7 +197,7 @@ public class JetCompletionContributor extends CompletionContributor {
}
private static boolean shouldRunTopLevelCompletion(@NotNull CompletionParameters parameters) {
- final PsiElement element = parameters.getPosition();
+ PsiElement element = parameters.getPosition();
if (parameters.getInvocationCount() > 1) {
return true;
@@ -158,9 +221,9 @@ public class JetCompletionContributor extends CompletionContributor {
@Nullable
private static JetSimpleNameReference getJetReference(@NotNull CompletionParameters parameters) {
- final PsiElement element = parameters.getPosition();
+ PsiElement element = parameters.getPosition();
if (element.getParent() != null) {
- final PsiElement parent = element.getParent();
+ PsiElement parent = element.getParent();
PsiReference[] references = parent.getReferences();
if (references.length != 0) {
@@ -176,11 +239,11 @@ public class JetCompletionContributor extends CompletionContributor {
}
private static void addCompletionToResult(
- @NotNull final CompletionResultSet result,
+ @NotNull CompletionResultSet result,
@NotNull LookupElement element,
- @NotNull HashSet positions) {
+ @NotNull Set positions) {
- final LookupPositionObject lookupPosition = getLookupPosition(element);
+ LookupPositionObject lookupPosition = getLookupPosition(element);
if (lookupPosition != null) {
if (!positions.contains(lookupPosition)) {
positions.add(lookupPosition);
@@ -195,14 +258,14 @@ public class JetCompletionContributor extends CompletionContributor {
}
private static LookupPositionObject getLookupPosition(LookupElement element) {
- final Object lookupObject = element.getObject();
+ Object lookupObject = element.getObject();
if (lookupObject instanceof PsiElement) {
// PsiElement psiElement = (PsiElement) lookupObject;
return new LookupPositionObject((PsiElement) lookupObject);
}
else if (lookupObject instanceof JetLookupObject) {
// JetLookupObject jetLookupObject = (JetLookupObject) lookupObject;
- final PsiElement psiElement = ((JetLookupObject) lookupObject).getPsiElement();
+ PsiElement psiElement = ((JetLookupObject) lookupObject).getPsiElement();
if (psiElement != null) {
return new LookupPositionObject(psiElement);
}
@@ -210,4 +273,9 @@ public class JetCompletionContributor extends CompletionContributor {
return null;
}
+
+ @Override
+ public void beforeCompletion(@NotNull CompletionInitializationContext context) {
+ super.beforeCompletion(context); //To change body of overridden methods use File | Settings | File Templates.
+ }
}
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java
index 75f3c44fbd1..b62ddcd5fef 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java
+++ b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java
@@ -29,6 +29,9 @@ import org.jetbrains.jet.lang.psi.JetNamespaceHeader;
import org.jetbrains.jet.plugin.references.JetPackageReference;
/**
+ * Performs completion in package directive. Should suggest only packages and avoid showing fake package produced by
+ * DUMMY_IDENTIFIER.
+ *
* @author Nikolay Krasko
*/
public class JetPackagesContributor extends CompletionContributor {
diff --git a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java
index 40612db4ebd..9e46c7c00d4 100644
--- a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java
+++ b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java
@@ -115,11 +115,6 @@ public class JetFunctionInsertHandler implements InsertHandler {
return;
}
- // No auto import for qualified expressions
- if (PsiTreeUtil.getParentOfType(element, JetQualifiedExpression.class) != null) {
- return;
- }
-
if (context.getFile() instanceof JetFile && item.getObject() instanceof JetLookupObject) {
final DeclarationDescriptor descriptor = ((JetLookupObject) item.getObject()).getDescriptor();
if (descriptor instanceof SimpleFunctionDescriptor) {
@@ -128,6 +123,13 @@ public class JetFunctionInsertHandler implements InsertHandler {
SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) descriptor;
final String fqn = DescriptorUtils.getFQName(functionDescriptor);
+ // Don't insert import for qualified expression if don't try to insert extension function
+ if (PsiTreeUtil.getParentOfType(element, JetQualifiedExpression.class) != null &&
+ !functionDescriptor.getReceiverParameter().exists()) {
+
+ return;
+ }
+
if (DescriptorUtils.isTopLevelFunction(functionDescriptor)) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/JetLiveTemplateCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/liveTemplates/JetLiveTemplateCompletionContributor.java
index 9b843f235f7..e7388dcc7d1 100644
--- a/idea/src/org/jetbrains/jet/plugin/liveTemplates/JetLiveTemplateCompletionContributor.java
+++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/JetLiveTemplateCompletionContributor.java
@@ -46,6 +46,9 @@ public class JetLiveTemplateCompletionContributor extends CompletionContributor
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull final CompletionResultSet result) {
+ if (parameters.getInvocationCount() == 0) {
+ return;
+ }
final PsiFile file = parameters.getPosition().getContainingFile();
final int offset = parameters.getOffset();
final List templates = listApplicableTemplates(file, offset);
diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java
index 2bb9ebdcd17..1e0183f1776 100644
--- a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java
+++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/JetSuggestVariableNameMacro.java
@@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.JetBundle;
public class JetSuggestVariableNameMacro extends Macro {
@Override
public String getName() {
- return "suggestVariableName";
+ return "kotlinSuggestVariableName";
}
@Override
diff --git a/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java b/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java
index 97572a1652e..923efa85391 100644
--- a/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java
+++ b/idea/src/org/jetbrains/jet/plugin/stubindex/StubIndexServiceImpl.java
@@ -43,14 +43,16 @@ public class StubIndexServiceImpl implements StubIndexService {
public void indexFunction(PsiJetFunctionStub stub, IndexSink sink) {
String name = stub.getName();
if (name != null) {
- if (!stub.isExtension()) {
- if (stub.isTopLevel()) {
+ if (stub.isTopLevel()) {
+ // Collection only top level functions as only they are expected in completion without explicit import
+ if (!stub.isExtension()) {
sink.occurrence(JetIndexKeys.TOP_LEVEL_FUNCTION_SHORT_NAME_KEY, name);
+ // sink.occurrence(JetIndexKeys.TOP_LEVEL_FUNCTION_FQNAME_KEY, name);
+ } else {
+ sink.occurrence(JetIndexKeys.EXTENSION_FUNCTION_SHORT_NAME_KEY, name);
+ // sink.occurrence(JetIndexKeys.EXTENSION_FUNCTION_FQNAME_KEY, name);
}
}
- else {
- sink.occurrence(JetIndexKeys.EXTENSION_FUNCTION_SHORT_NAME_KEY, name);
- }
}
}
}
diff --git a/idea/testData/completion/basic/ExtensionFromStandardLibrary.kt b/idea/testData/completion/basic/ExtensionFromStandardLibrary.kt
new file mode 100644
index 00000000000..f662efd8701
--- /dev/null
+++ b/idea/testData/completion/basic/ExtensionFromStandardLibrary.kt
@@ -0,0 +1,13 @@
+package first
+
+import java.util.ArrayList
+
+fun firstFun() {
+ val a = ArrayList()
+ a.toLinke
+}
+
+// RUNTIME: 1
+// TIME: 2
+// EXIST: toLinkedList
+// NUMBER: 1
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/DoNotCompleteWithConstraints-1.kt b/idea/testData/completion/basic/multifile/DoNotCompleteWithConstraints-1.kt
new file mode 100644
index 00000000000..2bc456b90ab
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/DoNotCompleteWithConstraints-1.kt
@@ -0,0 +1,15 @@
+package first
+
+trait TestedTrait() {
+}
+
+fun firstFun() {
+ val a = second.SomeTest()
+ a.testing
+}
+
+// EXIST: testingMethod
+// EXIST: testingExpectedFunction
+// ABSENT: testingUnexpectedFunction
+
+// NUMBER: 2
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/DoNotCompleteWithConstraints-2.kt b/idea/testData/completion/basic/multifile/DoNotCompleteWithConstraints-2.kt
new file mode 100644
index 00000000000..4614b598b5e
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/DoNotCompleteWithConstraints-2.kt
@@ -0,0 +1,16 @@
+package second
+
+open class SomeOther() {}
+
+class SomeTest {
+ fun testingMethod() {
+
+ }
+}
+
+fun SomeTest.testingUnexpectedFunction() {
+}
+
+fun SomeTest.testingExpectedFunction(i : Int) : String {
+ return ""
+}
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/ExtensionFunctionOnUnresolved-1.kt b/idea/testData/completion/basic/multifile/ExtensionFunctionOnUnresolved-1.kt
new file mode 100644
index 00000000000..784ac599a7a
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/ExtensionFunctionOnUnresolved-1.kt
@@ -0,0 +1,11 @@
+package first
+
+fun firstFun() {
+ val a = SomeUnknownClass()
+ a.hello
+}
+
+// ABSENT: helloFun
+// ABSENT: helloFunPreventAutoInsert
+// ABSENT: helloWithParams
+// NUMBER: 0
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/ExtensionFunctionOnUnresolved-2.kt b/idea/testData/completion/basic/multifile/ExtensionFunctionOnUnresolved-2.kt
new file mode 100644
index 00000000000..26ba80640b4
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/ExtensionFunctionOnUnresolved-2.kt
@@ -0,0 +1,11 @@
+package second
+
+fun String.helloFun() {
+}
+
+fun String.helloWithParams(i : Int) : String {
+ return ""
+}
+
+fun String.helloFunPreventAutoInsert() {
+}
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/ExtensionOnNullable-1.kt b/idea/testData/completion/basic/multifile/ExtensionOnNullable-1.kt
new file mode 100644
index 00000000000..66e065edf74
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/ExtensionOnNullable-1.kt
@@ -0,0 +1,12 @@
+package first
+
+fun firstFun() {
+ val a : String? = ""
+ a.hello
+}
+
+// EXIST: helloFun
+// EXIST: helloFunPreventAutoInsert
+// EXIST: helloWithParams
+// ABSENT: helloFake
+// NUMBER: 3
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/ExtensionOnNullable-2.kt b/idea/testData/completion/basic/multifile/ExtensionOnNullable-2.kt
new file mode 100644
index 00000000000..0d782748e87
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/ExtensionOnNullable-2.kt
@@ -0,0 +1,14 @@
+package second
+
+fun String.helloFun() {
+}
+
+fun String.helloWithParams(i : Int) : String {
+ return ""
+}
+
+fun String.helloFunPreventAutoInsert() {
+}
+
+fun Int.helloFake() {
+}
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/ExtensionProperty-1.kt b/idea/testData/completion/basic/multifile/ExtensionProperty-1.kt
new file mode 100644
index 00000000000..45b5e8b4acc
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/ExtensionProperty-1.kt
@@ -0,0 +1,12 @@
+package first
+
+import second.SomeTestClass
+
+fun firstFun() {
+ SomeTestClass().some
+}
+
+// EXIST: someProperty
+// EXIST: someOtherProperty
+// EXIST: someSelfProperty
+// NUMBER: 3
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/ExtensionProperty-2.kt b/idea/testData/completion/basic/multifile/ExtensionProperty-2.kt
new file mode 100644
index 00000000000..a8e890a7fa3
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/ExtensionProperty-2.kt
@@ -0,0 +1,8 @@
+package second
+
+class SomeTestClass() {
+}
+
+val SomeTestClass.someProperty = 12
+var SomeTestClass.someOtherProperty = ""
+val SomeTestClass.someSelfProperty = SomeTestClass()
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/NotImportedExtensionFunction-1.kt b/idea/testData/completion/basic/multifile/NotImportedExtensionFunction-1.kt
new file mode 100644
index 00000000000..dda68250d5e
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/NotImportedExtensionFunction-1.kt
@@ -0,0 +1,12 @@
+package first
+
+fun firstFun() {
+ val a = ""
+ a.hello
+}
+
+// EXIST: helloFun
+// EXIST: helloFunPreventAutoInsert
+// EXIST: helloWithParams
+// ABSENT: helloFake
+// NUMBER: 3
\ No newline at end of file
diff --git a/idea/testData/completion/basic/multifile/NotImportedExtensionFunction-2.kt b/idea/testData/completion/basic/multifile/NotImportedExtensionFunction-2.kt
new file mode 100644
index 00000000000..0d782748e87
--- /dev/null
+++ b/idea/testData/completion/basic/multifile/NotImportedExtensionFunction-2.kt
@@ -0,0 +1,14 @@
+package second
+
+fun String.helloFun() {
+}
+
+fun String.helloWithParams(i : Int) : String {
+ return ""
+}
+
+fun String.helloFunPreventAutoInsert() {
+}
+
+fun Int.helloFake() {
+}
\ No newline at end of file
diff --git a/idea/testData/completion/handlers/multifile/ExtensionFunctions-1.kt b/idea/testData/completion/handlers/multifile/ExtensionFunctions-1.kt
new file mode 100644
index 00000000000..9b743c13c61
--- /dev/null
+++ b/idea/testData/completion/handlers/multifile/ExtensionFunctions-1.kt
@@ -0,0 +1,6 @@
+package first
+
+fun firstFun() {
+ val a = ""
+ a.hello
+}
\ No newline at end of file
diff --git a/idea/testData/completion/handlers/multifile/ExtensionFunctions-2.kt b/idea/testData/completion/handlers/multifile/ExtensionFunctions-2.kt
new file mode 100644
index 00000000000..2f98c0a94f4
--- /dev/null
+++ b/idea/testData/completion/handlers/multifile/ExtensionFunctions-2.kt
@@ -0,0 +1,4 @@
+package second
+
+fun String.helloFun() {
+}
\ No newline at end of file
diff --git a/idea/testData/completion/handlers/multifile/ExtensionFunctions.kt.after b/idea/testData/completion/handlers/multifile/ExtensionFunctions.kt.after
new file mode 100644
index 00000000000..d2679999b61
--- /dev/null
+++ b/idea/testData/completion/handlers/multifile/ExtensionFunctions.kt.after
@@ -0,0 +1,8 @@
+package first
+
+import second.helloFun
+
+fun firstFun() {
+ val a = ""
+ a.helloFun()
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java b/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java
index 2ec8535261a..5b0b9b10783 100644
--- a/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java
+++ b/idea/tests/org/jetbrains/jet/completion/ExpectedCompletionUtils.java
@@ -68,17 +68,17 @@ public class ExpectedCompletionUtils {
@Nullable
public Integer getExpectedNumber(String fileText) {
- final String[] numberStrings = findListWithPrefix(numberLinePrefix, fileText);
- if (numberStrings.length > 0) {
- return Integer.parseInt(numberStrings[0]);
- }
-
- return null;
+ return getPrefixedInt(fileText, numberLinePrefix);
}
@Nullable
public Integer getExecutionTime(String fileText) {
- final String[] numberStrings = findListWithPrefix(executionTimePrefix, fileText);
+ return getPrefixedInt(fileText, executionTimePrefix);
+ }
+
+ @Nullable
+ public static Integer getPrefixedInt(String fileText, String prefix) {
+ final String[] numberStrings = findListWithPrefix(prefix, fileText);
if (numberStrings.length > 0) {
return Integer.parseInt(numberStrings[0]);
}
diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java
index 660e9d1f92f..24927696af2 100644
--- a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java
+++ b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java
@@ -45,6 +45,10 @@ public class JetBasicCompletionTest extends JetCompletionTestBase {
doTest();
}
+ public void testExtensionFromStandardLibrary() {
+ doTest();
+ }
+
public void testFromImports() {
doTest();
}
@@ -101,6 +105,8 @@ public class JetBasicCompletionTest extends JetCompletionTestBase {
doTest();
}
+
+
@Override
protected String getTestDataPath() {
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/basic").getPath() +
diff --git a/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java b/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java
index 4c832c5cee6..a9218f58514 100644
--- a/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java
+++ b/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java
@@ -22,7 +22,12 @@ import com.intellij.codeInsight.completion.LightCompletionTestCase;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
+import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import org.apache.commons.lang.SystemUtils;
+import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
/**
@@ -47,32 +52,71 @@ public abstract class JetCompletionTestBase extends LightCompletionTestCase {
final String fileText = getFile().getText();
- Integer completionTime = completionUtils.getExecutionTime(fileText);
-
- complete(completionTime == null ? 1 : completionTime);
+ boolean withKotlinRuntime = ExpectedCompletionUtils.getPrefixedInt(fileText, "// RUNTIME:") != null;
- final String[] expected = completionUtils.itemsShouldExist(fileText);
- final String[] unexpected = completionUtils.itemsShouldAbsent(fileText);
- Integer itemsNumber = completionUtils.getExpectedNumber(fileText);
+ try {
+ if (withKotlinRuntime) {
+ configureWithKotlinRuntime();
+ }
- assertTrue("Should be some assertions about completion", expected.length != 0 || unexpected.length != 0 || itemsNumber != null);
+ Integer completionTime = completionUtils.getExecutionTime(fileText);
- assertContainsItems(expected);
- assertNotContainItems(unexpected);
+ complete(completionTime == null ? 1 : completionTime);
- if (itemsNumber != null) {
- assertEquals(itemsNumber.intValue(), myItems.length);
+ final String[] expected = completionUtils.itemsShouldExist(fileText);
+ final String[] unexpected = completionUtils.itemsShouldAbsent(fileText);
+ Integer itemsNumber = completionUtils.getExpectedNumber(fileText);
+
+ assertTrue("Should be some assertions about completion", expected.length != 0 || unexpected.length != 0 || itemsNumber != null);
+
+ assertContainsItems(expected);
+ assertNotContainItems(unexpected);
+
+ if (itemsNumber != null) {
+ assertEquals(itemsNumber.intValue(), myItems.length);
+ }
}
+ finally {
+ if (withKotlinRuntime) {
+ unConfigureKotlinRuntime();
+ }
+ }
+
+
} catch (Exception e) {
throw new AssertionError(e);
}
}
+ protected static void configureWithKotlinRuntime() {
+ final ModuleRootManager rootManager = ModuleRootManager.getInstance(getModule());
+ final ModifiableRootModel rootModel = rootManager.getModifiableModel();
+
+ rootModel.setSdk(getFullJavaJDK());
+ JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE.configureModule(getModule(), rootModel, null);
+
+ rootModel.commit();
+ }
+
+ protected void unConfigureKotlinRuntime() {
+ final ModuleRootManager rootManager = ModuleRootManager.getInstance(getModule());
+ final ModifiableRootModel rootModel = rootManager.getModifiableModel();
+
+ rootModel.setSdk(getProjectJDK());
+ JetWithJdkAndRuntimeLightProjectDescriptor.unConfigureModule(rootModel);
+
+ rootModel.commit();
+ }
+
@Override
protected Sdk getProjectJDK() {
return PluginTestCaseBase.jdkFromIdeaHome();
}
+ protected static Sdk getFullJavaJDK() {
+ return JavaSdk.getInstance().createJdk("JDK", SystemUtils.getJavaHome().getAbsolutePath());
+ }
+
@Override
protected void complete(final int time) {
new CodeCompletionHandlerBase(type, false, false, true).invokeCompletion(getProject(), getEditor(), time, false);
diff --git a/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java
index 66c76b9d1cf..7056bf1131c 100644
--- a/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java
+++ b/idea/tests/org/jetbrains/jet/completion/JetMultifileBasicCompletionTest.java
@@ -23,10 +23,30 @@ import org.jetbrains.jet.plugin.PluginTestCaseBase;
*/
public class JetMultifileBasicCompletionTest extends JetCompletionMultiTestBase {
+ public void testDoNotCompleteWithConstraints() {
+ doFileTest(2);
+ }
+
public void testTopLevelFunction() throws Exception {
doFileTest(2);
}
+ public void todotestExtensionFunctionOnUnresolved() throws Exception {
+ doFileTest(2);
+ }
+
+ public void testExtensionOnNullable() throws Exception {
+ doFileTest(2);
+ }
+
+ public void todotestExtensionProperty() throws Exception {
+ doFileTest(2);
+ }
+
+ public void testNotImportedExtensionFunction() throws Exception {
+ doFileTest(2);
+ }
+
public void testExtensionFunction() throws Exception {
// TODO: fix and uncomment
// doFileTest();
diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java
index 68e78e1c80e..e6311d8e58a 100644
--- a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java
+++ b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java
@@ -26,6 +26,10 @@ import java.io.File;
*/
public class CompletionMultifileHandlerTest extends CompletionTestCase {
+ public void testExtensionFunctions() throws Exception {
+ doTest();
+ }
+
public void testTopLevelFunctionImport() throws Exception {
doTest();
}
diff --git a/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java b/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java
index a698d4fea2b..e666476b25f 100644
--- a/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java
+++ b/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java
@@ -21,14 +21,14 @@ import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.ContentEntry;
-import com.intellij.openapi.roots.ModifiableRootModel;
-import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.LightProjectDescriptor;
import org.apache.commons.lang.SystemUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ForTestCompileStdlib;
/**
@@ -52,11 +52,25 @@ public class JetWithJdkAndRuntimeLightProjectDescriptor implements LightProjectD
}
@Override
- public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
+ public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @Nullable ContentEntry contentEntry) {
Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("ktl").getModifiableModel();
VirtualFile cd = JarFileSystem.getInstance().findFileByPath(ForTestCompileStdlib.stdlibJarForTests() + "!/");
assert cd != null;
modifiableModel.addRoot(cd, OrderRootType.CLASSES);
modifiableModel.commit();
}
+
+ public static void unConfigureModule(@NotNull ModifiableRootModel model) {
+ for (OrderEntry orderEntry : model.getOrderEntries()) {
+ if (orderEntry instanceof LibraryOrderEntry) {
+ LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry) orderEntry;
+
+ Library library = libraryOrderEntry.getLibrary();
+ if (library != null && library.getName().equals("ktl")) {
+ model.getModuleLibraryTable().removeLibrary(library);
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/js/js.tests/js.tests.iml b/js/js.tests/js.tests.iml
index 72acf26a5cc..aa9f0a6aab3 100644
--- a/js/js.tests/js.tests.iml
+++ b/js/js.tests/js.tests.iml
@@ -5,7 +5,7 @@
-
+
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/ArrayListTest.java b/js/js.tests/test/org/jetbrains/k2js/test/ArrayListTest.java
index 7e3f7506cab..85d4a4706cc 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/ArrayListTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/ArrayListTest.java
@@ -31,32 +31,32 @@ public final class ArrayListTest extends JavaClassesTest {
}
public void testEmptyList() throws Exception {
- testFooBoxIsTrue("emptyList.kt");
+ checkFooBoxIsTrue("emptyList.kt");
}
public void testAccess() throws Exception {
- testFooBoxIsTrue("access.kt");
+ checkFooBoxIsTrue("access.kt");
}
public void testIsEmpty() throws Exception {
- testFooBoxIsTrue("isEmpty.kt");
+ checkFooBoxIsTrue("isEmpty.kt");
}
public void testArrayAccess() throws Exception {
- testFooBoxIsTrue("arrayAccess.kt");
+ checkFooBoxIsTrue("arrayAccess.kt");
}
public void testIterate() throws Exception {
- testFooBoxIsTrue("iterate.kt");
+ checkFooBoxIsTrue("iterate.kt");
}
public void testRemove() throws Exception {
- testFooBoxIsTrue("remove.kt");
+ checkFooBoxIsTrue("remove.kt");
}
public void testIndexOOB() throws Exception {
try {
- testFooBoxIsTrue("indexOOB.kt");
+ checkFooBoxIsTrue("indexOOB.kt");
fail();
} catch (JavaScriptException e) {
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/ClassInheritanceTest.java b/js/js.tests/test/org/jetbrains/k2js/test/ClassInheritanceTest.java
index ed2d3369c68..6aa1d44b8cc 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/ClassInheritanceTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/ClassInheritanceTest.java
@@ -33,27 +33,27 @@ public final class ClassInheritanceTest extends TranslationTest {
}
public void testMethodOverride() throws Exception {
- testFooBoxIsTrue("methodOverride.kt");
+ checkFooBoxIsTrue("methodOverride.kt");
}
public void testInitializationOrder() throws Exception {
- testFooBoxIsTrue("initializationOrder.kt");
+ checkFooBoxIsTrue("initializationOrder.kt");
}
public void testComplexInitializationOrder() throws Exception {
- testFooBoxIsTrue("complexInitializationOrder.kt");
+ checkFooBoxIsTrue("complexInitializationOrder.kt");
}
public void testValuePassedToAncestorConstructor() throws Exception {
- testFooBoxIsTrue("valuePassedToAncestorConstructor.kt");
+ checkFooBoxIsTrue("valuePassedToAncestorConstructor.kt");
}
public void testBaseClassDefinedAfterDerived() throws Exception {
- testFooBoxIsTrue("baseClassDefinedAfterDerived.kt");
+ checkFooBoxIsTrue("baseClassDefinedAfterDerived.kt");
}
public void testDefinitionOrder() throws Exception {
- testFooBoxIsTrue("definitionOrder.kt");
+ checkFooBoxIsTrue("definitionOrder.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/ConditionalTest.java b/js/js.tests/test/org/jetbrains/k2js/test/ConditionalTest.java
index 8eaec5f933c..01bc150435f 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/ConditionalTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/ConditionalTest.java
@@ -33,7 +33,7 @@ public class ConditionalTest extends AbstractExpressionTest {
public void testIfElseAsExpressionWithThrow() throws Exception {
try {
- testFooBoxIsTrue("ifAsExpressionWithThrow.kt");
+ checkFooBoxIsTrue("ifAsExpressionWithThrow.kt");
fail();
} catch (JavaScriptException e) {
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java
index 783d67f71ec..428fdad5ed7 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/ExtensionFunctionTest.java
@@ -28,38 +28,38 @@ public final class ExtensionFunctionTest extends TranslationTest {
}
public void testIntExtension() throws Exception {
- testFooBoxIsTrue("intExtension.kt");
+ checkFooBoxIsTrue("intExtension.kt");
}
public void testExtensionWithImplicitReceiver() throws Exception {
- testFooBoxIsTrue("extensionWithImplicitReceiver.kt");
+ checkFooBoxIsTrue("extensionWithImplicitReceiver.kt");
}
public void testExtensionFunctionOnExpression() throws Exception {
- testFooBoxIsTrue("extensionFunctionOnExpression.kt");
+ checkFooBoxIsTrue("extensionFunctionOnExpression.kt");
}
public void testExtensionUsedInsideClass() throws Exception {
- testFooBoxIsTrue("extensionUsedInsideClass.kt");
+ checkFooBoxIsTrue("extensionUsedInsideClass.kt");
}
public void testVirtualExtension() throws Exception {
- testFooBoxIsTrue("virtualExtension.kt");
+ checkFooBoxIsTrue("virtualExtension.kt");
}
public void testVirtualExtensionOverride() throws Exception {
- testFooBoxIsTrue("virtualExtensionOverride.kt");
+ checkFooBoxIsTrue("virtualExtensionOverride.kt");
}
public void testExtensionLiteralPassedToFunction() throws Exception {
- testFooBoxIsTrue("extensionLiteralPassedToFunction.kt");
+ checkFooBoxIsTrue("extensionLiteralPassedToFunction.kt");
}
public void testExtensionInsideFunctionLiteral() throws Exception {
- testFooBoxIsTrue("extensionInsideFunctionLiteral.kt");
+ checkFooBoxIsTrue("extensionInsideFunctionLiteral.kt");
}
public void testGenericExtension() throws Exception {
- testFooBoxIsOk("generic.kt");
+ checkFooBoxIsOk("generic.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/ExtensionPropertyTest.java b/js/js.tests/test/org/jetbrains/k2js/test/ExtensionPropertyTest.java
index 983dd8ab86f..c6387d097bb 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/ExtensionPropertyTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/ExtensionPropertyTest.java
@@ -28,14 +28,14 @@ public final class ExtensionPropertyTest extends TranslationTest {
}
public void testSimplePropertyWithGetter() throws Exception {
- testFooBoxIsTrue("simplePropertyWithGetter.kt");
+ checkFooBoxIsTrue("simplePropertyWithGetter.kt");
}
public void testPropertyWithGetterAndSetter() throws Exception {
- testFooBoxIsTrue("propertyWithGetterAndSetter.kt");
+ checkFooBoxIsTrue("propertyWithGetterAndSetter.kt");
}
public void testAbsExtension() throws Exception {
- testFooBoxIsTrue("absExtension.kt");
+ checkFooBoxIsTrue("absExtension.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/ForTest.java b/js/js.tests/test/org/jetbrains/k2js/test/ForTest.java
index 6c469fc070e..4ea77af1c5d 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/ForTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/ForTest.java
@@ -29,10 +29,10 @@ public final class ForTest extends AbstractExpressionTest {
}
public void testForIteratesOverArray() throws Exception {
- testFooBoxIsTrue("forIteratesOverArray.kt");
+ checkFooBoxIsTrue("forIteratesOverArray.kt");
}
public void testForOnEmptyArray() throws Exception {
- testFooBoxIsTrue("forOnEmptyArray.kt");
+ checkFooBoxIsTrue("forOnEmptyArray.kt");
}
}
\ No newline at end of file
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/FunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/FunctionTest.java
index c339e7343af..f819c841a4d 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/FunctionTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/FunctionTest.java
@@ -29,35 +29,35 @@ public class FunctionTest extends AbstractExpressionTest {
}
public void testFunctionUsedBeforeDeclaration() throws Exception {
- testFooBoxIsTrue("functionUsedBeforeDeclaration.kt");
+ checkFooBoxIsTrue("functionUsedBeforeDeclaration.kt");
}
public void testFunctionWithTwoParametersCall() throws Exception {
- testFooBoxIsTrue("functionWithTwoParametersCall.kt");
+ checkFooBoxIsTrue("functionWithTwoParametersCall.kt");
}
public void testFunctionLiteral() throws Exception {
- testFooBoxIsTrue("functionLiteral.kt");
+ checkFooBoxIsTrue("functionLiteral.kt");
}
public void testAdderClosure() throws Exception {
- testFooBoxIsTrue("adderClosure.kt");
+ checkFooBoxIsTrue("adderClosure.kt");
}
public void testLoopClosure() throws Exception {
- testFooBoxIsTrue("loopClosure.kt");
+ checkFooBoxIsTrue("loopClosure.kt");
}
public void testFunctionLiteralAsParameter() throws Exception {
- testFooBoxIsTrue("functionLiteralAsParameter.kt");
+ checkFooBoxIsTrue("functionLiteralAsParameter.kt");
}
public void testClosureWithParameter() throws Exception {
- testFooBoxIsOk("closureWithParameter.kt");
+ checkFooBoxIsOk("closureWithParameter.kt");
}
public void testClosureWithParameterAndBoxing() throws Exception {
- testFooBoxIsOk("closureWithParameterAndBoxing.jet");
+ checkFooBoxIsOk("closureWithParameterAndBoxing.jet");
}
public void testEnclosingThis() throws Exception {
@@ -66,32 +66,32 @@ public class FunctionTest extends AbstractExpressionTest {
public void testImplicitItParameter() throws Exception {
- testFooBoxIsTrue("implicitItParameter.kt");
+ checkFooBoxIsTrue("implicitItParameter.kt");
}
public void testDefaultParameters() throws Exception {
- testFooBoxIsTrue("defaultParameters.kt");
+ checkFooBoxIsTrue("defaultParameters.kt");
}
public void testFunctionLiteralAsLastParameter() throws Exception {
- testFooBoxIsTrue("functionLiteralAsLastParameter.kt");
+ checkFooBoxIsTrue("functionLiteralAsLastParameter.kt");
}
public void testNamedArguments() throws Exception {
- testFooBoxIsTrue("namedArguments.kt");
+ checkFooBoxIsTrue("namedArguments.kt");
}
public void testExpressionAsFunction() throws Exception {
- testFooBoxIsTrue("expressionAsFunction.kt");
+ checkFooBoxIsTrue("expressionAsFunction.kt");
}
public void testVararg() throws Exception {
- testFooBoxIsTrue("vararg.kt");
+ checkFooBoxIsTrue("vararg.kt");
}
@@ -104,6 +104,6 @@ public class FunctionTest extends AbstractExpressionTest {
}
public void testFunctionInsideFunction() throws Exception {
- testFooBoxIsTrue("functionInsideFunction.kt");
+ checkFooBoxIsTrue("functionInsideFunction.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/KotlinLibTest.java b/js/js.tests/test/org/jetbrains/k2js/test/KotlinLibTest.java
index ea94e687ba9..2fb1afd4e19 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/KotlinLibTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/KotlinLibTest.java
@@ -55,7 +55,7 @@ public final class KotlinLibTest extends TranslationTest {
final Map> propertyToType
= new HashMap>();
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("trait.js")),
- new RhinoPropertyTypesChecker("foo", propertyToType));
+ new RhinoPropertyTypesChecker("foo", propertyToType));
}
@@ -63,56 +63,61 @@ public final class KotlinLibTest extends TranslationTest {
final Map> propertyToType
= new HashMap>();
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("namespace.js")),
- new RhinoPropertyTypesChecker("foo", propertyToType));
+ new RhinoPropertyTypesChecker("foo", propertyToType));
}
//
// TODO:Refactor calls to function result checker with test
public void testNamespaceHasDeclaredFunction() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("namespace.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
}
public void testNamespaceHasDeclaredClasses() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("namespaceWithClasses.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
}
public void testIsSameType() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isSameType.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
}
public void testIsAncestorType() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isAncestorType.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
}
public void testIsComplexTest() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isComplexTest.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
}
public void testCommaExpression() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("commaExpression.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
}
public void testArray() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("array.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
}
public void testHashMap() throws Exception {
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("hashMap.js")),
- new RhinoFunctionResultChecker("test", true));
+ new RhinoFunctionResultChecker("test", true));
+ }
+
+ @Override
+ protected boolean shouldCreateOut() {
+ return false;
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/MiscTest.java b/js/js.tests/test/org/jetbrains/k2js/test/MiscTest.java
index d56a8371b78..b34076ddce0 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/MiscTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/MiscTest.java
@@ -36,11 +36,11 @@ public final class MiscTest extends AbstractExpressionTest {
public void testIntRange() throws Exception {
// checkOutput("intRange.kt", " ");
- testFooBoxIsTrue("intRange.kt");
+ checkFooBoxIsTrue("intRange.kt");
}
public void testSafecallComputesExpressionOnlyOnce() throws Exception {
- testFooBoxIsTrue("safecallComputesExpressionOnlyOnce.kt");
+ checkFooBoxIsTrue("safecallComputesExpressionOnlyOnce.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/MultiFileTest.java b/js/js.tests/test/org/jetbrains/k2js/test/MultiFileTest.java
index 76738d49285..4b0a375f952 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/MultiFileTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/MultiFileTest.java
@@ -29,15 +29,15 @@ public final class MultiFileTest extends TranslationTest {
}
public void testFunctionsVisibleFromOtherFile() throws Exception {
- testFooBoxIsTrue("functionsVisibleFromOtherFile");
+ checkFooBoxIsTrue("functionsVisibleFromOtherFile");
}
public void testClassesInheritedFromOtherFile() throws Exception {
- testFooBoxIsTrue("classesInheritedFromOtherFile");
+ checkFooBoxIsTrue("classesInheritedFromOtherFile");
}
@Override
- public void testFooBoxIsTrue(String dirName) throws Exception {
+ public void checkFooBoxIsTrue(String dirName) throws Exception {
testMultiFile(dirName, "foo", "box", true);
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/MultiNamespaceTest.java b/js/js.tests/test/org/jetbrains/k2js/test/MultiNamespaceTest.java
index 8d7d473d636..cdc9b928b36 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/MultiNamespaceTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/MultiNamespaceTest.java
@@ -28,15 +28,15 @@ public class MultiNamespaceTest extends TranslationTest {
}
public void testFunctionsVisibleFromOtherNamespace() throws Exception {
- testFooBoxIsTrue("functionsVisibleFromOtherNamespace");
+ checkFooBoxIsTrue("functionsVisibleFromOtherNamespace");
}
public void testClassesInheritedFromOtherNamespace() throws Exception {
- testFooBoxIsTrue("classesInheritedFromOtherNamespace");
+ checkFooBoxIsTrue("classesInheritedFromOtherNamespace");
}
@Override
- public void testFooBoxIsTrue(String dirName) throws Exception {
+ public void checkFooBoxIsTrue(String dirName) throws Exception {
testMultiFile(dirName, "foo", "box", true);
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/NameClashesTest.java b/js/js.tests/test/org/jetbrains/k2js/test/NameClashesTest.java
index 67f563d2430..c3c7d2c5bc8 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/NameClashesTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/NameClashesTest.java
@@ -29,6 +29,6 @@ public final class NameClashesTest extends TranslationTest {
}
public void testMethodOverload() throws Exception {
- testFooBoxIsTrue("methodOverload.kt");
+ checkFooBoxIsTrue("methodOverload.kt");
}
}
\ No newline at end of file
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/ObjectTest.java b/js/js.tests/test/org/jetbrains/k2js/test/ObjectTest.java
index f0824057fdc..c40cebca8fa 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/ObjectTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/ObjectTest.java
@@ -30,16 +30,16 @@ public final class ObjectTest extends TranslationTest {
public void testObjectWithMethods() throws Exception {
- testFooBoxIsTrue("objectWithMethods.kt");
+ checkFooBoxIsTrue("objectWithMethods.kt");
}
public void testObjectDeclaration() throws Exception {
- testFooBoxIsTrue("objectDeclaration.kt");
+ checkFooBoxIsTrue("objectDeclaration.kt");
}
public void testObjectInMethod() throws Exception {
- testFooBoxIsTrue("objectInMethod.kt");
+ checkFooBoxIsTrue("objectInMethod.kt");
}
}
\ No newline at end of file
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java b/js/js.tests/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java
index d36e34ed211..61a0fe93124 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java
@@ -30,79 +30,79 @@ public final class OperatorOverloadingTest extends TranslationTest {
public void testPlusOverload() throws Exception {
- testFooBoxIsTrue("plusOverload.kt");
+ checkFooBoxIsTrue("plusOverload.kt");
}
public void testPostfixInc() throws Exception {
- testFooBoxIsTrue("postfixIncOverload.kt");
+ checkFooBoxIsTrue("postfixIncOverload.kt");
}
public void testPrefixDecOverload() throws Exception {
- testFooBoxIsTrue("prefixDecOverload.kt");
+ checkFooBoxIsTrue("prefixDecOverload.kt");
}
public void testPrefixIncReturnsCorrectValue() throws Exception {
- testFooBoxIsTrue("prefixIncReturnsCorrectValue.kt");
+ checkFooBoxIsTrue("prefixIncReturnsCorrectValue.kt");
}
public void testOverloadedCallOnProperty() throws Exception {
- testFooBoxIsTrue("overloadedCallOnProperty.kt");
+ checkFooBoxIsTrue("overloadedCallOnProperty.kt");
}
public void testPostfixOnProperty() throws Exception {
- testFooBoxIsTrue("postfixOnProperty.kt");
+ checkFooBoxIsTrue("postfixOnProperty.kt");
}
public void testOperatorOverloadOnPropertyCallGetterAndSetterOnlyOnce() throws Exception {
- testFooBoxIsTrue("operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce.kt");
+ checkFooBoxIsTrue("operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce.kt");
}
public void testUnaryOnIntProperty() throws Exception {
- testFooBoxIsTrue("unaryOnIntProperty.kt");
+ checkFooBoxIsTrue("unaryOnIntProperty.kt");
}
public void testUnaryOnIntPropertyAsStatement() throws Exception {
- testFooBoxIsTrue("unaryOnIntProperty2.kt");
+ checkFooBoxIsTrue("unaryOnIntProperty2.kt");
}
public void testBinaryDivOverload() throws Exception {
- testFooBoxIsTrue("binaryDivOverload.kt");
+ checkFooBoxIsTrue("binaryDivOverload.kt");
}
public void testPlusAssignNoReassign() throws Exception {
- testFooBoxIsTrue("plusAssignNoReassign.kt");
+ checkFooBoxIsTrue("plusAssignNoReassign.kt");
}
public void testNotOverload() throws Exception {
- testFooBoxIsTrue("notOverload.kt");
+ checkFooBoxIsTrue("notOverload.kt");
}
public void testCompareTo() throws Exception {
- testFooBoxIsTrue("compareTo.kt");
+ checkFooBoxIsTrue("compareTo.kt");
}
public void testPlusAndMinusAsAnExpression() throws Exception {
- testFooBoxIsTrue("plusAndMinusAsAnExpression.kt");
+ checkFooBoxIsTrue("plusAndMinusAsAnExpression.kt");
}
public void testUsingModInCaseModAssignNotAvailable() throws Exception {
- testFooBoxIsTrue("usingModInCaseModAssignNotAvailable.kt");
+ checkFooBoxIsTrue("usingModInCaseModAssignNotAvailable.kt");
}
public void testOverloadPlusAssignArrayList() throws Exception {
- testFooBoxIsOk("overloadPlusAssignArrayList.kt");
+ checkFooBoxIsOk("overloadPlusAssignArrayList.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/PatternMatchingTest.java b/js/js.tests/test/org/jetbrains/k2js/test/PatternMatchingTest.java
index d9ff84c1b0e..7bb03d3fd06 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/PatternMatchingTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/PatternMatchingTest.java
@@ -32,37 +32,37 @@ public final class PatternMatchingTest extends TranslationTest {
public void testWhenType() throws Exception {
- testFooBoxIsTrue("whenType.kt");
+ checkFooBoxIsTrue("whenType.kt");
}
public void testWhenNotType() throws Exception {
- testFooBoxIsTrue("whenNotType.kt");
+ checkFooBoxIsTrue("whenNotType.kt");
}
public void testWhenExecutesOnlyOnce() throws Exception {
- testFooBoxIsTrue("whenExecutesOnlyOnce.kt");
+ checkFooBoxIsTrue("whenExecutesOnlyOnce.kt");
}
public void testWhenValue() throws Exception {
- testFooBoxIsTrue("whenValue.kt");
+ checkFooBoxIsTrue("whenValue.kt");
}
public void testWhenNotValue() throws Exception {
- testFooBoxIsTrue("whenNotValue.kt");
+ checkFooBoxIsTrue("whenNotValue.kt");
}
public void testWhenValueOrType() throws Exception {
- testFooBoxIsTrue("whenValueOrType.kt");
+ checkFooBoxIsTrue("whenValueOrType.kt");
}
public void testWhenWithIf() throws Exception {
- testFooBoxIsTrue("whenWithIf.kt");
+ checkFooBoxIsTrue("whenWithIf.kt");
}
@@ -72,17 +72,17 @@ public final class PatternMatchingTest extends TranslationTest {
public void testMatchNullableType() throws Exception {
- testFooBoxIsTrue("matchNullableType.kt");
+ checkFooBoxIsTrue("matchNullableType.kt");
}
public void testWhenAsExpression() throws Exception {
- testFooBoxIsTrue("whenAsExpression.kt");
+ checkFooBoxIsTrue("whenAsExpression.kt");
}
public void whenAsExpressionWithThrow() throws Exception {
try {
- testFooBoxIsTrue("whenAsExpressionWithThrow.kt");
+ checkFooBoxIsTrue("whenAsExpressionWithThrow.kt");
fail();
} catch (JavaScriptException e) {
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/PropertyAccessTest.java b/js/js.tests/test/org/jetbrains/k2js/test/PropertyAccessTest.java
index d08b4b1dd52..78d7e0243dc 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/PropertyAccessTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/PropertyAccessTest.java
@@ -30,12 +30,12 @@ public final class PropertyAccessTest extends TranslationTest {
public void testAccessToInstanceProperty() throws Exception {
- testFooBoxIsTrue("accessToInstanceProperty.kt");
+ checkFooBoxIsTrue("accessToInstanceProperty.kt");
}
public void testTwoClassesWithProperties() throws Exception {
- testFooBoxIsTrue("twoClassesWithProperties.kt");
+ checkFooBoxIsTrue("twoClassesWithProperties.kt");
}
@@ -45,55 +45,55 @@ public final class PropertyAccessTest extends TranslationTest {
public void testCustomGetter() throws Exception {
- testFooBoxIsTrue("customGetter.kt");
+ checkFooBoxIsTrue("customGetter.kt");
}
public void testCustomSetter() throws Exception {
- testFooBoxIsTrue("customSetter.kt");
+ checkFooBoxIsTrue("customSetter.kt");
}
public void testSafeCall() throws Exception {
- testFooBoxIsTrue("safeCall.kt");
+ checkFooBoxIsTrue("safeCall.kt");
}
//TODO: place safecalls under distinkt category
public void testSafeCallReturnsNullIfFails() throws Exception {
- testFooBoxIsTrue("safeCallReturnsNullIfFails.kt");
+ checkFooBoxIsTrue("safeCallReturnsNullIfFails.kt");
}
public void testNamespacePropertyInitializer() throws Exception {
- testFooBoxIsTrue("namespacePropertyInitializer.kt");
+ checkFooBoxIsTrue("namespacePropertyInitializer.kt");
}
public void testNamespacePropertySet() throws Exception {
- testFooBoxIsTrue("namespacePropertySet.kt");
+ checkFooBoxIsTrue("namespacePropertySet.kt");
}
public void testNamespaceCustomAccessors() throws Exception {
- testFooBoxIsTrue("namespaceCustomAccessors.kt");
+ checkFooBoxIsTrue("namespaceCustomAccessors.kt");
}
public void testClassUsesNamespaceProperties() throws Exception {
- testFooBoxIsTrue("classUsesNamespaceProperties.kt");
+ checkFooBoxIsTrue("classUsesNamespaceProperties.kt");
}
public void testSafeAccess() throws Exception {
- testFooBoxIsTrue("safeAccess.kt");
+ checkFooBoxIsTrue("safeAccess.kt");
}
public void testSafeExtensionFunctionCall() throws Exception {
- testFooBoxIsOk("safeExtensionFunctionCall.kt");
+ checkFooBoxIsOk("safeExtensionFunctionCall.kt");
}
public void testExtensionLiteralSafeCall() throws Exception {
- testFooBoxIsTrue("extensionLiteralSafeCall.kt");
+ checkFooBoxIsTrue("extensionLiteralSafeCall.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/RTTITest.java b/js/js.tests/test/org/jetbrains/k2js/test/RTTITest.java
index 03ea3e85b9c..2529fbcc5ee 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/RTTITest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/RTTITest.java
@@ -29,10 +29,10 @@ public class RTTITest extends TranslationTest {
}
public void testIsSameClass() throws Exception {
- testFooBoxIsTrue("isSameClass.kt");
+ checkFooBoxIsTrue("isSameClass.kt");
}
public void testNotIsOtherClass() throws Exception {
- testFooBoxIsTrue("notIsOtherClass.kt");
+ checkFooBoxIsTrue("notIsOtherClass.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/RangeTest.java b/js/js.tests/test/org/jetbrains/k2js/test/RangeTest.java
index fe3b89d2756..6fbc5269a41 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/RangeTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/RangeTest.java
@@ -30,20 +30,20 @@ public final class RangeTest extends TranslationTest {
public void testExplicitRange() throws Exception {
- testFooBoxIsTrue("explicitRange.kt");
+ checkFooBoxIsTrue("explicitRange.kt");
}
public void testRangeSugarSyntax() throws Exception {
- testFooBoxIsTrue("rangeSugarSyntax.kt");
+ checkFooBoxIsTrue("rangeSugarSyntax.kt");
}
public void testIntInRange() throws Exception {
- testFooBoxIsTrue("intInRange.kt");
+ checkFooBoxIsTrue("intInRange.kt");
}
public void testIteratingOverRanges() throws Exception {
- testFooBoxIsTrue("iteratingOverRanges.kt");
+ checkFooBoxIsTrue("iteratingOverRanges.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/SimpleTestSuite.java b/js/js.tests/test/org/jetbrains/k2js/test/SimpleTestSuite.java
index 6f8f741ca4f..5b7637a36ba 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/SimpleTestSuite.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/SimpleTestSuite.java
@@ -29,7 +29,7 @@ public final class SimpleTestSuite extends UsefulTestCase {
return Suite.suiteForDirectory("simple/", new Suite.SingleFileTester() {
@Override
public void performTest(@NotNull Suite test, @NotNull String filename) throws Exception {
- test.testFooBoxIsTrue(filename);
+ test.checkFooBoxIsTrue(filename);
}
});
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/StandardClassesTest.java b/js/js.tests/test/org/jetbrains/k2js/test/StandardClassesTest.java
index 95b2cbedcf1..51578051cc4 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/StandardClassesTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/StandardClassesTest.java
@@ -29,38 +29,38 @@ public class StandardClassesTest extends TranslationTest {
public void testArray() throws Exception {
- testFooBoxIsTrue("array.kt");
+ checkFooBoxIsTrue("array.kt");
}
public void testArrayAccess() throws Exception {
- testFooBoxIsTrue("arrayAccess.kt");
+ checkFooBoxIsTrue("arrayAccess.kt");
}
public void testArrayIsFilledWithNulls() throws Exception {
- testFooBoxIsTrue("arrayIsFilledWithNulls.kt");
+ checkFooBoxIsTrue("arrayIsFilledWithNulls.kt");
}
public void testArrayFunctionConstructor() throws Exception {
- testFooBoxIsTrue("arrayFunctionConstructor.kt");
+ checkFooBoxIsTrue("arrayFunctionConstructor.kt");
}
public void testArraySize() throws Exception {
- testFooBoxIsTrue("arraySize.kt");
+ checkFooBoxIsTrue("arraySize.kt");
}
//TODO: this feature in not supported for some time
//TODO: support it. Probably configurable.
// (expected = JavaScriptException.class)
// public void arrayThrowsExceptionOnOOBaccess() throws Exception {
-// testFooBoxIsTrue("arrayThrowsExceptionOnOOBaccess.kt");
+// checkFooBoxIsTrue("arrayThrowsExceptionOnOOBaccess.kt");
// }
public void testArraysIterator() throws Exception {
- testFooBoxIsTrue("arraysIterator.kt");
+ checkFooBoxIsTrue("arraysIterator.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/StringTest.java b/js/js.tests/test/org/jetbrains/k2js/test/StringTest.java
index bf45441f9e7..b01412c5f06 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/StringTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/StringTest.java
@@ -29,11 +29,11 @@ public class StringTest extends AbstractExpressionTest {
}
public void testStringConstant() throws Exception {
- testFooBoxIsTrue("stringConstant.kt");
+ checkFooBoxIsTrue("stringConstant.kt");
}
public void testStringAssignment() throws Exception {
- testFooBoxIsTrue("stringAssignment.kt");
+ checkFooBoxIsTrue("stringAssignment.kt");
}
public void testIntInTemplate() throws Exception {
@@ -49,6 +49,6 @@ public class StringTest extends AbstractExpressionTest {
}
public void testToStringMethod() throws Exception {
- testFooBoxIsTrue("objectToStringCallInTemplate.kt");
+ checkFooBoxIsTrue("objectToStringCallInTemplate.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/Suite.java b/js/js.tests/test/org/jetbrains/k2js/test/Suite.java
index 75ff01988a0..4151de967e5 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/Suite.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/Suite.java
@@ -35,6 +35,7 @@ public final class Suite extends TranslationTest {
this.name = testName;
this.tester = tester;
this.testMain = suiteDirName;
+ setName(name);
}
public Suite() {
@@ -46,10 +47,15 @@ public final class Suite extends TranslationTest {
});
}
-// //NOTE: just to avoid warning
+ //NOTE: just to avoid warning
public void testNothing() {
}
+ @Override
+ protected boolean shouldCreateOut() {
+ return false;
+ }
+
@Override
protected String mainDirectory() {
return testMain;
@@ -62,13 +68,15 @@ public final class Suite extends TranslationTest {
public static Test suiteForDirectory(@NotNull final String mainName, @NotNull final SingleFileTester testMethod) {
return TranslatorTestCaseBuilder.suiteForDirectory(TranslationTest.TEST_FILES,
- mainName + casesDirectoryName(), true, new TranslatorTestCaseBuilder.NamedTestFactory() {
- @NotNull
- @Override
- public Test createTest(@NotNull String name) {
- return (new Suite(name, mainName, testMethod));
- }
- });
+ mainName + casesDirectoryName(),
+ true,
+ new TranslatorTestCaseBuilder.NamedTestFactory() {
+ @NotNull
+ @Override
+ public Test createTest(@NotNull String name) {
+ return (new Suite(name, mainName, testMethod));
+ }
+ });
}
protected static interface SingleFileTester {
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/TraitTest.java b/js/js.tests/test/org/jetbrains/k2js/test/TraitTest.java
index f58d18d038f..0363121db1c 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/TraitTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/TraitTest.java
@@ -30,41 +30,41 @@ public final class TraitTest extends TranslationTest {
public void testTraitAddsFunctionsToClass() throws Exception {
- testFooBoxIsTrue("traitAddsFunctionsToClass.kt");
+ checkFooBoxIsTrue("traitAddsFunctionsToClass.kt");
}
public void testClassDerivesFromClassAndTrait() throws Exception {
- testFooBoxIsTrue("classDerivesFromClassAndTrait.kt");
+ checkFooBoxIsTrue("classDerivesFromClassAndTrait.kt");
}
public void testClassDerivesFromTraitAndClass() throws Exception {
- testFooBoxIsTrue("classDerivesFromTraitAndClass.kt");
+ checkFooBoxIsTrue("classDerivesFromTraitAndClass.kt");
}
public void testExample() throws Exception {
- testFooBoxIsTrue("example.kt");
+ checkFooBoxIsTrue("example.kt");
}
public void testTraitExtendsTrait() throws Exception {
- testFooBoxIsTrue("traitExtendsTrait.kt");
+ checkFooBoxIsTrue("traitExtendsTrait.kt");
}
public void testTraitExtendsTwoTraits() throws Exception {
- testFooBoxIsTrue("traitExtendsTwoTraits.kt");
+ checkFooBoxIsTrue("traitExtendsTwoTraits.kt");
}
public void testFunDelegation() throws Exception {
- testFooBoxIsOk("funDelegation.jet");
+ checkFooBoxIsOk("funDelegation.jet");
}
public void testDefinitionOrder() throws Exception {
- testFooBoxIsTrue("definitionOrder.kt");
+ checkFooBoxIsTrue("definitionOrder.kt");
}
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/TranslationTest.java b/js/js.tests/test/org/jetbrains/k2js/test/TranslationTest.java
index bbb77c11318..dcb12157e3d 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/TranslationTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/TranslationTest.java
@@ -17,6 +17,7 @@
package org.jetbrains.k2js.test;
import com.google.dart.compiler.backend.js.ast.JsProgram;
+import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.k2js.facade.K2JSTranslator;
@@ -27,9 +28,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -44,7 +42,8 @@ import static org.jetbrains.k2js.utils.JetFileUtils.createPsiFileList;
*/
public abstract class TranslationTest extends BaseTest {
- public final static String TEST_FILES = "js.translator/testFiles/";
+ private static final boolean DELETE_OUT = false;
+ public static final String TEST_FILES = "js.translator/testFiles/";
private static final String CASES = "cases/";
private static final String OUT = "out/";
private static final String KOTLIN_JS_LIB = TEST_FILES + "kotlin_lib.js";
@@ -63,6 +62,32 @@ public abstract class TranslationTest extends BaseTest {
K2JSTranslator.saveProgramToFile(outputFile, program);
}
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ if (!shouldCreateOut()) {
+ return;
+ }
+ File outDir = new File(getOutputPath());
+ assert (!outDir.exists() || outDir.isDirectory()) : "If out already exists it should be a directory.";
+ if (!outDir.exists()) {
+ boolean success = outDir.mkdir();
+ assert success;
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (!shouldCreateOut() || !DELETE_OUT) {
+ return;
+ }
+ File outDir = new File(getOutputPath());
+ assert outDir.exists();
+ boolean success = FileUtil.delete(outDir);
+ assert success;
+ }
+
protected static String kotlinLibraryPath() {
return KOTLIN_JS_LIB;
}
@@ -116,6 +141,10 @@ public abstract class TranslationTest extends BaseTest {
new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
}
+ protected boolean shouldCreateOut() {
+ return true;
+ }
+
protected void translateFile(String filename) throws Exception {
translateFile(getInputFilePath(filename),
getOutputFilePath(filename));
@@ -126,7 +155,7 @@ public abstract class TranslationTest extends BaseTest {
File dir = new File(dirPath);
List fullFilePaths = new ArrayList();
for (String fileName : dir.list()) {
- fullFilePaths.add(getInputFilePath(dirName) + "\\" + fileName);
+ fullFilePaths.add(getInputFilePath(dirName) + "/" + fileName);
}
assert dir.isDirectory();
traslateFiles(fullFilePaths,
@@ -158,13 +187,17 @@ public abstract class TranslationTest extends BaseTest {
return getExpectedPath() + testName + ".out";
}
- protected void runFileWithRhino(String inputFile, Context context, Scriptable scope) throws Exception {
+ protected static void runFileWithRhino(String inputFile, Context context, Scriptable scope) throws Exception {
FileReader reader = new FileReader(inputFile);
- context.evaluateReader(scope, reader, inputFile, 1, null);
- reader.close();
+ try {
+ context.evaluateReader(scope, reader, inputFile, 1, null);
+ } finally {
+ reader.close();
+ }
}
- protected void runRhinoTest(List fileNames, RhinoResultChecker checker) throws Exception {
+ protected static void runRhinoTest(@NotNull List fileNames,
+ @NotNull RhinoResultChecker checker) throws Exception {
Context context = Context.enter();
Scriptable scope = context.initStandardObjects();
for (String filename : fileNames) {
@@ -174,11 +207,11 @@ public abstract class TranslationTest extends BaseTest {
Context.exit();
}
- public void testFooBoxIsTrue(String filename) throws Exception {
+ public void checkFooBoxIsTrue(String filename) throws Exception {
testFunctionOutput(filename, "foo", "box", true);
}
- public void testFooBoxIsOk(String filename) throws Exception {
+ public void checkFooBoxIsOk(String filename) throws Exception {
testFunctionOutput(filename, "foo", "box", "OK");
}
@@ -188,21 +221,16 @@ public abstract class TranslationTest extends BaseTest {
new RhinoSystemOutputChecker(expectedResult, Arrays.asList(args)));
}
- protected void testWithMain(String testName, String testId, String... args) throws Exception {
+ protected void performTestWithMain(String testName, String testId, String... args) throws Exception {
checkOutput(testName + ".kt", readFile(expected(testName + testId)), args);
}
private static String readFile(String path) throws IOException {
FileInputStream stream = new FileInputStream(new File(path));
try {
- FileChannel fc = stream.getChannel();
- MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
- /* Instead of using default, pass in a decoder. */
- return Charset.defaultCharset().decode(bb).toString();
+ return FileUtil.loadTextAndClose(stream);
} finally {
stream.close();
}
}
-
-
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/TranslatorTestCaseBuilder.java b/js/js.tests/test/org/jetbrains/k2js/test/TranslatorTestCaseBuilder.java
index ff9a8ed4c78..4f6b8c7cdb2 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/TranslatorTestCaseBuilder.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/TranslatorTestCaseBuilder.java
@@ -53,6 +53,7 @@ public abstract class TranslatorTestCaseBuilder {
public static TestSuite suiteForDirectory(String baseDataDir, @NotNull final String dataPath, boolean recursive,
final FilenameFilter filter, @NotNull NamedTestFactory factory) {
TestSuite suite = new TestSuite(dataPath);
+ suite.setName(dataPath);
appendTestsInDirectory(baseDataDir, dataPath, recursive, filter, factory, suite);
return suite;
}
@@ -75,7 +76,8 @@ public abstract class TranslatorTestCaseBuilder {
return extensionFilter.accept(file, s) && filter.accept(file, s);
}
};
- } else {
+ }
+ else {
resultFilter = extensionFilter;
}
File dir = new File(baseDataDir + dataPath);
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/TupleTest.java b/js/js.tests/test/org/jetbrains/k2js/test/TupleTest.java
index d40b350d90f..e2e18fbe6e8 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/TupleTest.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/TupleTest.java
@@ -29,11 +29,11 @@ public final class TupleTest extends TranslationTest {
}
public void testTwoElements() throws Exception {
- testFooBoxIsTrue("twoElements.kt");
+ checkFooBoxIsTrue("twoElements.kt");
}
public void testMultipleMembers() throws Exception {
- testFooBoxIsTrue("multipleMembers.kt");
+ checkFooBoxIsTrue("multipleMembers.kt");
}
diff --git a/js/js.tests/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java b/js/js.tests/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java
index 1eb409c2b8a..cd9da6a45b3 100644
--- a/js/js.tests/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java
+++ b/js/js.tests/test/org/jetbrains/k2js/test/WebDemoExamples2Test.java
@@ -29,22 +29,22 @@ public final class WebDemoExamples2Test extends TranslationTest {
}
public void testBottles() throws Exception {
- testWithMain("bottles", "2", "2");
- testWithMain("bottles", "");
+ performTestWithMain("bottles", "2", "2");
+ performTestWithMain("bottles", "");
}
public void testLife() throws Exception {
- testWithMain("life", "", "2");
+ performTestWithMain("life", "", "2");
}
public void testBuilder() throws Exception {
- testWithMain("builder", "");
- testWithMain("builder", "1", "over9000");
+ performTestWithMain("builder", "");
+ performTestWithMain("builder", "1", "over9000");
}
//TODO: comparator LinkedList dependencies
// @Test
// public void maze() throws Exception {
-// testWithMain("maze", "");
+// performTestWithMain("maze", "");
// }
}
diff --git a/js/js.translator/lib/args4j-2.0.12.jar b/js/js.translator/lib/args4j-2.0.12.jar
new file mode 100644
index 00000000000..61a4d5a6485
Binary files /dev/null and b/js/js.translator/lib/args4j-2.0.12.jar differ
diff --git a/js/js.translator/lib/dartc.jar b/js/js.translator/lib/dartc.jar
index 5ffa521701b..c0e03cf6411 100644
Binary files a/js/js.translator/lib/dartc.jar and b/js/js.translator/lib/dartc.jar differ
diff --git a/js/js.translator/lib/guava-10.0.1.jar b/js/js.translator/lib/guava-10.0.1.jar
deleted file mode 100644
index d107c0f3b0c..00000000000
Binary files a/js/js.translator/lib/guava-10.0.1.jar and /dev/null differ
diff --git a/js/js.translator/lib/json.jar b/js/js.translator/lib/json.jar
new file mode 100644
index 00000000000..b8838d19dc7
Binary files /dev/null and b/js/js.translator/lib/json.jar differ
diff --git a/js/js.translator/src/org/jetbrains/k2js/analyze/Analyzer.java b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacade.java
similarity index 92%
rename from js/js.translator/src/org/jetbrains/k2js/analyze/Analyzer.java
rename to js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacade.java
index 9337a34131a..890f0624499 100644
--- a/js/js.translator/src/org/jetbrains/k2js/analyze/Analyzer.java
+++ b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacade.java
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.Configuration;
import org.jetbrains.jet.lang.JetSemanticServices;
-import org.jetbrains.jet.lang.StandardConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -40,9 +39,9 @@ import java.util.List;
/**
* @author Pavel Talanov
*/
-public final class Analyzer {
+public final class AnalyzerFacade {
- private Analyzer() {
+ private AnalyzerFacade() {
}
@NotNull
@@ -58,10 +57,10 @@ public final class Analyzer {
@NotNull Config config) {
Project project = config.getProject();
return AnalyzingUtils.analyzeFiles(project,
- JsConfiguration.jsLibConfiguration(project),
- withJsLibAdded(files, config),
- notLibFiles(config.getLibFiles()),
- JetControlFlowDataTraceFactory.EMPTY);
+ JsConfiguration.jsLibConfiguration(project),
+ withJsLibAdded(files, config),
+ notLibFiles(config.getLibFiles()),
+ JetControlFlowDataTraceFactory.EMPTY);
}
private static void checkForErrors(@NotNull List allFiles, @NotNull BindingContext bindingContext) {
@@ -105,7 +104,6 @@ public final class Analyzer {
JetControlFlowDataTraceFactory.EMPTY,
bindingTraceContext,
semanticServices);
-// return AnalyzerFacade.analyzeOneFileWithJavaIntegration(file, flowDataTraceFactory);
}
private static final class JsConfiguration implements Configuration {
diff --git a/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java b/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java
index fe744752b94..7840ead283d 100644
--- a/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/facade/K2JSTranslator.java
@@ -23,7 +23,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.plugin.JetMainDetector;
-import org.jetbrains.k2js.analyze.Analyzer;
+import org.jetbrains.k2js.analyze.AnalyzerFacade;
import org.jetbrains.k2js.config.Config;
import org.jetbrains.k2js.config.IDEAConfig;
import org.jetbrains.k2js.generate.CodeGenerator;
@@ -61,8 +61,11 @@ public final class K2JSTranslator {
}
String callToMain = translator.generateCallToMain(fileWithMain, "");
FileWriter writer = new FileWriter(new File(outputPath));
- writer.write(programCode + callToMain);
- writer.close();
+ try {
+ writer.write(programCode + callToMain);
+ } finally {
+ writer.close();
+ }
}
public static void saveProgramToFile(@NotNull String outputFile, @NotNull JsProgram program) throws IOException {
@@ -79,6 +82,8 @@ public final class K2JSTranslator {
}
//TODO: refactor
+ //TODO: web demo related method
+ @SuppressWarnings("UnusedDeclaration")
@NotNull
public String translateStringWithCallToMain(@NotNull String programText, @NotNull String argumentsString) {
JetFile file = JetFileUtils.createPsiFile("test", programText, getProject());
@@ -103,18 +108,20 @@ public final class K2JSTranslator {
return generator.generateToString(program);
}
+ //TODO: relates to web demo
+ @SuppressWarnings("UnusedDeclaration")
@NotNull
public BindingContext analyzeProgramCode(@NotNull String programText) {
JetFile file = JetFileUtils.createPsiFile("test", programText, getProject());
- return Analyzer.analyzeFiles(Arrays.asList(file), config);
+ return AnalyzerFacade.analyzeFiles(Arrays.asList(file), config);
}
@NotNull
public JsProgram generateProgram(@NotNull List filesToTranslate) {
JetStandardLibrary.initialize(config.getProject());
- BindingContext bindingContext = Analyzer.analyzeFilesAndCheckErrors(filesToTranslate, config);
- return Translation.generateAst(bindingContext, Analyzer.withJsLibAdded(filesToTranslate, config));
+ BindingContext bindingContext = AnalyzerFacade.analyzeFilesAndCheckErrors(filesToTranslate, config);
+ return Translation.generateAst(bindingContext, AnalyzerFacade.withJsLibAdded(filesToTranslate, config));
}
@@ -126,7 +133,7 @@ public final class K2JSTranslator {
}
@NotNull
- private List parseString(@NotNull String argumentString) {
+ private static List parseString(@NotNull String argumentString) {
List result = new ArrayList();
StringTokenizer stringTokenizer = new StringTokenizer(argumentString);
while (stringTokenizer.hasMoreTokens()) {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/NamingScope.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/NamingScope.java
index 6b267859ab2..122bad33a81 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/context/NamingScope.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/NamingScope.java
@@ -19,8 +19,7 @@ package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
-
-import java.util.Iterator;
+import org.jetbrains.k2js.translate.utils.JsAstUtils;
/**
* @author Pavel Talanov
@@ -80,7 +79,7 @@ public final class NamingScope {
String result = name;
while (true) {
JsName existingNameWithSameIdent = scope.findExistingName(result);
- boolean isDuplicate = (existingNameWithSameIdent != null) && ownsName(scope, existingNameWithSameIdent);
+ boolean isDuplicate = (existingNameWithSameIdent != null) && JsAstUtils.ownsName(scope, existingNameWithSameIdent);
if (!isDuplicate) break;
@@ -90,17 +89,6 @@ public final class NamingScope {
return result;
}
- //TODO: util?
- private static boolean ownsName(@NotNull JsScope scope, @NotNull JsName name) {
- Iterator nameIterator = scope.getAllNames();
- while (nameIterator.hasNext()) {
- if (nameIterator.next() == name) {
- return true;
- }
- }
- return false;
- }
-
@NotNull
public JsName declareTemporary() {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java
index b588c225ecc..bb3de688359 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java
@@ -323,6 +323,7 @@ public final class StaticContext {
}
}
+ @NotNull
private NamingScope getEnclosingScope(@NotNull DeclarationDescriptor descriptor) {
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
return getScopeForDescriptor(containingDeclaration.getOriginal());
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java
index 35c86f5dc6d..75c2071bbe6 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
+import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
import java.util.List;
@@ -165,10 +166,7 @@ public final class ClassTranslator extends AbstractTranslator {
}
propertyList.addAll(translatePropertiesAsConstructorParameters());
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, context()));
- //TODO: util?
- JsObjectLiteral jsObjectLiteral = new JsObjectLiteral();
- jsObjectLiteral.getPropertyInitializers().addAll(propertyList);
- return jsObjectLiteral;
+ return JsAstUtils.newObjectLiteral(propertyList);
}
@NotNull
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java
index 4309096dd25..cbff606f420 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceDeclarationTranslator.java
@@ -100,7 +100,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
}
@NotNull
- private List declarationStatements(@NotNull List namespaceTranslators) {
+ private static List declarationStatements(@NotNull List namespaceTranslators) {
List result = Lists.newArrayList();
for (NamespaceTranslator translator : namespaceTranslators) {
result.add(translator.getDeclarationStatement());
@@ -109,7 +109,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
}
@NotNull
- private List initializeStatements(@NotNull List namespaceTranslators) {
+ private static List initializeStatements(@NotNull List namespaceTranslators) {
List result = Lists.newArrayList();
for (NamespaceTranslator translator : namespaceTranslators) {
result.add(translator.getInitializeStatement());
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java
index f026b6aed24..6f7380e1040 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java
@@ -29,8 +29,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.ArrayList;
import java.util.List;
-import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
-import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
+import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
/**
* @author Pavel.Talanov
@@ -96,9 +95,6 @@ public final class NamespaceTranslator extends AbstractTranslator {
List propertyList = new ArrayList();
propertyList.add(Translation.generateNamespaceInitializerMethod(descriptor, context()));
propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(descriptor, context()));
- //TODO: make util, search for dups
- JsObjectLiteral jsObjectLiteral = new JsObjectLiteral();
- jsObjectLiteral.getPropertyInitializers().addAll(propertyList);
- return jsObjectLiteral;
+ return newObjectLiteral(propertyList);
}
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
index 23770651790..fa6c0c2c373 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
@@ -224,6 +224,7 @@ public final class ExpressionVisitor extends TranslatorVisitor {
return translateAsExpression(expression, context);
}
+ //NOTE: since JsWhile and JsDoWhile do not have an ancestor, cannot avoid duplication here
@Override
@NotNull
public JsNode visitWhileExpression(@NotNull JetWhileExpression expression, @NotNull TranslationContext context) {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java
index 6441f04b066..eeca826c737 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java
@@ -128,15 +128,15 @@ public final class FunctionTranslator extends AbstractTranslator {
@NotNull
private JsFunction createFunctionObject() {
- if (isDeclaration()) {
- return context().getFunctionObject(descriptor);
- }
- if (isLiteral()) {
- //TODO: changing this piece of code to more natural "same as for declaration" results in life test failing
- //TODO: must investigate
- return new JsFunction(context().jsScope());
- }
- throw new AssertionError("Unsupported type of functionDeclaration.");
+ // if (isDeclaration()) {
+ return context().getFunctionObject(descriptor);
+// }
+// if (isLiteral()) {
+// //TODO: changing this piece of code to more natural "same as for declaration" results in life test failing
+// //TODO: must investigate
+// return new JsFunction(context().jsScope());
+// }
+ // throw new AssertionError("Unsupported type of functionDeclaration.");
}
private void translateBody() {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java
index 58c1a09d8bb..73401186594 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java
@@ -28,7 +28,6 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.BindingUtils;
-import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
@@ -134,6 +133,6 @@ public final class PatternTranslator extends AbstractTranslator {
assert patternExpression != null : "Expression patter should have an expression.";
JsExpression expressionToMatchAgainst =
Translation.translateAsExpression(patternExpression, context());
- return JsAstUtils.equals(expressionToMatch, expressionToMatchAgainst);
+ return equality(expressionToMatch, expressionToMatchAgainst);
}
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java
index 42432d4bba9..d33d534b17e 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java
@@ -82,8 +82,8 @@ public class WhenTranslator extends AbstractTranslator {
@NotNull
private JsStatement surroundWithDummyIf(@NotNull JsStatement entryStatement) {
- JsExpression stepNumberEqualsCurrentEntryNumber = new JsBinaryOperation(JsBinaryOperator.EQ,
- dummyCounter.reference(), program().getNumberLiteral(currentEntryNumber));
+ JsNumberLiteral jsEntryNumber = program().getNumberLiteral(this.currentEntryNumber);
+ JsExpression stepNumberEqualsCurrentEntryNumber = equality(dummyCounter.reference(), jsEntryNumber);
currentEntryNumber++;
return new JsIf(stepNumberEqualsCurrentEntryNumber, entryStatement, null);
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java
index ecd94aac82a..fa2d508388b 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
-import org.jetbrains.k2js.translate.intrinsic.string.LengthIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.Collections;
@@ -34,7 +34,6 @@ import java.util.List;
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
-import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
/**
@@ -43,8 +42,8 @@ import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
public final class ArrayForTranslator extends ForTranslator {
@NotNull
- public static JsStatement translate(@NotNull JetForExpression expression,
- @NotNull TranslationContext context) {
+ public static JsStatement doTranslate(@NotNull JetForExpression expression,
+ @NotNull TranslationContext context) {
return (new ArrayForTranslator(expression, context).translate());
}
@@ -70,7 +69,10 @@ public final class ArrayForTranslator extends ForTranslator {
private ArrayForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
super(forExpression, context);
loopRange = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
- JsExpression length = LengthIntrinsic.INSTANCE.apply(loopRange.reference(), Collections.emptyList(), context());
+ Intrinsic lengthPropertyIntrinsic = context().intrinsics().getLengthPropertyIntrinsic();
+ JsExpression length = lengthPropertyIntrinsic.apply(loopRange.reference(),
+ Collections.emptyList(),
+ context());
end = context().declareTemporary(length);
index = context().declareTemporary(program().getNumberLiteral(0));
}
@@ -78,36 +80,27 @@ public final class ArrayForTranslator extends ForTranslator {
@NotNull
private JsBlock translate() {
List blockStatements = temporariesInitialization(loopRange, end);
- blockStatements.add(generateForExpression());
+ blockStatements.add(generateForExpression(getInitExpression(), getCondition(), getIncrExpression(), getBody()));
return newBlock(blockStatements);
}
- @NotNull
- private JsFor generateForExpression() {
- JsFor result = new JsFor();
- result.setInitVars(initExpression());
- result.setCondition(getCondition());
- result.setIncrExpr(getIncrExpression());
- result.setBody(getBody());
- return result;
- }
@NotNull
private JsStatement getBody() {
JsArrayAccess arrayAccess = new JsArrayAccess(loopRange.reference(), index.reference());
JsStatement currentVar = newVar(parameterName, arrayAccess);
- JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context());
+ JsStatement realBody = translateOriginalBodyExpression();
return AstUtil.newBlock(currentVar, realBody);
}
@NotNull
- private JsVars initExpression() {
+ private JsVars getInitExpression() {
return newVar(index.name(), program().getNumberLiteral(0));
}
@NotNull
private JsExpression getCondition() {
- return notEqual(index.reference(), end.reference());
+ return inequality(index.reference(), end.reference());
}
@NotNull
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java
index 776d8d578e8..831769a86d1 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java
@@ -39,15 +39,15 @@ public abstract class ForTranslator extends AbstractTranslator {
public static JsStatement translate(@NotNull JetForExpression expression,
@NotNull TranslationContext context) {
if (RangeLiteralForTranslator.isApplicable(expression, context)) {
- return RangeLiteralForTranslator.translate(expression, context);
+ return RangeLiteralForTranslator.doTranslate(expression, context);
}
if (RangeForTranslator.isApplicable(expression, context)) {
- return RangeForTranslator.translate(expression, context);
+ return RangeForTranslator.doTranslate(expression, context);
}
if (ArrayForTranslator.isApplicable(expression, context)) {
- return ArrayForTranslator.translate(expression, context);
+ return ArrayForTranslator.doTranslate(expression, context);
}
- return IteratorForTranslator.translate(expression, context);
+ return IteratorForTranslator.doTranslate(expression, context);
}
@NotNull
@@ -67,7 +67,6 @@ public abstract class ForTranslator extends AbstractTranslator {
return context().getNameForElement(loopParameter);
}
- //TODO: look for should-be-usages
@NotNull
protected JsStatement translateOriginalBodyExpression() {
return Translation.translateAsStatement(getLoopBody(expression), context());
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java
index 8b537937218..b088e0114f7 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java
@@ -41,8 +41,8 @@ import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
public final class IteratorForTranslator extends ForTranslator {
@NotNull
- public static JsStatement translate(@NotNull JetForExpression expression,
- @NotNull TranslationContext context) {
+ public static JsStatement doTranslate(@NotNull JetForExpression expression,
+ @NotNull TranslationContext context) {
return (new IteratorForTranslator(expression, context).translate());
}
@@ -61,6 +61,7 @@ public final class IteratorForTranslator extends ForTranslator {
return AstUtil.newBlock(iterator.assignmentExpression().makeStmt(), cycle);
}
+ //TODO: check whether complex logic with blocks is needed
@NotNull
private JsBlock generateCycleBody() {
JsBlock cycleBody = new JsBlock();
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java
index e8501e036ee..c509b2fb80a 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java
@@ -32,7 +32,6 @@ import java.util.List;
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
-import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
/**
@@ -42,8 +41,8 @@ public final class RangeForTranslator extends ForTranslator {
//TODO: inspection
@NotNull
- public static JsStatement translate(@NotNull JetForExpression expression,
- @NotNull TranslationContext context) {
+ public static JsStatement doTranslate(@NotNull JetForExpression expression,
+ @NotNull TranslationContext context) {
return (new RangeForTranslator(expression, context).translate());
}
@@ -52,6 +51,7 @@ public final class RangeForTranslator extends ForTranslator {
JetExpression loopRange = getLoopRange(expression);
JetType rangeType = BindingUtils.getTypeForExpression(context.bindingContext(), loopRange);
//TODO: better check
+ //TODO: long range?
return getClassDescriptorForType(rangeType).getName().equals("IntRange");
}
@@ -73,7 +73,7 @@ public final class RangeForTranslator extends ForTranslator {
program().getNumberLiteral(1));
incrVar = context().declareTemporary(incrVarValue);
start = context().declareTemporary(callFunction("get_start"));
- end = context().declareTemporary(new JsBinaryOperation(JsBinaryOperator.ADD, callFunction("get_end"), incrVar.reference()));
+ end = context().declareTemporary(sum(callFunction("get_end"), incrVar.reference()));
}
@NotNull
@@ -89,7 +89,7 @@ public final class RangeForTranslator extends ForTranslator {
result.setInitVars(initExpression());
result.setCondition(getCondition());
result.setIncrExpr(getIncrExpression());
- result.setBody(Translation.translateAsStatement(getLoopBody(expression), context()));
+ result.setBody(translateOriginalBodyExpression());
return result;
}
@@ -100,12 +100,12 @@ public final class RangeForTranslator extends ForTranslator {
@NotNull
private JsExpression getCondition() {
- return notEqual(parameterName.makeRef(), end.reference());
+ return inequality(parameterName.makeRef(), end.reference());
}
@NotNull
private JsExpression getIncrExpression() {
- return new JsBinaryOperation(JsBinaryOperator.ASG_ADD, parameterName.makeRef(), incrVar.reference());
+ return addAssign(parameterName.makeRef(), incrVar.reference());
}
@NotNull
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java
index 585c98e9807..2f4baa5c046 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java
@@ -41,8 +41,8 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRight
public final class RangeLiteralForTranslator extends ForTranslator {
@NotNull
- public static JsStatement translate(@NotNull JetForExpression expression,
- @NotNull TranslationContext context) {
+ public static JsStatement doTranslate(@NotNull JetForExpression expression,
+ @NotNull TranslationContext context) {
return (new RangeLiteralForTranslator(expression, context).translate());
}
@@ -80,20 +80,13 @@ public final class RangeLiteralForTranslator extends ForTranslator {
@NotNull
private JsBlock translate() {
List blockStatements = temporariesInitialization(rangeEnd);
- blockStatements.add(generateForExpression());
+ blockStatements.add(generateForExpression(initExpression(),
+ getCondition(),
+ getIncrExpression(),
+ translateOriginalBodyExpression()));
return newBlock(blockStatements);
}
- @NotNull
- private JsFor generateForExpression() {
- JsFor result = new JsFor();
- result.setInitVars(initExpression());
- result.setCondition(getCondition());
- result.setIncrExpr(getIncrExpression());
- result.setBody(translateOriginalBodyExpression());
- return result;
- }
-
@NotNull
private JsVars initExpression() {
return newVar(parameterName, rangeStart);
@@ -101,7 +94,7 @@ public final class RangeLiteralForTranslator extends ForTranslator {
@NotNull
private JsExpression getCondition() {
- return notEqual(parameterName.makeRef(), rangeEnd.reference());
+ return inequality(parameterName.makeRef(), rangeEnd.reference());
}
@NotNull
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java
index 2f6e99bbe9b..44ba8651e96 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java
@@ -48,8 +48,9 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
private final List initializerStatements = new ArrayList();
public ClassInitializerTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) {
- super(context.getScopeForElement(classDeclaration).innerScope
- ("initializer " + classDeclaration.getName()), context);
+ // Note: it's important we use scope for class descriptor because anonymous function used in property initializers
+ // belong to the properties themselves
+ super(context.getScopeForDescriptor(getClassDescriptor(context.bindingContext(), classDeclaration)), context);
this.classDeclaration = classDeclaration;
}
@@ -83,6 +84,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
private void addCallToSuperMethod(@NotNull JetDelegatorToSuperCall superCall) {
//TODO: look into
JsName superMethodName = initializerMethodScope.jsScope().declareName(Namer.superMethodName());
+ superMethodName.setObfuscatable(false);
List arguments = translateArguments(superCall);
initializerStatements.add(convertToStatement(newInvocation(thisQualifiedReference(superMethodName), arguments)));
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/NamespaceInitializerTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/NamespaceInitializerTranslator.java
index 3e7173779c0..b0732d319f2 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/NamespaceInitializerTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/NamespaceInitializerTranslator.java
@@ -32,8 +32,8 @@ public final class NamespaceInitializerTranslator extends AbstractInitializerTra
private final NamespaceDescriptor namespace;
public NamespaceInitializerTranslator(@NotNull NamespaceDescriptor namespace, @NotNull TranslationContext context) {
- super(context.getScopeForDescriptor(namespace).innerScope
- ("initializer " + namespace.getName()), context);
+ //NOTE:
+ super(context.getScopeForDescriptor(namespace), context);
this.namespace = namespace;
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java
deleted file mode 100644
index 9a5e0eab723..00000000000
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2000-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.k2js.translate.intrinsic;
-
-/**
- * @author Pavel Talanov
- */
-public interface FunctionIntrinsic extends Intrinsic {
-
-}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java
index 9893e8f489d..8a130b98c71 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java
@@ -26,10 +26,12 @@ import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.PrimitiveType;
import org.jetbrains.jet.lexer.JetToken;
-import org.jetbrains.k2js.translate.intrinsic.array.*;
+import org.jetbrains.k2js.translate.intrinsic.array.ArrayGetIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.array.ArraySetIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.array.BuiltInPropertyIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.array.CallStandardMethodIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.primitive.*;
import org.jetbrains.k2js.translate.intrinsic.string.CharAtIntrinsic;
-import org.jetbrains.k2js.translate.intrinsic.string.LengthIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.tuple.TupleAccessIntrinsic;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
@@ -50,8 +52,8 @@ import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getPropertyByNa
public final class Intrinsics {
@NotNull
- private final Map functionIntrinsics =
- new HashMap();
+ private final Map functionIntrinsics =
+ new HashMap();
@NotNull
private final Map equalsIntrinsics =
@@ -61,6 +63,9 @@ public final class Intrinsics {
private final Map compareToIntrinsics =
new HashMap();
+ @NotNull
+ private final Intrinsic lengthPropertyIntrinsic = new BuiltInPropertyIntrinsic("length");
+
public static Intrinsics standardLibraryIntrinsics(@NotNull JetStandardLibrary library) {
return new Intrinsics(library);
}
@@ -76,6 +81,11 @@ public final class Intrinsics {
declareArrayIntrinsics();
}
+ @NotNull
+ public Intrinsic getLengthPropertyIntrinsic() {
+ return lengthPropertyIntrinsic;
+ }
+
private void declareTuplesIntrinsics() {
for (int tupleSize = 0; tupleSize < JetStandardClasses.TUPLE_COUNT; ++tupleSize) {
declareTupleIntrinsics(tupleSize);
@@ -94,9 +104,8 @@ public final class Intrinsics {
}
private void declareNullConstructorIntrinsic() {
- //TODO:
FunctionDescriptor nullArrayConstructor = library.getLibraryScope().getFunctions("Array").iterator().next();
- functionIntrinsics.put(nullArrayConstructor, ArrayNullConstructorIntrinsic.INSTANCE);
+ functionIntrinsics.put(nullArrayConstructor, new CallStandardMethodIntrinsic("Kotlin.nullArray", false, 1));
}
//TODO: some dangerous operation unchecked here
@@ -107,14 +116,15 @@ public final class Intrinsics {
FunctionDescriptor getFunction = getFunctionByName(arrayMemberScope, "get");
functionIntrinsics.put(getFunction, ArrayGetIntrinsic.INSTANCE);
PropertyDescriptor sizeProperty = getPropertyByName(arrayMemberScope, "size");
- functionIntrinsics.put(sizeProperty.getGetter(), ArraySizeIntrinsic.INSTANCE);
+ functionIntrinsics.put(sizeProperty.getGetter(), lengthPropertyIntrinsic);
+ //TODO: excessive object creation
PropertyDescriptor indicesProperty = getPropertyByName(arrayMemberScope, "indices");
- functionIntrinsics.put(indicesProperty.getGetter(), ArrayIndicesIntrinsic.INSTANCE);
+ functionIntrinsics.put(indicesProperty.getGetter(), new CallStandardMethodIntrinsic("Kotlin.arrayIndices", true, 0));
FunctionDescriptor iteratorFunction = getFunctionByName(arrayMemberScope, "iterator");
- functionIntrinsics.put(iteratorFunction, ArrayIteratorIntrinsic.INSTANCE);
+ functionIntrinsics.put(iteratorFunction, new CallStandardMethodIntrinsic("Kotlin.arrayIterator", true, 0));
ConstructorDescriptor arrayConstructor =
((ClassDescriptor) arrayMemberScope.getContainingDeclaration()).getConstructors().iterator().next();
- functionIntrinsics.put(arrayConstructor, ArrayFunctionConstructorIntrinsic.INSTANCE);
+ functionIntrinsics.put(arrayConstructor, new CallStandardMethodIntrinsic("Kotlin.arrayFromFun", false, 2));
}
private List getLibraryArrayTypes() {
@@ -137,7 +147,7 @@ public final class Intrinsics {
private void declareStringIntrinsics() {
PropertyDescriptor lengthProperty =
getPropertyByName(library.getCharSequence().getDefaultType().getMemberScope(), "length");
- functionIntrinsics.put(lengthProperty.getGetter(), LengthIntrinsic.INSTANCE);
+ functionIntrinsics.put(lengthProperty.getGetter(), new BuiltInPropertyIntrinsic("length"));
FunctionDescriptor getFunction =
getFunctionByName(library.getString().getDefaultType().getMemberScope(), "get");
functionIntrinsics.put(getFunction, CharAtIntrinsic.INSTANCE);
@@ -173,7 +183,7 @@ public final class Intrinsics {
}
@NotNull
- public FunctionIntrinsic getFunctionIntrinsic(@NotNull FunctionDescriptor descriptor) {
+ public Intrinsic getFunctionIntrinsic(@NotNull FunctionDescriptor descriptor) {
return functionIntrinsics.get(descriptor.getOriginal());
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayGetIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayGetIntrinsic.java
index ea0d565247d..c786cc6fc09 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayGetIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayGetIntrinsic.java
@@ -21,14 +21,14 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.List;
/**
* @author Pavel Talanov
*/
-public enum ArrayGetIntrinsic implements FunctionIntrinsic {
+public enum ArrayGetIntrinsic implements Intrinsic {
INSTANCE;
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayIndicesIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayIndicesIntrinsic.java
deleted file mode 100644
index c9e9f9d1005..00000000000
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayIndicesIntrinsic.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2000-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.k2js.translate.intrinsic.array;
-
-import com.google.dart.compiler.backend.js.ast.JsExpression;
-import com.google.dart.compiler.backend.js.ast.JsNameRef;
-import com.google.dart.compiler.util.AstUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
-
-import java.util.List;
-
-/**
- * @author Pavel Talanov
- */
-public enum ArrayIndicesIntrinsic implements FunctionIntrinsic {
-
- INSTANCE;
-
-
- @NotNull
- @Override
- public JsExpression apply(@Nullable JsExpression receiver, @NotNull List arguments,
- @NotNull TranslationContext context) {
- assert receiver != null;
- assert arguments.size() == 0;
- //TODO: provide better mechanism
- JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef("Kotlin.arrayIndices");
- return AstUtil.newInvocation(iteratorFunName, receiver);
- }
-}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayIteratorIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayIteratorIntrinsic.java
deleted file mode 100644
index cc04aa26246..00000000000
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayIteratorIntrinsic.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2000-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.k2js.translate.intrinsic.array;
-
-import com.google.dart.compiler.backend.js.ast.JsExpression;
-import com.google.dart.compiler.backend.js.ast.JsNameRef;
-import com.google.dart.compiler.util.AstUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
-
-import java.util.List;
-
-/**
- * @author Pavel Talanov
- */
-public enum ArrayIteratorIntrinsic implements FunctionIntrinsic {
-
- INSTANCE;
-
- @NotNull
- @Override
- public JsExpression apply(@Nullable JsExpression receiver, @NotNull List arguments,
- @NotNull TranslationContext context) {
- assert receiver != null;
- assert arguments.size() == 0;
- //TODO: provide better mechanism
- JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef("Kotlin.arrayIterator");
- return AstUtil.newInvocation(iteratorFunName, receiver);
- }
-}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayNullConstructorIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayNullConstructorIntrinsic.java
deleted file mode 100644
index 3d590da0f2e..00000000000
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayNullConstructorIntrinsic.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2000-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.k2js.translate.intrinsic.array;
-
-import com.google.dart.compiler.backend.js.ast.JsExpression;
-import com.google.dart.compiler.backend.js.ast.JsNameRef;
-import com.google.dart.compiler.util.AstUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
-
-import java.util.List;
-
-import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
-
-/**
- * @author Pavel Talanov
- */
-public enum ArrayNullConstructorIntrinsic implements FunctionIntrinsic {
-
- INSTANCE;
-
- //TODO: implement function passing to array constructor
- @NotNull
- @Override
- public JsExpression apply(@Nullable JsExpression receiver, @NotNull List arguments,
- @NotNull TranslationContext context) {
- assert receiver == null;
- assert arguments.size() == 1;
- //TODO: provide better mechanism
- JsNameRef nullArrayFunName = AstUtil.newQualifiedNameRef("Kotlin.nullArray");
- return newInvocation(nullArrayFunName, arguments);
- }
-}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySetIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySetIntrinsic.java
index 03f41d57c7c..773d6547dbf 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySetIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySetIntrinsic.java
@@ -22,14 +22,14 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.List;
/**
* @author Pavel Talanov
*/
-public enum ArraySetIntrinsic implements FunctionIntrinsic {
+public enum ArraySetIntrinsic implements Intrinsic {
INSTANCE;
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySizeIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/BuiltInPropertyIntrinsic.java
similarity index 53%
rename from js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySizeIntrinsic.java
rename to js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/BuiltInPropertyIntrinsic.java
index c1715d85b3f..10445c1921c 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySizeIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/BuiltInPropertyIntrinsic.java
@@ -1,19 +1,3 @@
-/*
- * Copyright 2000-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.k2js.translate.intrinsic.array;
import com.google.dart.compiler.backend.js.ast.JsExpression;
@@ -22,7 +6,7 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.List;
@@ -31,10 +15,14 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel Talanov
*/
-public enum ArraySizeIntrinsic implements FunctionIntrinsic {
+public final class BuiltInPropertyIntrinsic implements Intrinsic {
- INSTANCE;
+ @NotNull
+ private final String propertyName;
+ public BuiltInPropertyIntrinsic(@NotNull String propertyName) {
+ this.propertyName = propertyName;
+ }
@NotNull
@Override
@@ -43,8 +31,8 @@ public enum ArraySizeIntrinsic implements FunctionIntrinsic {
assert receiver != null;
assert arguments.isEmpty() : "Length expression must have zero arguments.";
//TODO: provide better way
- JsNameRef lengthProperty = AstUtil.newQualifiedNameRef("length");
+ JsNameRef lengthProperty = AstUtil.newQualifiedNameRef(propertyName);
setQualifier(lengthProperty, receiver);
return lengthProperty;
}
-}
+}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayFunctionConstructorIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/CallStandardMethodIntrinsic.java
similarity index 52%
rename from js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayFunctionConstructorIntrinsic.java
rename to js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/CallStandardMethodIntrinsic.java
index 2a025280241..d073fadf5a4 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayFunctionConstructorIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/array/CallStandardMethodIntrinsic.java
@@ -16,13 +16,14 @@
package org.jetbrains.k2js.translate.intrinsic.array;
+import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.List;
@@ -31,20 +32,42 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
/**
* @author Pavel Talanov
*/
-public enum ArrayFunctionConstructorIntrinsic implements FunctionIntrinsic {
+public final class CallStandardMethodIntrinsic implements Intrinsic {
- INSTANCE;
+ @NotNull
+ private final String methodName;
+ private final boolean receiverShouldBeNotNull;
+ private final int expectedParamsNumber;
+
+ public CallStandardMethodIntrinsic(@NotNull String methodName, boolean receiverShouldBeNotNull, int expectedParamsNumber) {
+ this.methodName = methodName;
+ this.receiverShouldBeNotNull = receiverShouldBeNotNull;
+ this.expectedParamsNumber = expectedParamsNumber;
+ }
@NotNull
@Override
public JsExpression apply(@Nullable JsExpression receiver,
@NotNull List arguments,
@NotNull TranslationContext context) {
- assert receiver == null;
- assert arguments.size() == 2;
- //TODO: provide better mechanism
- JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef("Kotlin.arrayFromFun");
- return newInvocation(iteratorFunName, arguments);
+ assert (receiver != null == receiverShouldBeNotNull);
+ assert arguments.size() == expectedParamsNumber;
+ List args = composeArguments(receiver, arguments);
+ JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef(methodName);
+ return newInvocation(iteratorFunName, composeArguments(receiver, arguments));
}
-}
+
+ @NotNull
+ private static List composeArguments(@Nullable JsExpression receiver, @NotNull List arguments) {
+ if (receiver != null) {
+ List args = Lists.newArrayList();
+ args.add(receiver);
+ args.addAll(arguments);
+ return args;
+ }
+ else {
+ return arguments;
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveBinaryOperationIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveBinaryOperationIntrinsic.java
index 5d6039319e9..2da91dff5a1 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveBinaryOperationIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveBinaryOperationIntrinsic.java
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import java.util.List;
@@ -31,7 +31,7 @@ import java.util.List;
/**
* @author Pavel Talanov
*/
-public final class PrimitiveBinaryOperationIntrinsic implements FunctionIntrinsic {
+public final class PrimitiveBinaryOperationIntrinsic implements Intrinsic {
@NotNull
public static PrimitiveBinaryOperationIntrinsic newInstance(@NotNull JetToken token) {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveEqualsIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveEqualsIntrinsic.java
index 3d95c2ca6b9..9d3140af8c7 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveEqualsIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveEqualsIntrinsic.java
@@ -21,11 +21,11 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
-import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.List;
-import static org.jetbrains.k2js.translate.utils.JsAstUtils.notEqual;
+import static org.jetbrains.k2js.translate.utils.JsAstUtils.equality;
+import static org.jetbrains.k2js.translate.utils.JsAstUtils.inequality;
/**
* @author Pavel Talanov
@@ -46,10 +46,10 @@ public final class PrimitiveEqualsIntrinsic extends EqualsIntrinsic {
assert arguments.size() == 1 : "Equals operation should have one argument";
assert receiver != null;
if (isNegated()) {
- return notEqual(receiver, arguments.get(0));
+ return inequality(receiver, arguments.get(0));
}
else {
- return JsAstUtils.equals(receiver, arguments.get(0));
+ return equality(receiver, arguments.get(0));
}
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveRangeToIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveRangeToIntrinsic.java
index 3920ade7a2a..4bb5777266d 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveRangeToIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveRangeToIntrinsic.java
@@ -24,7 +24,7 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.List;
@@ -33,7 +33,7 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
/**
* @author Pavel Talanov
*/
-public final class PrimitiveRangeToIntrinsic implements FunctionIntrinsic {
+public final class PrimitiveRangeToIntrinsic implements Intrinsic {
@NotNull
public static PrimitiveRangeToIntrinsic newInstance() {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveUnaryOperationIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveUnaryOperationIntrinsic.java
index 817461472a3..8766549e5b7 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveUnaryOperationIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveUnaryOperationIntrinsic.java
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import java.util.List;
@@ -31,7 +31,7 @@ import java.util.List;
/**
* @author Pavel Talanov
*/
-public final class PrimitiveUnaryOperationIntrinsic implements FunctionIntrinsic {
+public final class PrimitiveUnaryOperationIntrinsic implements Intrinsic {
@NotNull
public static PrimitiveUnaryOperationIntrinsic newInstance(@NotNull JetToken token) {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/string/CharAtIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/string/CharAtIntrinsic.java
index 902cbf6f0dc..2cc4d9c2134 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/string/CharAtIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/string/CharAtIntrinsic.java
@@ -22,7 +22,7 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.List;
@@ -32,7 +32,7 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel Talanov
*/
-public enum CharAtIntrinsic implements FunctionIntrinsic {
+public enum CharAtIntrinsic implements Intrinsic {
INSTANCE;
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/string/LengthIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/string/LengthIntrinsic.java
deleted file mode 100644
index 510c9f938a2..00000000000
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/string/LengthIntrinsic.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2000-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.k2js.translate.intrinsic.string;
-
-
-import com.google.dart.compiler.backend.js.ast.JsExpression;
-import com.google.dart.compiler.backend.js.ast.JsNameRef;
-import com.google.dart.compiler.util.AstUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
-
-import java.util.List;
-
-import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
-
-/**
- * @author Pavel Talanov
- */
-public enum LengthIntrinsic implements FunctionIntrinsic {
-
- INSTANCE;
-
- @NotNull
- @Override
- public JsExpression apply(@Nullable JsExpression receiver, @NotNull List arguments,
- @NotNull TranslationContext context) {
- assert receiver != null;
- assert arguments.isEmpty() : "Length expression must have zero arguments.";
- //TODO: provide better way
- JsNameRef lengthProperty = AstUtil.newQualifiedNameRef("length");
- setQualifier(lengthProperty, receiver);
- return lengthProperty;
- }
-}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/tuple/TupleAccessIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/tuple/TupleAccessIntrinsic.java
index 0dd7aa92dcb..4e8aa2d2ff0 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/tuple/TupleAccessIntrinsic.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/tuple/TupleAccessIntrinsic.java
@@ -21,14 +21,14 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.List;
/**
* @author Pavel Talanov
*/
-public final class TupleAccessIntrinsic implements FunctionIntrinsic {
+public final class TupleAccessIntrinsic implements Intrinsic {
private final int elementIndex;
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java
index 85e3a978cbd..b987b7bddbe 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java
@@ -33,8 +33,6 @@ import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
import org.jetbrains.k2js.translate.reference.CallBuilder;
import org.jetbrains.k2js.translate.reference.CallType;
-import java.util.Arrays;
-
import static org.jetbrains.k2js.translate.operation.AssignmentTranslator.isAssignmentOperator;
import static org.jetbrains.k2js.translate.operation.CompareToTranslator.isCompareToCall;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
@@ -42,8 +40,7 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isEquals;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.not;
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
-import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
-import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
+import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
/**
@@ -105,9 +102,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
assert operationDescriptor != null : "Equals operation must resolve to descriptor.";
EqualsIntrinsic intrinsic = context().intrinsics().getEqualsIntrinsic(operationDescriptor);
intrinsic.setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ));
- JsExpression left = translateLeftExpression(context(), expression);
- JsExpression right = translateRightExpression(context(), expression);
- return intrinsic.apply(left, Arrays.asList(right), context());
+ return applyIntrinsicToBinaryExpression(context(), intrinsic, expression);
}
@NotNull
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
index 3ce5449c216..8b346d023b1 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
@@ -29,12 +29,11 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
-import java.util.Arrays;
-
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isCompareTo;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
-import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
+import static org.jetbrains.k2js.translate.utils.TranslationUtils.applyIntrinsicToBinaryExpression;
+import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
/**
* @author Pavel Talanov
@@ -93,8 +92,7 @@ public final class CompareToTranslator extends AbstractTranslator {
private JsExpression intrinsicCompareTo() {
CompareToIntrinsic intrinsic = context().intrinsics().getCompareToIntrinsic(descriptor);
intrinsic.setComparisonToken((JetToken) expression.getOperationToken());
- JsExpression left = translateLeftExpression(context(), expression);
- JsExpression right = translateRightExpression(context(), expression);
- return intrinsic.apply(left, Arrays.asList(right), context());
+ return applyIntrinsicToBinaryExpression(context(), intrinsic, expression);
}
+
}
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
index cd6e096c1cf..34c052cbe8e 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
@@ -29,7 +29,7 @@ import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
-import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -121,10 +121,10 @@ public final class CallTranslator extends AbstractTranslator {
@NotNull
private JsExpression intrinsicInvocation() {
assert descriptor instanceof FunctionDescriptor;
- FunctionIntrinsic functionIntrinsic =
+ Intrinsic intrinsic =
context().intrinsics().getFunctionIntrinsic((FunctionDescriptor) descriptor);
JsExpression receiverExpression = resolveThisObject(/*do not get qualifier*/false);
- return functionIntrinsic.apply(receiverExpression, arguments, context());
+ return intrinsic.apply(receiverExpression, arguments, context());
}
private boolean isConstructor() {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java
index 19510c0e5e4..a4f0fcc74a8 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java
@@ -27,9 +27,9 @@ import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression;
import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
+import org.jetbrains.k2js.translate.utils.TranslationUtils;
import static com.google.dart.compiler.util.AstUtil.newSequence;
-import static org.jetbrains.k2js.translate.utils.JsAstUtils.notEqual;
/**
* @author Pavel Talanov
@@ -42,11 +42,10 @@ public enum CallType {
@NotNull TranslationContext context) {
assert receiver != null;
TemporaryVariable temporaryVariable = context.declareTemporary(receiver);
+ JsBinaryOperation notNullCheck = TranslationUtils.notNullCheck(context, temporaryVariable.reference());
JsNullLiteral nullLiteral = context.program().getNullLiteral();
- //TODO: find similar not null checks
- JsBinaryOperation notNullCheck = notEqual(temporaryVariable.reference(), nullLiteral);
- JsConditional callMethodIfNotNullElseNull =
- new JsConditional(notNullCheck, constructor.construct(temporaryVariable.reference()), nullLiteral);
+ JsExpression methodCall = constructor.construct(temporaryVariable.reference());
+ JsConditional callMethodIfNotNullElseNull = new JsConditional(notNullCheck, methodCall, nullLiteral);
return newSequence(temporaryVariable.assignmentExpression(), callMethodIfNotNullElseNull);
}
},
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java
index 636d0e6b9ff..0e02c4b1114 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java
@@ -205,6 +205,7 @@ public final class BindingUtils {
}
+ //TODO: refactor duplication
//TODO: check where we use there, suspicious
public static boolean isOwnedByNamespace(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor) {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java
index a1b115b1916..f2cdff1975c 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java
@@ -19,9 +19,10 @@ package org.jetbrains.k2js.translate.utils;
import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -130,18 +131,18 @@ public final class JsAstUtils {
}
@NotNull
- public static JsBinaryOperation equals(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
+ public static JsBinaryOperation equality(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
return new JsBinaryOperation(JsBinaryOperator.EQ, arg1, arg2);
}
@NotNull
- public static JsBinaryOperation notEqual(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
+ public static JsBinaryOperation inequality(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
return new JsBinaryOperation(JsBinaryOperator.NEQ, arg1, arg2);
}
@NotNull
public static JsExpression equalsTrue(@NotNull JsExpression expression, @NotNull JsProgram program) {
- return equals(expression, program.getTrueLiteral());
+ return equality(expression, program.getTrueLiteral());
}
@NotNull
@@ -154,6 +155,11 @@ public final class JsAstUtils {
return new JsBinaryOperation(JsBinaryOperator.ADD, left, right);
}
+ @NotNull
+ public static JsBinaryOperation addAssign(@NotNull JsExpression left, @NotNull JsExpression right) {
+ return new JsBinaryOperation(JsBinaryOperator.ASG_ADD, left, right);
+ }
+
@NotNull
public static JsBinaryOperation subtract(@NotNull JsExpression left, @NotNull JsExpression right) {
return new JsBinaryOperation(JsBinaryOperator.SUB, left, right);
@@ -166,7 +172,37 @@ public final class JsAstUtils {
@NotNull
public static JsBinaryOperation typeof(@NotNull JsExpression expression, @NotNull JsStringLiteral string) {
- return equals(new JsPrefixOperation(JsUnaryOperator.TYPEOF, expression), string);
+ return equality(new JsPrefixOperation(JsUnaryOperator.TYPEOF, expression), string);
+ }
+
+ @NotNull
+ public static JsFor generateForExpression(@NotNull JsVars initExpression,
+ @NotNull JsExpression condition,
+ @NotNull JsExpression incrExpression,
+ @NotNull JsStatement body) {
+ JsFor result = new JsFor();
+ result.setInitVars(initExpression);
+ result.setCondition(condition);
+ result.setIncrExpr(incrExpression);
+ result.setBody(body);
+ return result;
+ }
+
+ public static boolean ownsName(@NotNull JsScope scope, @NotNull JsName name) {
+ Iterator nameIterator = scope.getAllNames();
+ while (nameIterator.hasNext()) {
+ if (nameIterator.next() == name) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @NotNull
+ public static JsObjectLiteral newObjectLiteral(@NotNull List propertyList) {
+ JsObjectLiteral jsObjectLiteral = new JsObjectLiteral();
+ jsObjectLiteral.getPropertyInitializers().addAll(propertyList);
+ return jsObjectLiteral;
}
public interface Mutator {
diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
index 899a8365ae3..676bf5e5a53 100644
--- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
+++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
@@ -24,8 +24,10 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
+import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
@@ -44,14 +46,14 @@ public final class TranslationUtils {
public static JsBinaryOperation notNullCheck(@NotNull TranslationContext context,
@NotNull JsExpression expressionToCheck) {
JsNullLiteral nullLiteral = context.program().getNullLiteral();
- return notEqual(expressionToCheck, nullLiteral);
+ return inequality(expressionToCheck, nullLiteral);
}
@NotNull
public static JsBinaryOperation isNullCheck(@NotNull TranslationContext context,
@NotNull JsExpression expressionToCheck) {
JsNullLiteral nullLiteral = context.program().getNullLiteral();
- return JsAstUtils.equals(expressionToCheck, nullLiteral);
+ return equality(expressionToCheck, nullLiteral);
}
@NotNull
@@ -71,14 +73,6 @@ public final class TranslationUtils {
return Translation.translateAsExpression(jetExpression, context);
}
- //TODO: refactor backing field reference generation to use the generic way
- @NotNull
- public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
- @NotNull JetProperty expression) {
- PropertyDescriptor propertyDescriptor = getPropertyDescriptor(context.bindingContext(), expression);
- return backingFieldReference(context, propertyDescriptor);
- }
-
@NotNull
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
@NotNull PropertyDescriptor descriptor) {
@@ -164,14 +158,6 @@ public final class TranslationUtils {
return Translation.translateAsExpression(baseExpression, context);
}
- //TODO:
- @NotNull
- public static JsExpression translateReceiver(@NotNull TranslationContext context,
- @NotNull JetDotQualifiedExpression expression) {
- return Translation.translateAsExpression(expression.getReceiverExpression(), context);
- }
-
-
@NotNull
public static JsExpression translateLeftExpression(@NotNull TranslationContext context,
@NotNull JetBinaryExpression expression) {
@@ -227,4 +213,12 @@ public final class TranslationUtils {
context.aliaser().removeAliasForThis(descriptor);
}
+ @NotNull
+ public static JsExpression applyIntrinsicToBinaryExpression(@NotNull TranslationContext context,
+ @NotNull Intrinsic intrinsic,
+ @NotNull JetBinaryExpression binaryExpression) {
+ JsExpression left = translateLeftExpression(context, binaryExpression);
+ JsExpression right = translateRightExpression(context, binaryExpression);
+ return intrinsic.apply(left, Arrays.asList(right), context);
+ }
}
diff --git a/lib/asm-all-3.3.1.jar b/lib/asm-all-3.3.1.jar
new file mode 100644
index 00000000000..df03b326614
Binary files /dev/null and b/lib/asm-all-3.3.1.jar differ
diff --git a/lib/asm-util-3.3.1.jar b/lib/asm-util-3.3.1.jar
deleted file mode 100644
index 0230bbcfb71..00000000000
Binary files a/lib/asm-util-3.3.1.jar and /dev/null differ
diff --git a/update_dependencies.xml b/update_dependencies.xml
index febea7ad77f..8132cbe6065 100644
--- a/update_dependencies.xml
+++ b/update_dependencies.xml
@@ -13,8 +13,12 @@
+
+
+
+