diff --git a/compiler/testData/cli/js/diagnosticForUnhandledElements.args b/compiler/testData/cli/js/diagnosticForUnhandledElements.args new file mode 100644 index 00000000000..1f2d0cfb6f0 --- /dev/null +++ b/compiler/testData/cli/js/diagnosticForUnhandledElements.args @@ -0,0 +1,4 @@ +$TESTDATA_DIR$/diagnosticForUnhandledElements.kt +-no-stdlib +-output +$TEMP_DIR$/out.js diff --git a/compiler/testData/cli/js/diagnosticForUnhandledElements.kt b/compiler/testData/cli/js/diagnosticForUnhandledElements.kt new file mode 100644 index 00000000000..3857bad825d --- /dev/null +++ b/compiler/testData/cli/js/diagnosticForUnhandledElements.kt @@ -0,0 +1,18 @@ +package foo + +annotation class fancy + +[fancy] +class Foo { + [fancy] + fun baz([fancy] foo : Int) : Int { + return [fancy] 1 + } +} + +fun test() { + + class A { + fun foo(){} + } +} diff --git a/compiler/testData/cli/js/diagnosticForUnhandledElements.out b/compiler/testData/cli/js/diagnosticForUnhandledElements.out new file mode 100644 index 00000000000..5d225ef737b --- /dev/null +++ b/compiler/testData/cli/js/diagnosticForUnhandledElements.out @@ -0,0 +1,4 @@ +WARNING: compiler/testData/cli/js/diagnosticForUnhandledElements.kt: (8, 21) Parameter 'foo' is never used +ERROR: compiler/testData/cli/js/diagnosticForUnhandledElements.kt: (9, 16) Cannot translate (not supported yet): '[fancy] 1' +ERROR: compiler/testData/cli/js/diagnosticForUnhandledElements.kt: (15, 5) Cannot translate (not supported yet): 'class A {...' +COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java index b05349c9cbf..b235bd418bf 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java @@ -183,6 +183,12 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/cli/js"), Pattern.compile("^(.+)\\.args$"), false); } + @TestMetadata("diagnosticForUnhandledElements.args") + public void testDiagnosticForUnhandledElements() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/diagnosticForUnhandledElements.args"); + doJsTest(fileName); + } + @TestMetadata("jsExtraHelp.args") public void testJsExtraHelp() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/jsExtraHelp.args"); diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt index 154cdb319e4..a4632673949 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/DefaultErrorMessagesJs.kt @@ -34,6 +34,8 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by Delegates.lazy { put(ErrorsJs.JSCODE_ERROR, "JavaScript: {0}", JsCallDataTextRenderer) put(ErrorsJs.JSCODE_WARNING, "JavaScript: {0}", JsCallDataTextRenderer) put(ErrorsJs.JSCODE_ARGUMENT_SHOULD_BE_CONSTANT, "Argument must be string constant") + put(ErrorsJs.NOT_SUPPORTED, "Cannot translate (not supported yet): ''{0}''", RenderFirstLineOfElementText) + this } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java index 3d0c64f324b..69b7af2cb58 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java @@ -39,6 +39,7 @@ public interface ErrorsJs { DiagnosticFactory1 JSCODE_ERROR = DiagnosticFactory1.create(ERROR, JsCodePositioningStrategy.INSTANCE$); DiagnosticFactory1 JSCODE_WARNING = DiagnosticFactory1.create(WARNING, JsCodePositioningStrategy.INSTANCE$); DiagnosticFactory0 JSCODE_ARGUMENT_SHOULD_BE_CONSTANT = DiagnosticFactory0.create(ERROR, DEFAULT); + DiagnosticFactory1 NOT_SUPPORTED = DiagnosticFactory1.create(ERROR, DEFAULT); @SuppressWarnings("UnusedDeclaration") Object _initializer = new Object() { diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/jsRenderers.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/jsRenderers.kt index 7fe3c46bbbf..5d5d1619f55 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/jsRenderers.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/jsRenderers.kt @@ -16,10 +16,17 @@ package org.jetbrains.kotlin.js.resolve.diagnostics -import org.jetbrains.kotlin.renderer.Renderer -import org.jetbrains.kotlin.js.resolve.diagnostics.JsCallData -import org.jetbrains.kotlin.js.resolve.diagnostics.JsCallDataWithCode import com.google.gwt.dev.js.rhino.Utils.isEndOfLine +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.renderer.Renderer + +object RenderFirstLineOfElementText : Renderer { + override fun render(element: PsiElement): String { + val text = element.getText() + val index = text.indexOf('\n') + return if (index == -1) text else text.substring(0, index) + "..." + } +} abstract class JsCallDataRenderer : Renderer { protected abstract fun format(data: JsCallDataWithCode): String diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java index 2c2bf7fc076..1e3978f134d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java @@ -63,6 +63,11 @@ public class DeclarationBodyVisitor extends TranslatorVisitor { return enumEntryList; } + @Override + protected Void emptyResult(@NotNull TranslationContext context) { + return null; + } + @Override public Void visitClass(@NotNull JetClass expression, TranslationContext context) { return null; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java index e29eb10155d..d5947e0ff6b 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java @@ -60,6 +60,11 @@ import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.translate import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure; public final class ExpressionVisitor extends TranslatorVisitor { + @Override + protected JsNode emptyResult(@NotNull TranslationContext context) { + return context.getEmptyExpression(); + } + @Override @NotNull public JsNode visitConstantExpression(@NotNull JetConstantExpression expression, @NotNull TranslationContext context) { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/TranslatorVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/TranslatorVisitor.java index 66253a96716..f39ab04f301 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/TranslatorVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/TranslatorVisitor.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.js.translate.general; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs; import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.psi.JetDeclaration; import org.jetbrains.kotlin.psi.JetDeclarationContainer; @@ -26,12 +27,14 @@ import org.jetbrains.kotlin.psi.JetVisitor; /** * This class is a base class for all visitors. */ -public class TranslatorVisitor extends JetVisitor { +public abstract class TranslatorVisitor extends JetVisitor { + + protected abstract T emptyResult(@NotNull TranslationContext context); @Override - @NotNull public T visitJetElement(@NotNull JetElement expression, TranslationContext context) { - throw new UnsupportedOperationException("Unsupported expression encountered:" + expression.toString()); + context.bindingTrace().report(ErrorsJs.NOT_SUPPORTED.on(expression, expression)); + return emptyResult(context); } public final void traverseContainer(@NotNull JetDeclarationContainer jetClass, diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java index a0c5d22eafb..3666a8829ea 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/InitializerVisitor.java @@ -37,6 +37,11 @@ public final class InitializerVisitor extends TranslatorVisitor { this.result = result; } + @Override + protected Void emptyResult(@NotNull TranslationContext context) { + return null; + } + @Override public final Void visitProperty(@NotNull JetProperty property, @NotNull TranslationContext context) { JetExpression initializer = property.getInitializer();