From 36bc7580aaa5a1240cbbe95850f73724d837b148 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Sun, 16 Feb 2014 02:24:17 +0100 Subject: [PATCH] fix main function detection to rely on actually resolved types --- .../compiler/KotlinToJVMBytecodeCompiler.java | 13 +- .../lang/cfg/JetFlowInformationProvider.java | 5 +- .../jetbrains/jet/plugin/JetMainDetector.java | 70 ----------- .../jet/plugin/MainFunctionDetector.java | 116 ++++++++++++++++++ .../src/org/jetbrains/kotlin/AntTaskTest.java | 10 ++ .../jetbrains/kotlin/CompilerSmokeTest.java | 16 +++ .../hello.compile.expected | 1 + .../compileAndRunHelloAppFQMain/hello.kt | 5 + .../hello.run.expected | 4 + .../hello.compile.expected | 1 + .../compileAndRunHelloAppVarargMain/hello.kt | 5 + .../hello.run.expected | 4 + .../k2jsWithMainFQArgs/build.log.expected | 10 ++ .../testData/k2jsWithMainFQArgs/build.xml | 7 ++ .../testData/k2jsWithMainFQArgs/root1/foo.kt | 9 ++ .../k2jsWithMainVarargs/build.log.expected | 10 ++ .../testData/k2jsWithMainVarargs/build.xml | 7 ++ .../testData/k2jsWithMainVarargs/root1/foo.kt | 9 ++ .../jet/plugin/run/JetRunConfiguration.java | 8 +- .../run/JetRunConfigurationProducer.java | 11 +- .../k2js/translate/general/Translation.java | 5 +- 21 files changed, 242 insertions(+), 84 deletions(-) delete mode 100644 compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java create mode 100644 compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.compile.expected create mode 100644 compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.kt create mode 100644 compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.run.expected create mode 100644 compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.compile.expected create mode 100644 compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.kt create mode 100644 compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.run.expected create mode 100644 compiler/integration-tests/testData/k2jsWithMainFQArgs/build.log.expected create mode 100644 compiler/integration-tests/testData/k2jsWithMainFQArgs/build.xml create mode 100644 compiler/integration-tests/testData/k2jsWithMainFQArgs/root1/foo.kt create mode 100644 compiler/integration-tests/testData/k2jsWithMainVarargs/build.log.expected create mode 100644 compiler/integration-tests/testData/k2jsWithMainVarargs/build.xml create mode 100644 compiler/integration-tests/testData/k2jsWithMainVarargs/root1/foo.kt diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index 2ef0fd24780..00fcca192fe 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -49,7 +49,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.types.lang.InlineUtil; -import org.jetbrains.jet.plugin.JetMainDetector; +import org.jetbrains.jet.plugin.MainFunctionDetector; import org.jetbrains.jet.utils.KotlinPaths; import java.io.File; @@ -162,10 +162,11 @@ public class KotlinToJVMBytecodeCompiler { } @Nullable - private static FqName findMainClass(@NotNull List files) { + private static FqName findMainClass(@NotNull GenerationState generationState, @NotNull List files) { + MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(generationState.getBindingContext()); FqName mainClass = null; for (JetFile file : files) { - if (JetMainDetector.hasMain(file.getDeclarations())) { + if (mainFunctionDetector.hasMain(file.getDeclarations())) { if (mainClass != null) { // more than one main return null; @@ -184,13 +185,13 @@ public class KotlinToJVMBytecodeCompiler { boolean includeRuntime ) { - FqName mainClass = findMainClass(environment.getSourceFiles()); - GenerationState generationState = analyzeAndGenerate(environment); if (generationState == null) { return false; } + FqName mainClass = findMainClass(generationState, environment.getSourceFiles()); + try { OutputDirector outputDirector = outputDir != null ? new SingleDirectoryDirector(outputDir) : null; writeOutput(environment.getConfiguration(), generationState.getFactory(), outputDirector, jar, includeRuntime, mainClass); @@ -309,4 +310,4 @@ public class KotlinToJVMBytecodeCompiler { } return generationState; } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index 7b977826a5b..d6449a019b8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -47,7 +47,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiver; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.plugin.JetMainDetector; +import org.jetbrains.jet.plugin.MainFunctionDetector; import java.util.*; @@ -557,7 +557,8 @@ public class JetFlowInformationProvider { else if (element instanceof JetParameter) { PsiElement psiElement = element.getParent().getParent(); if (psiElement instanceof JetFunction) { - boolean isMain = (psiElement instanceof JetNamedFunction) && JetMainDetector.isMain((JetNamedFunction) psiElement); + MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(trace.getBindingContext()); + boolean isMain = (psiElement instanceof JetNamedFunction) && mainFunctionDetector.isMain((JetNamedFunction) psiElement); if (psiElement instanceof JetFunctionLiteral) return; DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement); assert descriptor instanceof FunctionDescriptor : psiElement.getText(); diff --git a/compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java b/compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java deleted file mode 100644 index 44521558edd..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/plugin/JetMainDetector.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2010-2013 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; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.*; - -import java.util.Collection; -import java.util.List; - -public class JetMainDetector { - private JetMainDetector() { - } - - public static boolean hasMain(@NotNull List declarations) { - return findMainFunction(declarations) != null; - } - - public static boolean isMain(@NotNull JetNamedFunction function) { - if ("main".equals(function.getName())) { - List parameters = function.getValueParameters(); - if (parameters.size() == 1) { - JetTypeReference reference = parameters.get(0).getTypeReference(); - if (reference != null && reference.getText().equals("Array")) { // TODO correct check - return true; - } - } - } - return false; - } - - @Nullable - public static JetNamedFunction getMainFunction(@NotNull Collection files) { - for (JetFile file : files) { - JetNamedFunction mainFunction = findMainFunction(file.getDeclarations()); - if (mainFunction != null) { - return mainFunction; - } - } - return null; - } - - @Nullable - private static JetNamedFunction findMainFunction(@NotNull List declarations) { - for (JetDeclaration declaration : declarations) { - if (declaration instanceof JetNamedFunction) { - JetNamedFunction candidateFunction = (JetNamedFunction) declaration; - if (isMain(candidateFunction)) { - return candidateFunction; - } - } - } - return null; - } -} diff --git a/compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java b/compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java new file mode 100644 index 00000000000..46b9dcfff8f --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/plugin/MainFunctionDetector.java @@ -0,0 +1,116 @@ +/* + * Copyright 2010-2013 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; + +import com.intellij.util.NotNullFunction; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.psi.JetDeclaration; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; + +import java.util.Collection; +import java.util.List; + +public class MainFunctionDetector { + private final NotNullFunction getFunctionDescriptor; + + /** Assumes that the function declaration is already resolved and the descriptor can be found in the {@code bindingContext}. */ + public MainFunctionDetector(@NotNull final BindingContext bindingContext) { + this.getFunctionDescriptor = new NotNullFunction() { + @NotNull + @Override + public FunctionDescriptor fun(JetNamedFunction function) { + SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, function); + if (functionDescriptor == null) { + throw new IllegalStateException("No descriptor resolved for " + function + " " + function.getText()); + } + return functionDescriptor; + } + }; + } + + /** Uses the {@code resolveSession} to resolve the function declaration. Suitable when the function declaration is not resolved yet. */ + public MainFunctionDetector(@NotNull final ResolveSession resolveSession) { + this.getFunctionDescriptor = new NotNullFunction() { + @NotNull + @Override + public FunctionDescriptor fun(JetNamedFunction function) { + return (FunctionDescriptor) resolveSession.resolveToDescriptor(function); + } + }; + } + + public boolean hasMain(@NotNull List declarations) { + return findMainFunction(declarations) != null; + } + + public boolean isMain(@NotNull JetNamedFunction function) { + if ("main".equals(function.getName())) { + FunctionDescriptor functionDescriptor = getFunctionDescriptor.fun(function); + List parameters = functionDescriptor.getValueParameters(); + if (parameters.size() == 1) { + ValueParameterDescriptor parameter = parameters.get(0); + JetType parameterType = parameter.getType(); + KotlinBuiltIns kotlinBuiltIns = KotlinBuiltIns.getInstance(); + if (kotlinBuiltIns.isArray(parameterType)) { + List typeArguments = parameterType.getArguments(); + if (typeArguments.size() == 1) { + JetType typeArgument = typeArguments.get(0).getType(); + if (JetTypeChecker.INSTANCE.equalTypes(typeArgument, kotlinBuiltIns.getStringType())) { + return true; + } + } + } + } + } + return false; + } + + @Nullable + public JetNamedFunction getMainFunction(@NotNull Collection files) { + for (JetFile file : files) { + JetNamedFunction mainFunction = findMainFunction(file.getDeclarations()); + if (mainFunction != null) { + return mainFunction; + } + } + return null; + } + + @Nullable + private JetNamedFunction findMainFunction(@NotNull List declarations) { + for (JetDeclaration declaration : declarations) { + if (declaration instanceof JetNamedFunction) { + JetNamedFunction candidateFunction = (JetNamedFunction) declaration; + if (isMain(candidateFunction)) { + return candidateFunction; + } + } + } + return null; + } +} diff --git a/compiler/integration-tests/src/org/jetbrains/kotlin/AntTaskTest.java b/compiler/integration-tests/src/org/jetbrains/kotlin/AntTaskTest.java index a3a28cc9bb8..94e2b0e962d 100644 --- a/compiler/integration-tests/src/org/jetbrains/kotlin/AntTaskTest.java +++ b/compiler/integration-tests/src/org/jetbrains/kotlin/AntTaskTest.java @@ -125,6 +125,16 @@ public class AntTaskTest extends KotlinIntegrationTestBase { doJsAntTest(); } + @Test + public void k2jsWithMainFQArgs() throws Exception { + doJsAntTest(); + } + + @Test + public void k2jsWithMainVarargs() throws Exception { + doJsAntTest(); + } + @Test public void k2jsManySources() throws Exception { doJsAntTest(); diff --git a/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java b/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java index cc92d660b53..4650572f645 100644 --- a/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java +++ b/compiler/integration-tests/src/org/jetbrains/kotlin/CompilerSmokeTest.java @@ -32,6 +32,22 @@ public class CompilerSmokeTest extends KotlinIntegrationTestBase { runJava("hello.run", "-cp", jar, "Hello.HelloPackage"); } + @Test + public void compileAndRunHelloAppFQMain() throws Exception { + String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar"; + + assertEquals("compilation failed", 0, runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar)); + runJava("hello.run", "-cp", jar, "Hello.HelloPackage"); + } + + @Test + public void compileAndRunHelloAppVarargMain() throws Exception { + String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar"; + + assertEquals("compilation failed", 0, runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar)); + runJava("hello.run", "-cp", jar, "Hello.HelloPackage"); + } + @Test public void compileAndRunModule() throws Exception { String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "smoke.jar"; diff --git a/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.compile.expected b/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.compile.expected new file mode 100644 index 00000000000..a14ac74940f --- /dev/null +++ b/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.compile.expected @@ -0,0 +1 @@ +Return code: 0 diff --git a/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.kt b/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.kt new file mode 100644 index 00000000000..dd83e3c3de8 --- /dev/null +++ b/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.kt @@ -0,0 +1,5 @@ +package Hello + +fun main(args: kotlin.Array) { + System.out.println("Hello from fully qualified main!") +} diff --git a/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.run.expected b/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.run.expected new file mode 100644 index 00000000000..f052dde0a17 --- /dev/null +++ b/compiler/integration-tests/testData/compileAndRunHelloAppFQMain/hello.run.expected @@ -0,0 +1,4 @@ +OUT: +Hello from fully qualified main! + +Return code: 0 diff --git a/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.compile.expected b/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.compile.expected new file mode 100644 index 00000000000..a14ac74940f --- /dev/null +++ b/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.compile.expected @@ -0,0 +1 @@ +Return code: 0 diff --git a/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.kt b/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.kt new file mode 100644 index 00000000000..414877a7dba --- /dev/null +++ b/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.kt @@ -0,0 +1,5 @@ +package Hello + +fun main(vararg args: kotlin.String) { + System.out.println("Hello from vararg main!") +} diff --git a/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.run.expected b/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.run.expected new file mode 100644 index 00000000000..bb985624029 --- /dev/null +++ b/compiler/integration-tests/testData/compileAndRunHelloAppVarargMain/hello.run.expected @@ -0,0 +1,4 @@ +OUT: +Hello from vararg main! + +Return code: 0 diff --git a/compiler/integration-tests/testData/k2jsWithMainFQArgs/build.log.expected b/compiler/integration-tests/testData/k2jsWithMainFQArgs/build.log.expected new file mode 100644 index 00000000000..438f56679ca --- /dev/null +++ b/compiler/integration-tests/testData/k2jsWithMainFQArgs/build.log.expected @@ -0,0 +1,10 @@ +OUT: +Buildfile: [TestData]/build.xml + +build: +[kotlin2js] Compiling [[TestData]/root1] => [[Temp]/out.js] + +BUILD SUCCESSFUL +Total time: [time] + +Return code: 0 diff --git a/compiler/integration-tests/testData/k2jsWithMainFQArgs/build.xml b/compiler/integration-tests/testData/k2jsWithMainFQArgs/build.xml new file mode 100644 index 00000000000..a80ea4410f9 --- /dev/null +++ b/compiler/integration-tests/testData/k2jsWithMainFQArgs/build.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/compiler/integration-tests/testData/k2jsWithMainFQArgs/root1/foo.kt b/compiler/integration-tests/testData/k2jsWithMainFQArgs/root1/foo.kt new file mode 100644 index 00000000000..84c3a8a43ee --- /dev/null +++ b/compiler/integration-tests/testData/k2jsWithMainFQArgs/root1/foo.kt @@ -0,0 +1,9 @@ +package foo + +var ok = "FAIL" + +fun main(args: kotlin.Array) { + ok = "OK" +} + +fun box(): String = ok diff --git a/compiler/integration-tests/testData/k2jsWithMainVarargs/build.log.expected b/compiler/integration-tests/testData/k2jsWithMainVarargs/build.log.expected new file mode 100644 index 00000000000..438f56679ca --- /dev/null +++ b/compiler/integration-tests/testData/k2jsWithMainVarargs/build.log.expected @@ -0,0 +1,10 @@ +OUT: +Buildfile: [TestData]/build.xml + +build: +[kotlin2js] Compiling [[TestData]/root1] => [[Temp]/out.js] + +BUILD SUCCESSFUL +Total time: [time] + +Return code: 0 diff --git a/compiler/integration-tests/testData/k2jsWithMainVarargs/build.xml b/compiler/integration-tests/testData/k2jsWithMainVarargs/build.xml new file mode 100644 index 00000000000..a80ea4410f9 --- /dev/null +++ b/compiler/integration-tests/testData/k2jsWithMainVarargs/build.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/compiler/integration-tests/testData/k2jsWithMainVarargs/root1/foo.kt b/compiler/integration-tests/testData/k2jsWithMainVarargs/root1/foo.kt new file mode 100644 index 00000000000..e9b5d129049 --- /dev/null +++ b/compiler/integration-tests/testData/k2jsWithMainVarargs/root1/foo.kt @@ -0,0 +1,9 @@ +package foo + +var ok = "FAIL" + +fun main(vararg args: kotlin.String) { + ok = "OK" +} + +fun box(): String = ok diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java index 7d81426f8c2..2353be2ef4d 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfiguration.java @@ -39,9 +39,11 @@ import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.plugin.JetMainDetector; +import org.jetbrains.jet.plugin.MainFunctionDetector; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.stubindex.JetTopLevelFunctionsFqnNameIndex; import java.util.*; @@ -269,7 +271,9 @@ public class JetRunConfiguration extends ModuleBasedConfiguration mainFunctions = JetTopLevelFunctionsFqnNameIndex.getInstance().get( mainFunFqName, module.getProject(), module.getModuleRuntimeScope(true)); for (JetNamedFunction function : mainFunctions) { - if (JetMainDetector.isMain(function)) { + BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(function); + MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(bindingContext); + if (mainFunctionDetector.isMain(function)) { return function; } } diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java index 00581469470..e25871e75e0 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java @@ -27,14 +27,18 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.analyzer.AnalyzerFacade; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.name.FqName; -import org.jetbrains.jet.plugin.JetMainDetector; +import org.jetbrains.jet.plugin.MainFunctionDetector; import org.jetbrains.jet.plugin.JetPluginUtil; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeProvider; import org.jetbrains.jet.plugin.project.ProjectStructureUtil; +import java.util.Collections; import java.util.List; public class JetRunConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable { @@ -79,7 +83,10 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im PsiFile psiFile = location.getPsiElement().getContainingFile(); if (psiFile instanceof JetFile) { JetFile jetFile = (JetFile) psiFile; - if (JetMainDetector.hasMain(jetFile.getDeclarations())) { + AnalyzerFacade analyzerFacade = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(jetFile); + ResolveSession resolveSession = analyzerFacade.getLazyResolveSession(jetFile.getProject(), Collections.singleton(jetFile)); + MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(resolveSession); + if (mainFunctionDetector.hasMain(jetFile.getDeclarations())) { return jetFile; } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java index 3a52ee288be..6f73befeb99 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java @@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.plugin.MainFunctionDetector; import org.jetbrains.k2js.config.Config; import org.jetbrains.k2js.facade.MainCallParameters; import org.jetbrains.k2js.facade.exceptions.MainFunctionNotFoundException; @@ -49,7 +50,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import static org.jetbrains.jet.plugin.JetMainDetector.getMainFunction; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor; import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; import static org.jetbrains.k2js.translate.utils.dangerous.DangerousData.collect; @@ -170,7 +170,8 @@ public final class Translation { @Nullable private static JsStatement generateCallToMain(@NotNull TranslationContext context, @NotNull Collection files, @NotNull List arguments) throws MainFunctionNotFoundException { - JetNamedFunction mainFunction = getMainFunction(files); + MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(context.bindingContext()); + JetNamedFunction mainFunction = mainFunctionDetector.getMainFunction(files); if (mainFunction == null) { return null; }