Merge branch 'master' of github.com:JetBrains/kotlin
This commit is contained in:
@@ -6,6 +6,7 @@ confluence/target
|
||||
out
|
||||
dist
|
||||
ideaSDK
|
||||
PluginVerifier
|
||||
.idea/dictionaries/yozh.xml
|
||||
.idea/codeStyleSettings.xml
|
||||
.idea/workspace.xml
|
||||
|
||||
+4
@@ -49,6 +49,10 @@
|
||||
<inspection_tool class="ContinueOrBreakFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="CovariantCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="CovariantEquals" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="DeclareCollectionAsInterface" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoreLocalVariables" value="false" />
|
||||
<option name="ignorePrivateMethodsAndFields" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="DoubleCheckedLocking" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoreOnVolatileVariables" value="true" />
|
||||
</inspection_tool>
|
||||
|
||||
Generated
+1
-1
@@ -1,7 +1,7 @@
|
||||
<component name="libraryTable">
|
||||
<library name="asm">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-3.3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-all-3.3.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
|
||||
Generated
+3
@@ -3,6 +3,9 @@
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/js.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/dartc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/args4j-2.0.12.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/guava-10.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/json.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Js-backend tests" type="JUnit" factoryName="JUnit">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<module name="js.tests" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<option name="PACKAGE_NAME" value="org.jetbrains.k2js.test" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="package" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/js" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="moduleWithDependencies" />
|
||||
</option>
|
||||
<envs />
|
||||
<patterns />
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
<option name="TRANSPORT" value="0" />
|
||||
<option name="LOCAL" value="true" />
|
||||
</RunnerSettings>
|
||||
<RunnerSettings RunnerId="Run" />
|
||||
<ConfigurationWrapper RunnerId="Debug" />
|
||||
<ConfigurationWrapper RunnerId="Run" />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" antfile="file://$PROJECT_DIR$/js_backend_tests.xml" target="copy_lib" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
+16
-2
@@ -2,10 +2,15 @@
|
||||
<import file="build.xml" optional="false"/>
|
||||
|
||||
<property name="build.number" value="snapshot"/>
|
||||
<property name="jdk16.home" value="${java.home}"/>
|
||||
|
||||
<property name="artifact.output.path" value="${basedir}/out/artifacts"/>
|
||||
<property name="plugin.xml" value="idea/src/META-INF/plugin.xml"/>
|
||||
<property name="plugin.xml.bk" value="${plugin.xml}.bk"/>
|
||||
|
||||
<property name="plugin.verifier" value="${basedir}/PluginVerifier/plugin-verifier-1.0-SNAPSHOT.jar"/>
|
||||
<property name="plugin.zip" value="${artifact.output.path}/kotlin-plugin-${build.number}.zip" />
|
||||
|
||||
<macrodef name="echoprop">
|
||||
<attribute name="prop"/>
|
||||
<sequential>
|
||||
@@ -55,13 +60,22 @@
|
||||
</target>
|
||||
|
||||
<target name="zipArtifact">
|
||||
<zip destfile="${artifact.output.path}/kotlin-plugin-${build.number}.zip">
|
||||
<zip destfile="${plugin.zip}">
|
||||
<zipfileset prefix="Kotlin" dir="${artifact.output.path}/Kotlin"/>
|
||||
</zip>
|
||||
<delete dir="${artifact.output.path}/Kotlin" quiet="true"/>
|
||||
</target>
|
||||
|
||||
<target name="post_build" depends="cleanupPluginXml, zipArtifact"/>
|
||||
<target name="verifyPlugin">
|
||||
<java fork="true" failonerror="true" jar="${plugin.verifier}">
|
||||
<arg value="-r" />
|
||||
<arg value="${jdk16.home}" />
|
||||
<arg value="${plugin.zip}" />
|
||||
<arg value="${basedir}/ideaSDK" />
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="post_build" depends="cleanupPluginXml, zipArtifact, verifyPlugin"/>
|
||||
|
||||
<target name="none">
|
||||
<fail message="Either specify pre_build or post_build"/>
|
||||
|
||||
@@ -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<CallableDescriptor>() {
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Module> modules = loadModuleScript(moduleFile);
|
||||
public boolean compileModuleScript(String moduleFile, @Nullable String jarPath, @Nullable String outputDir, boolean jarRuntime) {
|
||||
List<Module> 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<Module> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ClassDescriptor> 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<PsiFile> filesToAnalyzeCompletely =
|
||||
stubs ? Predicates.<PsiFile>alwaysFalse() : Predicates.<PsiFile>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<ClassDescriptor> 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();
|
||||
|
||||
+17
-17
@@ -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<PsiFile, Diagnostic> maps = LinkedHashMultimap.create();
|
||||
/*package*/ class MessageCollector {
|
||||
// File path (nullable) -> error message
|
||||
private final Multimap<String, String> 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<Diagnostic> 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<String> diagnostics = groupedMessages.get(path);
|
||||
for (String diagnostic : diagnostics) {
|
||||
out.println(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<PsiElement> 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 + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = "<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();
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ImportsResolver {
|
||||
List<JetImportDirective> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<JetExpression> argumentExpressions) {
|
||||
public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverDescriptor explicitReceiver,
|
||||
@Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression,
|
||||
@NotNull List<JetExpression> argumentExpressions) {
|
||||
List<ValueArgument> arguments = Lists.newArrayList();
|
||||
for (JetExpression argumentExpression : argumentExpressions) {
|
||||
arguments.add(makeValueArgument(argumentExpression, calleeExpression));
|
||||
|
||||
@@ -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<D> task, @NotNull TracingStrategy tracing
|
||||
) {
|
||||
OverloadResolutionResultsImpl<D> 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<OverloadResolutionResults.Code> someFailed = EnumSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES, OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
|
||||
EnumSet<OverloadResolutionResults.Code> 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 <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
||||
private static <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(
|
||||
ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
||||
|
||||
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
||||
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
|
||||
parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
||||
@@ -726,7 +734,9 @@ public class CallResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCallImpl<D> candidateCall, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument, ResolutionTask<D> task) {
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCallImpl<D> candidateCall,
|
||||
ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument,
|
||||
ResolutionTask<D> 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<ResolvedCallImpl<D>> 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<D> failed = failedCandidates.iterator().next();
|
||||
failed.getTrace().commit();
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
||||
@@ -861,7 +874,7 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallImpl<D>> results) {
|
||||
private static <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallImpl<D>> results) {
|
||||
for (ResolvedCallImpl<D> result : results) {
|
||||
if (result.isDirty()) return false;
|
||||
}
|
||||
@@ -939,7 +952,8 @@ public class CallResolver {
|
||||
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.<ResolvedCallImpl<FunctionDescriptor>>emptySet());
|
||||
}
|
||||
|
||||
private List<ResolvedCallImpl<FunctionDescriptor>> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List<JetType> parameterTypes) {
|
||||
private List<ResolvedCallImpl<FunctionDescriptor>> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver,
|
||||
String name, List<JetType> parameterTypes) {
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> result = Lists.newArrayList();
|
||||
if (receiver.exists()) {
|
||||
Collection<ResolvedCallImpl<FunctionDescriptor>> extensionFunctionDescriptors = ResolvedCallImpl.convertCollection(scope.getFunctions(name));
|
||||
@@ -966,7 +980,8 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean lookupExactSignature(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, List<JetType> parameterTypes, List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
private static boolean lookupExactSignature(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, List<JetType> parameterTypes,
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
boolean found = false;
|
||||
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : candidates) {
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||
@@ -979,7 +994,8 @@ public class CallResolver {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean findExtensionFunctions(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, ReceiverDescriptor receiver, List<JetType> parameterTypes, List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
private boolean findExtensionFunctions(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, ReceiverDescriptor receiver,
|
||||
List<JetType> parameterTypes, List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
boolean found = false;
|
||||
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : candidates) {
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||
@@ -994,7 +1010,7 @@ public class CallResolver {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean checkValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull List<JetType> parameterTypes) {
|
||||
private static boolean checkValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull List<JetType> parameterTypes) {
|
||||
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
|
||||
if (valueParameters.size() != parameterTypes.size()) return false;
|
||||
for (int i = 0; i < valueParameters.size(); i++) {
|
||||
|
||||
@@ -84,8 +84,8 @@ public class DelegatingCall implements Call {
|
||||
return delegate.getTypeArgumentList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getCallElement() {
|
||||
return delegate.getCallElement();
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+3
-1
@@ -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<ConstraintType> {
|
||||
@@ -33,7 +35,7 @@ public enum ConstraintType implements Comparable<ConstraintType> {
|
||||
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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
+2
-1
@@ -347,7 +347,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(ExpressionReceiver receiver, ExpressionTypingContext context, String name) {
|
||||
public static OverloadResolutionResults<FunctionDescriptor> 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.<ValueArgument>emptyList());
|
||||
|
||||
@@ -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;
|
||||
|
||||
+93
-12
@@ -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<CallableDescriptor> 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<CallableDescriptor> callableExtensionDescriptors = new ArrayList<CallableDescriptor>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<orderEntry type="module" module-name="stdlib" />
|
||||
<orderEntry type="module" module-name="cli" />
|
||||
<orderEntry type="library" name="idea-full" level="project" />
|
||||
<orderEntry type="library" name="asm" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -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<File> javaFilesInDir(File dir) {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> getPossiblePackageDeclarationsNames(Project project, GlobalSearchScope scope) {
|
||||
final ArrayList<String> result = new ArrayList<String>();
|
||||
|
||||
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<String> getTopExtensionFunctionNames(TypeDescriptor typeDescriptor, Project project,
|
||||
GlobalSearchScope scope) {
|
||||
|
||||
return getPossiblePackageDeclarationsNames(project, scope);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> getPossiblePackageDeclarationsNames(Project project, GlobalSearchScope scope) {
|
||||
Collection<String> result = new ArrayList<String>();
|
||||
|
||||
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<String> getTopExtensionFunctionNames(Project project, GlobalSearchScope scope) {
|
||||
|
||||
// Extension function should have an parameter of type JetValueParameter with explicit receiver parameter.
|
||||
|
||||
Set<String> extensionNames = new HashSet<String>();
|
||||
|
||||
Collection<PsiAnnotation> 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<PsiMethod> getTopExtensionFunctionByName(String name, Project project, GlobalSearchScope scope) {
|
||||
|
||||
Set<PsiMethod> selectedMethods = new HashSet<PsiMethod>();
|
||||
|
||||
Collection<PsiMethod> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<String> classNames = JetShortClassNameIndex.getInstance().getAllKeys(project);
|
||||
return classNames.toArray(new String[classNames.size()]);
|
||||
Collection<String> 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<String> classNames = JetShortClassNameIndex.getInstance().getAllKeys(project);
|
||||
Collection<String> 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<String> getALlJetClassFQNames() {
|
||||
final BindingContext context = getResolutionContext(GlobalSearchScope.allScope(project));
|
||||
return context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR);
|
||||
}
|
||||
// public Collection<String> getALlJetClassFQNames() {
|
||||
// final BindingContext context = getResolutionContext(GlobalSearchScope.allScope(project));
|
||||
// return context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR);
|
||||
// }
|
||||
|
||||
@NotNull
|
||||
public Collection<String> 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<String>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable String fqName) {
|
||||
@@ -128,26 +128,24 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
*/
|
||||
@NotNull
|
||||
public Collection<String> getAllTopLevelFunctionNames() {
|
||||
final HashSet<String> functionNames = new HashSet<String>();
|
||||
Set<String> functionNames = new HashSet<String>();
|
||||
functionNames.addAll(JetShortFunctionNameIndex.getInstance().getAllKeys(project));
|
||||
functionNames.addAll(JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(project, GlobalSearchScope.allScope(project)));
|
||||
return functionNames;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<SimpleFunctionDescriptor> getTopLevelFunctionDescriptorsByName(final @NotNull String name,
|
||||
final @NotNull GlobalSearchScope scope) {
|
||||
public Collection<SimpleFunctionDescriptor> getTopLevelFunctionDescriptorsByName(@NotNull String name,
|
||||
@NotNull GlobalSearchScope scope) {
|
||||
|
||||
// TODO: Add jet function in jar-dependencies (those functions are missing in BindingContext and stubs)
|
||||
|
||||
final Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope);
|
||||
Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope);
|
||||
|
||||
final BindingContext context = getResolutionContext(scope);
|
||||
BindingContext context = getResolutionContext(scope);
|
||||
|
||||
final HashSet<SimpleFunctionDescriptor> result = new HashSet<SimpleFunctionDescriptor>();
|
||||
HashSet<SimpleFunctionDescriptor> result = new HashSet<SimpleFunctionDescriptor>();
|
||||
|
||||
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<JetNamedFunction> getTopLevelFunctionsByName(final @NotNull String name, @NotNull GlobalSearchScope scope) {
|
||||
public Collection<JetNamedFunction> 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<String> getAllJetExtensionFunctionsNames(@NotNull GlobalSearchScope scope) {
|
||||
final Set<String> extensionFunctionNames = new HashSet<String>();
|
||||
Set<String> extensionFunctionNames = new HashSet<String>();
|
||||
|
||||
extensionFunctionNames.addAll(JetExtensionFunctionNameIndex.getInstance().getAllKeys(project));
|
||||
extensionFunctionNames.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionNames(null, project, scope));
|
||||
extensionFunctionNames.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionNames(project, scope));
|
||||
|
||||
return extensionFunctionNames;
|
||||
}
|
||||
|
||||
public Collection<SimpleFunctionDescriptor> 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<PsiElement> getJetExtensionFunctionsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
|
||||
HashSet<PsiElement> functions = new HashSet<PsiElement>();
|
||||
functions.addAll(JetExtensionFunctionNameIndex.getInstance().get(name, project, scope));
|
||||
functions.addAll(JetFromJavaDescriptorHelper.getTopExtensionFunctionByName(name, project, scope));
|
||||
|
||||
final Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope);
|
||||
return functions;
|
||||
}
|
||||
|
||||
final BindingContext context = getResolutionContext(scope);
|
||||
public Collection<JetNamedFunction> getJetFunctionsByName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope) {
|
||||
return JetShortFunctionNameIndex.getInstance().get(name, project, scope);
|
||||
}
|
||||
|
||||
final HashSet<SimpleFunctionDescriptor> result = new HashSet<SimpleFunctionDescriptor>();
|
||||
|
||||
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<String> 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<String> 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
|
||||
|
||||
@@ -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<String, CompilerMessageCategory> categories = new HashMap<String, CompilerMessageCategory>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,
|
||||
final @NotNull CompletionResultSet result) {
|
||||
@NotNull CompletionResultSet result) {
|
||||
|
||||
final HashSet<LookupPositionObject> positions = new HashSet<LookupPositionObject>();
|
||||
Set<LookupPositionObject> positions = new HashSet<LookupPositionObject>();
|
||||
|
||||
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<String> extensionFunctionsNames = namesCache.getAllJetExtensionFunctionsNames(
|
||||
GlobalSearchScope.allScope(position.getProject()));
|
||||
|
||||
Set<String> functionFQNs = new HashSet<String>();
|
||||
|
||||
// Collect all possible extension function qualified names
|
||||
for (String name : extensionFunctionsNames) {
|
||||
if (result.getPrefixMatcher().prefixMatches(name)) {
|
||||
Collection<PsiElement> 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<LookupPositionObject> positions) {
|
||||
@NotNull Set<LookupPositionObject> 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<LookupPositionObject> positions) {
|
||||
@NotNull Set<LookupPositionObject> 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<String> functionNames = namesCache.getAllTopLevelFunctionNames();
|
||||
JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache();
|
||||
GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
Collection<String> 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<LookupPositionObject> positions) {
|
||||
@NotNull final Set<LookupPositionObject> positions) {
|
||||
|
||||
JetClassCompletionContributor.addClasses(parameters, result, new Consumer<LookupElement>() {
|
||||
@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<LookupPositionObject> positions) {
|
||||
@NotNull Set<LookupPositionObject> 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.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -115,11 +115,6 @@ public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
|
||||
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<LookupElement> {
|
||||
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
|
||||
|
||||
+3
@@ -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<TemplateImpl> templates = listApplicableTemplates(file, offset);
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.JetBundle;
|
||||
public class JetSuggestVariableNameMacro extends Macro {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "suggestVariableName";
|
||||
return "kotlinSuggestVariableName";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package first
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
fun firstFun() {
|
||||
val a = ArrayList<Int>()
|
||||
a.toLinke<caret>
|
||||
}
|
||||
|
||||
// RUNTIME: 1
|
||||
// TIME: 2
|
||||
// EXIST: toLinkedList
|
||||
// NUMBER: 1
|
||||
@@ -0,0 +1,15 @@
|
||||
package first
|
||||
|
||||
trait TestedTrait() {
|
||||
}
|
||||
|
||||
fun firstFun() {
|
||||
val a = second.SomeTest<TestedTrait>()
|
||||
a.testing<caret>
|
||||
}
|
||||
|
||||
// EXIST: testingMethod
|
||||
// EXIST: testingExpectedFunction
|
||||
// ABSENT: testingUnexpectedFunction
|
||||
|
||||
// NUMBER: 2
|
||||
@@ -0,0 +1,16 @@
|
||||
package second
|
||||
|
||||
open class SomeOther() {}
|
||||
|
||||
class SomeTest<T> {
|
||||
fun testingMethod() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun <U : SomeOther> SomeTest<U>.testingUnexpectedFunction() {
|
||||
}
|
||||
|
||||
fun <W : Any> SomeTest<W>.testingExpectedFunction(i : Int) : String {
|
||||
return ""
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package first
|
||||
|
||||
fun firstFun() {
|
||||
val a = SomeUnknownClass()
|
||||
a.hello<caret>
|
||||
}
|
||||
|
||||
// ABSENT: helloFun
|
||||
// ABSENT: helloFunPreventAutoInsert
|
||||
// ABSENT: helloWithParams
|
||||
// NUMBER: 0
|
||||
@@ -0,0 +1,11 @@
|
||||
package second
|
||||
|
||||
fun String.helloFun() {
|
||||
}
|
||||
|
||||
fun String.helloWithParams(i : Int) : String {
|
||||
return ""
|
||||
}
|
||||
|
||||
fun String.helloFunPreventAutoInsert() {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package first
|
||||
|
||||
fun firstFun() {
|
||||
val a : String? = ""
|
||||
a.hello<caret>
|
||||
}
|
||||
|
||||
// EXIST: helloFun
|
||||
// EXIST: helloFunPreventAutoInsert
|
||||
// EXIST: helloWithParams
|
||||
// ABSENT: helloFake
|
||||
// NUMBER: 3
|
||||
@@ -0,0 +1,14 @@
|
||||
package second
|
||||
|
||||
fun String.helloFun() {
|
||||
}
|
||||
|
||||
fun String.helloWithParams(i : Int) : String {
|
||||
return ""
|
||||
}
|
||||
|
||||
fun String.helloFunPreventAutoInsert() {
|
||||
}
|
||||
|
||||
fun Int.helloFake() {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package first
|
||||
|
||||
import second.SomeTestClass
|
||||
|
||||
fun firstFun() {
|
||||
SomeTestClass().some<caret>
|
||||
}
|
||||
|
||||
// EXIST: someProperty
|
||||
// EXIST: someOtherProperty
|
||||
// EXIST: someSelfProperty
|
||||
// NUMBER: 3
|
||||
@@ -0,0 +1,8 @@
|
||||
package second
|
||||
|
||||
class SomeTestClass() {
|
||||
}
|
||||
|
||||
val SomeTestClass.someProperty = 12
|
||||
var SomeTestClass.someOtherProperty = ""
|
||||
val SomeTestClass.someSelfProperty = SomeTestClass()
|
||||
@@ -0,0 +1,12 @@
|
||||
package first
|
||||
|
||||
fun firstFun() {
|
||||
val a = ""
|
||||
a.hello<caret>
|
||||
}
|
||||
|
||||
// EXIST: helloFun
|
||||
// EXIST: helloFunPreventAutoInsert
|
||||
// EXIST: helloWithParams
|
||||
// ABSENT: helloFake
|
||||
// NUMBER: 3
|
||||
@@ -0,0 +1,14 @@
|
||||
package second
|
||||
|
||||
fun String.helloFun() {
|
||||
}
|
||||
|
||||
fun String.helloWithParams(i : Int) : String {
|
||||
return ""
|
||||
}
|
||||
|
||||
fun String.helloFunPreventAutoInsert() {
|
||||
}
|
||||
|
||||
fun Int.helloFake() {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package first
|
||||
|
||||
fun firstFun() {
|
||||
val a = ""
|
||||
a.hello<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package second
|
||||
|
||||
fun String.helloFun() {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package first
|
||||
|
||||
import second.helloFun
|
||||
|
||||
fun firstFun() {
|
||||
val a = ""
|
||||
a.helloFun()
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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() +
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
+18
-4
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.6" jdkType="JavaSDK" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="js.translator" />
|
||||
<orderEntry type="module" module-name="compiler-tests" />
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public final class KotlinLibTest extends TranslationTest {
|
||||
final Map<String, Class<? extends Scriptable>> propertyToType
|
||||
= new HashMap<String, Class<? extends Scriptable>>();
|
||||
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<String, Class<? extends Scriptable>> propertyToType
|
||||
= new HashMap<String, Class<? extends Scriptable>>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,6 @@ public final class NameClashesTest extends TranslationTest {
|
||||
}
|
||||
|
||||
public void testMethodOverload() throws Exception {
|
||||
testFooBoxIsTrue("methodOverload.kt");
|
||||
checkFooBoxIsTrue("methodOverload.kt");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String> fullFilePaths = new ArrayList<String>();
|
||||
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<String> fileNames, RhinoResultChecker checker) throws Exception {
|
||||
protected static void runRhinoTest(@NotNull List<String> 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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", "");
|
||||
// }
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6
-8
@@ -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<JetFile> 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 {
|
||||
@@ -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<JetFile> 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<String> parseString(@NotNull String argumentString) {
|
||||
private static List<String> parseString(@NotNull String argumentString) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
StringTokenizer stringTokenizer = new StringTokenizer(argumentString);
|
||||
while (stringTokenizer.hasMoreTokens()) {
|
||||
|
||||
@@ -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<JsName> nameIterator = scope.getAllNames();
|
||||
while (nameIterator.hasNext()) {
|
||||
if (nameIterator.next() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public JsName declareTemporary() {
|
||||
|
||||
@@ -323,6 +323,7 @@ public final class StaticContext {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private NamingScope getEnclosingScope(@NotNull DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
||||
return getScopeForDescriptor(containingDeclaration.getOriginal());
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -100,7 +100,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> declarationStatements(@NotNull List<NamespaceTranslator> namespaceTranslators) {
|
||||
private static List<JsStatement> declarationStatements(@NotNull List<NamespaceTranslator> namespaceTranslators) {
|
||||
List<JsStatement> result = Lists.newArrayList();
|
||||
for (NamespaceTranslator translator : namespaceTranslators) {
|
||||
result.add(translator.getDeclarationStatement());
|
||||
@@ -109,7 +109,7 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> initializeStatements(@NotNull List<NamespaceTranslator> namespaceTranslators) {
|
||||
private static List<JsStatement> initializeStatements(@NotNull List<NamespaceTranslator> namespaceTranslators) {
|
||||
List<JsStatement> result = Lists.newArrayList();
|
||||
for (NamespaceTranslator translator : namespaceTranslators) {
|
||||
result.add(translator.getInitializeStatement());
|
||||
|
||||
+2
-6
@@ -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<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +224,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
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) {
|
||||
|
||||
+9
-9
@@ -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() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user