From 38143847622d0f2929ce6b87889ccd43038fc9c4 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Fri, 6 Jul 2012 18:38:16 +0400 Subject: [PATCH] Isolate error reporting Introduce ErrorReportingUtils --- .../ClassDeclarationTranslator.java | 4 +- .../expression/ExpressionVisitor.java | 88 +++++++++---------- .../expression/FunctionTranslator.java | 7 +- .../translate/reference/CallTranslator.java | 22 +---- .../QualifiedExpressionTranslator.java | 28 +++--- .../k2js/translate/utils/BindingUtils.java | 69 ++++++++------- .../translate/utils/ErrorReportingUtils.java | 66 ++++++++++++++ 7 files changed, 168 insertions(+), 116 deletions(-) create mode 100644 js/js.translator/src/org/jetbrains/k2js/translate/utils/ErrorReportingUtils.java diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java index 05b560f4fb4..17b37a8ee28 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java @@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.Modality; -import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TranslationContext; @@ -39,6 +38,7 @@ import java.util.List; import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar; import static org.jetbrains.k2js.translate.general.Translation.translateClassDeclaration; import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor; +import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message; import static org.jetbrains.k2js.translate.utils.JsAstUtils.newBlock; /** @@ -152,7 +152,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { for (ListItem item : openList) { JsExpression translatedDeclaration = item.translatedDeclaration; if (translatedDeclaration == null) { - throw new IllegalStateException("Could not translate class declaration at " + DiagnosticUtils.atLocation(item.declaration)); + throw new IllegalStateException(message(item.declaration, "Could not translate class declaration)")); } generate(item, propertyInitializers, translatedDeclaration, vars); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java index 9a557914c5e..28aff721a32 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java @@ -20,7 +20,6 @@ import com.google.dart.compiler.backend.js.ast.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; @@ -42,6 +41,7 @@ import java.util.List; import static org.jetbrains.k2js.translate.general.Translation.translateAsExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.*; +import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message; import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationName; import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateInitializerForProperty; @@ -55,36 +55,36 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitConstantExpression(@NotNull JetConstantExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { CompileTimeConstant compileTimeValue = - context.bindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression); + context.bindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression); assert compileTimeValue != null; if (compileTimeValue instanceof NullValue) { return context.program().getNullLiteral(); } Object value = compileTimeValue.getValue(); if (value instanceof Integer) { - return context.program().getNumberLiteral((Integer)value); + return context.program().getNumberLiteral((Integer) value); } if (value instanceof Boolean) { - return context.program().getBooleanLiteral((Boolean)value); + return context.program().getBooleanLiteral((Boolean) value); } //TODO: test if (value instanceof Float) { - return context.program().getNumberLiteral((Float)value); + return context.program().getNumberLiteral((Float) value); } if (value instanceof Double) { - return context.program().getNumberLiteral((Double)value); + return context.program().getNumberLiteral((Double) value); } if (value instanceof String) { - return context.program().getStringLiteral((String)value); + return context.program().getStringLiteral((String) value); } if (value instanceof Character) { return context.program().getStringLiteral(value.toString()); } //TODO: all values - throw new AssertionError("Unsupported constant expression " + expression.toString() + " at " + DiagnosticUtils.atLocation(expression)); + throw new AssertionError(message(expression, "Unsupported constant expression")); } @Override @@ -105,7 +105,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitReturnExpression(@NotNull JetReturnExpression jetReturnExpression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JetExpression returnedExpression = jetReturnExpression.getReturnedExpression(); if (returnedExpression != null) { JsExpression jsExpression = translateAsExpression(returnedExpression, context); @@ -117,7 +117,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JetExpression expressionInside = expression.getExpression(); if (expressionInside != null) { return expressionInside.accept(this, context); @@ -128,7 +128,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitBinaryExpression(@NotNull JetBinaryExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return BinaryOperationTranslator.translate(expression, context); } @@ -145,7 +145,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitCallExpression(@NotNull JetCallExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return CallExpressionTranslator.translate(expression, null, CallType.NORMAL, context); } @@ -158,7 +158,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { } TemporaryVariable result = context.declareTemporary(context.program().getNullLiteral()); AssignToExpressionMutator saveResultToTemporaryMutator = - new AssignToExpressionMutator(result.reference()); + new AssignToExpressionMutator(result.reference()); JsNode mutatedIfStatement = mutateLastExpression(ifStatement, saveResultToTemporaryMutator); JsStatement resultingStatement = convertToStatement(mutatedIfStatement); context.addStatementToCurrentBlock(resultingStatement); @@ -168,14 +168,14 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return ReferenceTranslator.translateSimpleName(expression, context); } @NotNull private JsIf translateAsIfStatement(@NotNull JetIfExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JsIf result = new JsIf(); result.setIfExpr(translateConditionExpression(expression.getCondition(), context)); result.setThenStmt(translateNullableExpressionAsNotNullStatement(expression.getThen(), context)); @@ -185,7 +185,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Nullable private JsStatement translateElseAsStatement(@NotNull JetIfExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JetExpression jetElse = expression.getElse(); if (jetElse == null) { return null; @@ -195,7 +195,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull private JsStatement translateNullableExpressionAsNotNullStatement(@Nullable JetExpression nullableExpression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { if (nullableExpression == null) { return context.program().getEmptyStmt(); } @@ -204,7 +204,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull private JsExpression translateConditionExpression(@Nullable JetExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JsExpression jsCondition = translateNullableExpression(expression, context); assert (jsCondition != null) : "Condition should not be empty"; return convertToExpression(jsCondition); @@ -212,7 +212,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Nullable private JsExpression translateNullableExpression(@Nullable JetExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { if (expression == null) { return null; } @@ -241,7 +241,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitStringTemplateExpression(@NotNull JetStringTemplateExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JsStringLiteral stringLiteral = resolveAsStringConstant(expression, context); if (stringLiteral != null) { return stringLiteral; @@ -251,61 +251,61 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull private static JsNode resolveAsTemplate(@NotNull JetStringTemplateExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return StringTemplateTranslator.translate(expression, context); } @Nullable private static JsStringLiteral resolveAsStringConstant(@NotNull JetExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { Object value = getCompileTimeValue(context.bindingContext(), expression); if (value == null) { return null; } assert value instanceof String : "Compile time constant template should be a String constant."; - String constantString = (String)value; + String constantString = (String) value; return context.program().getStringLiteral(constantString); } @Override @NotNull public JsNode visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return QualifiedExpressionTranslator.translateQualifiedExpression(expression, context); } @Override @NotNull public JsNode visitPrefixExpression(@NotNull JetPrefixExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return UnaryOperationTranslator.translate(expression, context); } @Override @NotNull public JsNode visitPostfixExpression(@NotNull JetPostfixExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return UnaryOperationTranslator.translate(expression, context); } @Override @NotNull public JsNode visitIsExpression(@NotNull JetIsExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return Translation.patternTranslator(context).translateIsExpression(expression); } @Override @NotNull public JsNode visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return QualifiedExpressionTranslator.translateQualifiedExpression(expression, context); } @Override @NotNull public JsNode visitWhenExpression(@NotNull JetWhenExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return Translation.translateWhenExpression(expression, context); } @@ -313,7 +313,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitBinaryWithTypeRHSExpression(@NotNull JetBinaryExpressionWithTypeRHS expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { // we actually do not care for types in js return Translation.translateExpression(expression.getLeft(), context); } @@ -321,58 +321,58 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitBreakExpression(@NotNull JetBreakExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return new JsBreak(); } @Override @NotNull public JsNode visitContinueExpression(@NotNull JetContinueExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return new JsContinue(); } @Override @NotNull public JsNode visitFunctionLiteralExpression(@NotNull JetFunctionLiteralExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return Translation.functionTranslator(expression, context).translateAsLiteral(); } @Override @NotNull public JsNode visitThisExpression(@NotNull JetThisExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { DeclarationDescriptor descriptor = - getDescriptorForReferenceExpression(context.bindingContext(), expression.getInstanceReference()); + getDescriptorForReferenceExpression(context.bindingContext(), expression.getInstanceReference()); return TranslationUtils.getThisObject(context, descriptor); } @Override @NotNull public JsNode visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return AccessTranslationUtils.translateAsGet(expression, context); } @Override @NotNull public JsNode visitForExpression(@NotNull JetForExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return ForTranslator.translate(expression, context); } @Override @NotNull public JsNode visitTryExpression(@NotNull JetTryExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return TryTranslator.translate(expression, context); } @Override @NotNull public JsNode visitTupleExpression(@NotNull JetTupleExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JsArrayLiteral result = new JsArrayLiteral(); for (JetExpression entry : expression.getEntries()) { result.getExpressions().add(translateAsExpression(entry, context)); @@ -383,7 +383,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitThrowExpression(@NotNull JetThrowExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JetExpression thrownExpression = expression.getThrownExpression(); assert thrownExpression != null : "Thrown expression must not be null"; return new JsThrow(translateAsExpression(thrownExpression, context)); @@ -392,14 +392,14 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitObjectLiteralExpression(@NotNull JetObjectLiteralExpression expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return ClassTranslator.generateObjectLiteralExpression(expression, context); } @Override @NotNull public JsNode visitObjectDeclaration(@NotNull JetObjectDeclaration expression, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { JetObjectDeclarationName objectDeclarationName = getObjectDeclarationName(expression); DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), objectDeclarationName); JsName propertyName = context.getNameForDescriptor(descriptor); @@ -410,7 +410,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @Override @NotNull public JsNode visitNamedFunction(@NotNull JetNamedFunction function, - @NotNull TranslationContext context) { + @NotNull TranslationContext context) { return FunctionTranslator.newInstance(function, context).translateAsLocalFunction(); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java index 2e68a7ed488..605a6b94fd6 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java @@ -22,18 +22,15 @@ import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression; -import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.reference.ReferenceTranslator; -import org.jetbrains.k2js.translate.utils.BindingUtils; import org.jetbrains.k2js.translate.utils.JsDescriptorUtils; import org.jetbrains.k2js.translate.utils.TranslationUtils; import org.jetbrains.k2js.translate.utils.closure.ClosureContext; @@ -43,6 +40,7 @@ import java.util.ArrayList; import java.util.List; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor; +import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message; import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody; import static org.jetbrains.k2js.translate.utils.JsAstUtils.setParameters; import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*; @@ -81,7 +79,8 @@ public final class FunctionTranslator extends AbstractTranslator { this.descriptor = getFunctionDescriptor(context.bindingContext(), functionDeclaration); this.functionDeclaration = functionDeclaration; this.functionObject = context().getFunctionObject(descriptor); - assert this.functionObject.getParameters().isEmpty() : DiagnosticUtils.atLocation(BindingContextUtils.descriptorToDeclaration(context.bindingContext(), descriptor)); + assert this.functionObject.getParameters().isEmpty() + : message(bindingContext(), descriptor, "Function " + functionDeclaration.getText() + " processed for the second time."); this.functionBody = functionObject.getBody(); //NOTE: it's important we compute the context before we start the computation this.functionBodyContext = getFunctionBodyContext(); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index ff97abb9815..1ca078f5d6d 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -19,13 +19,9 @@ package org.jetbrains.k2js.translate.reference; import com.google.common.collect.Lists; import com.google.dart.compiler.backend.js.ast.*; import com.google.dart.compiler.util.AstUtil; -import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; -import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.calls.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall; @@ -33,6 +29,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.intrinsic.Intrinsic; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; +import org.jetbrains.k2js.translate.utils.ErrorReportingUtils; import java.util.ArrayList; import java.util.List; @@ -131,20 +128,9 @@ public final class CallTranslator extends AbstractTranslator { try { Intrinsic intrinsic = context().intrinsics().getFunctionIntrinsic((FunctionDescriptor) descriptor); return intrinsic.apply(callParameters.getThisOrReceiverOrNull(), arguments, context()); - } catch (RuntimeException e) { - PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext(), descriptor); - if (element == null) { - element = BindingContextUtils.descriptorToDeclaration(bindingContext(), descriptor.getOriginal()); - } - if (element == null && descriptor instanceof ASTNode) { - element = DiagnosticUtils.getClosestPsiElement((ASTNode) descriptor); - } - if (element != null) { - String location = DiagnosticUtils.atLocation(element); - throw new IllegalStateException(e.getMessage() + " at " + location, e); - } else { - throw e; - } + } + catch (RuntimeException e) { + throw ErrorReportingUtils.reportErrorWithLocation(e, descriptor, bindingContext()); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java index 75121bae788..939c64167be 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java @@ -17,16 +17,13 @@ package org.jetbrains.k2js.translate.reference; import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.utils.ErrorReportingUtils; import static org.jetbrains.k2js.translate.general.Translation.translateAsExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; @@ -72,16 +69,7 @@ public final class QualifiedExpressionTranslator { ((JetSimpleNameExpression)selector, receiver, callType, context); } if (selector instanceof JetCallExpression) { - try { - return CallExpressionTranslator.translate((JetCallExpression)selector, receiver, callType, context); - } catch (RuntimeException e) { - if (selector != null) { - String location = DiagnosticUtils.atLocation(selector); - throw new IllegalStateException(e.getMessage() + " at " + location, e); - } else { - throw e; - } - } + return invokeCallExpressionTranslator(receiver, selector, callType, context); } //TODO: never get there if (selector instanceof JetSimpleNameExpression) { @@ -90,6 +78,18 @@ public final class QualifiedExpressionTranslator { throw new AssertionError("Unexpected qualified expression: " + selector.getText()); } + @NotNull + private static JsExpression invokeCallExpressionTranslator(@Nullable JsExpression receiver, + @NotNull JetExpression selector, + @NotNull CallType callType, + @NotNull TranslationContext context) { + try { + return CallExpressionTranslator.translate((JetCallExpression) selector, receiver, callType, context); + } catch (RuntimeException e) { + throw ErrorReportingUtils.reportErrorWithLocation(selector, e); + } + } + @Nullable private static JsExpression translateReceiver(@NotNull JetQualifiedExpression expression, @NotNull TranslationContext context) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index f7378837b67..9a197b3bb34 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -21,7 +21,6 @@ import com.intellij.util.containers.OrderedSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; @@ -38,6 +37,7 @@ import java.util.Set; import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_GET; import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_SET; +import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message; import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*; /** @@ -57,7 +57,7 @@ public final class BindingUtils { DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); assert descriptor != null; assert descriptorClass.isInstance(descriptor) - : expression.toString() + " expected to have of type" + descriptorClass.toString() + DiagnosticUtils.atLocation(expression) + "."; + : message(expression, expression.toString() + " expected to have of type" + descriptorClass.toString()); //noinspection unchecked return (D) descriptor; } @@ -73,7 +73,7 @@ public final class BindingUtils { @NotNull JetFile declaration) { NamespaceDescriptor namespaceDescriptor = context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, JetPsiUtil.getFQName(declaration)); - assert namespaceDescriptor != null : "File should have a namespace descriptor" + DiagnosticUtils.atLocation(declaration) + "."; + assert namespaceDescriptor != null : message(declaration, "File should have a namespace descriptor"); return namespaceDescriptor; } @@ -92,19 +92,17 @@ public final class BindingUtils { @NotNull public static JetClass getClassForDescriptor(@NotNull BindingContext context, @NotNull ClassDescriptor descriptor) { - JetClass result = (JetClass) BindingContextUtils.classDescriptorToDeclaration(context, descriptor); - if (result == null) { - throw new IllegalStateException("JetClass not found for " + descriptor); - } - return result; + PsiElement result = BindingContextUtils.classDescriptorToDeclaration(context, descriptor); + assert result instanceof JetClass : message(context, descriptor, "JetClass not found for " + descriptor); + return (JetClass) result; } @NotNull public static JetFunction getFunctionForDescriptor(@NotNull BindingContext context, @NotNull SimpleFunctionDescriptor descriptor) { PsiElement result = BindingContextUtils.callableDescriptorToDeclaration(context, descriptor); - assert result instanceof JetFunction : "SimpleFunctionDescriptor should have declaration of type JetFunction at " + DiagnosticUtils.atLocation( - context, descriptor) + "."; + assert result instanceof JetFunction + : message(context, descriptor, "SimpleFunctionDescriptor should have declaration of type JetFunction"); return (JetFunction) result; } @@ -132,8 +130,7 @@ public final class BindingUtils { //TODO: never get there return null; } - assert result instanceof JetDeclaration : "Descriptor should correspond to an element at " + DiagnosticUtils.atLocation(null, - descriptor) + "."; + assert result instanceof JetDeclaration : message(context, descriptor, "Descriptor should correspond to an element"); return (JetDeclaration) result; } @@ -141,8 +138,8 @@ public final class BindingUtils { private static JetParameter getParameterForDescriptor(@NotNull BindingContext context, @NotNull ValueParameterDescriptor descriptor) { PsiElement result = BindingContextUtils.descriptorToDeclaration(context, descriptor); - assert result instanceof JetParameter : "ValueParameterDescriptor should have corresponding JetParameter at " + DiagnosticUtils.atLocation( - context, descriptor) + "."; + assert result instanceof JetParameter : + message(context, descriptor, "ValueParameterDescriptor should have corresponding JetParameter"); return (JetParameter) result; } @@ -154,7 +151,7 @@ public final class BindingUtils { public static boolean isStatement(@NotNull BindingContext context, @NotNull JetExpression expression) { Boolean isStatement = context.get(BindingContext.STATEMENT, expression); - assert isStatement != null : "Invalid behaviour of get(BindingContext.STATEMENT) at " + DiagnosticUtils.atLocation(expression) + "."; + assert isStatement != null : message(expression, "Invalid behaviour of get(BindingContext.STATEMENT) at"); return isStatement; } @@ -162,7 +159,7 @@ public final class BindingUtils { public static JetType getTypeByReference(@NotNull BindingContext context, @NotNull JetTypeReference typeReference) { JetType result = context.get(BindingContext.TYPE, typeReference); - assert result != null : "TypeReference should reference a type at " + DiagnosticUtils.atLocation(typeReference) + "."; + assert result != null : message(typeReference, "TypeReference should reference a type"); return result; } @@ -192,8 +189,8 @@ public final class BindingUtils { public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context, @NotNull JetReferenceExpression reference) { DeclarationDescriptor referencedDescriptor = getNullableDescriptorForReferenceExpression(context, reference); - assert referencedDescriptor != null : "Reference expression must reference a descriptor for reference " + reference.getText() + - " at " + DiagnosticUtils.atLocation(reference); + assert referencedDescriptor != null + : message(reference, "Reference expression must reference a descriptor for reference " + reference.getText()); return referencedDescriptor; } @@ -211,7 +208,7 @@ public final class BindingUtils { public static ResolvedCall getResolvedCall(@NotNull BindingContext context, @NotNull JetExpression expression) { ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression); - assert resolvedCall != null : "Must resolve to a call at " + DiagnosticUtils.atLocation(expression) + "."; + assert resolvedCall != null : message(expression, expression.getText() + " must resolve to a call"); return resolvedCall; } @@ -219,7 +216,7 @@ public final class BindingUtils { public static ResolvedCall getResolvedCallForProperty(@NotNull BindingContext context, @NotNull JetExpression expression) { ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression); - assert resolvedCall != null : "Must resolve to a call at " + DiagnosticUtils.atLocation(expression) + "."; + assert resolvedCall != null : message(expression, expression.getText() + "must resolve to a call"); if (resolvedCall instanceof VariableAsFunctionResolvedCall) { return ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall(); } @@ -235,7 +232,7 @@ public final class BindingUtils { public static boolean isVariableReassignment(@NotNull BindingContext context, @NotNull JetExpression expression) { Boolean result = context.get(BindingContext.VARIABLE_REASSIGNMENT, expression); - assert result != null : "at " + DiagnosticUtils.atLocation(expression) + "."; + assert result != null : message(expression); return result; } @@ -249,7 +246,7 @@ public final class BindingUtils { if (descriptorForReferenceExpression == null) return null; assert descriptorForReferenceExpression instanceof FunctionDescriptor - : "Operation should resolve to function descriptor at " + DiagnosticUtils.atLocation(expression.getOperationReference()) + "."; + : message(expression.getOperationReference(), "Operation should resolve to function descriptor"); return (FunctionDescriptor) descriptorForReferenceExpression; } @@ -258,7 +255,7 @@ public final class BindingUtils { @NotNull PsiElement element) { DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); - assert descriptor != null : element + " doesn't have a descriptor at " + DiagnosticUtils.atLocation(element) + "."; + assert descriptor != null : message(element, element + " doesn't have a descriptor"); return descriptor; } @@ -274,18 +271,19 @@ public final class BindingUtils { @NotNull public static JetExpression getDefaultArgument(@NotNull BindingContext context, @NotNull ValueParameterDescriptor parameterDescriptor) { - ValueParameterDescriptor descriptorWhichDeclaresDefaultValue = getOriginalDescriptorWhichDeclaresDefaultValue(context, parameterDescriptor); + ValueParameterDescriptor descriptorWhichDeclaresDefaultValue = + getOriginalDescriptorWhichDeclaresDefaultValue(context, parameterDescriptor); JetParameter psiParameter = getParameterForDescriptor(context, descriptorWhichDeclaresDefaultValue); JetExpression defaultValue = psiParameter.getDefaultValue(); - assert defaultValue != null : "No default value found in PSI at " + DiagnosticUtils.atLocation(context, parameterDescriptor) + "."; + assert defaultValue != null : message(context, parameterDescriptor, "No default value found in PSI"); return defaultValue; } private static ValueParameterDescriptor getOriginalDescriptorWhichDeclaresDefaultValue( BindingContext context, @NotNull ValueParameterDescriptor parameterDescriptor) { ValueParameterDescriptor result = parameterDescriptor; - assert result.hasDefaultValue() : "Unsupplied parameter must have default value at " + DiagnosticUtils.atLocation(context, - parameterDescriptor) + "."; + assert result.hasDefaultValue() : + message(context, parameterDescriptor, "Unsupplied parameter must have default value"); while (!result.declaresDefaultValue()) { result = result.getOverriddenDescriptors().iterator().next(); } @@ -296,7 +294,8 @@ public final class BindingUtils { public static FunctionDescriptor getIteratorFunction(@NotNull BindingContext context, @NotNull JetExpression rangeExpression) { FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_ITERATOR, rangeExpression); - assert functionDescriptor != null : "Range expression must have a descriptor for iterator function at " + DiagnosticUtils.atLocation(rangeExpression) + "."; + assert functionDescriptor != null : + message(rangeExpression, "Range expression must have a descriptor for iterator function"); return functionDescriptor; } @@ -304,7 +303,8 @@ public final class BindingUtils { public static FunctionDescriptor getNextFunction(@NotNull BindingContext context, @NotNull JetExpression rangeExpression) { FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_NEXT, rangeExpression); - assert functionDescriptor != null : "Range expression must have a descriptor for next function at " + DiagnosticUtils.atLocation(rangeExpression) + "."; + assert functionDescriptor != null : ErrorReportingUtils + .message(rangeExpression, "Range expression must have a descriptor for next function"); return functionDescriptor; } @@ -312,7 +312,8 @@ public final class BindingUtils { public static CallableDescriptor getHasNextCallable(@NotNull BindingContext context, @NotNull JetExpression rangeExpression) { CallableDescriptor hasNextDescriptor = context.get(BindingContext.LOOP_RANGE_HAS_NEXT, rangeExpression); - assert hasNextDescriptor != null : "Range expression must have a descriptor for hasNext function or property at " + DiagnosticUtils.atLocation(rangeExpression) + "."; + assert hasNextDescriptor != null + : message(rangeExpression, "Range expression must have a descriptor for hasNext function or property"); return hasNextDescriptor; } @@ -320,7 +321,7 @@ public final class BindingUtils { public static PropertyDescriptor getPropertyDescriptorForObjectDeclaration(@NotNull BindingContext context, @NotNull JetObjectDeclarationName name) { PropertyDescriptor propertyDescriptor = context.get(BindingContext.OBJECT_DECLARATION, name); - assert propertyDescriptor != null : "at " + DiagnosticUtils.atLocation(name) + "."; + assert propertyDescriptor != null : message(name); return propertyDescriptor; } @@ -342,7 +343,7 @@ public final class BindingUtils { public static JetType getTypeForExpression(@NotNull BindingContext context, @NotNull JetExpression expression) { JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression); - assert type != null : "at " + DiagnosticUtils.atLocation(expression) + "."; + assert type != null : message(expression); return type; } @@ -353,7 +354,7 @@ public final class BindingUtils { ResolvedCall resolvedCall = context.get(isGet ? INDEXED_LVALUE_GET : INDEXED_LVALUE_SET, arrayAccessExpression); - assert resolvedCall != null : "at " + DiagnosticUtils.atLocation(arrayAccessExpression) + "."; + assert resolvedCall != null : message(arrayAccessExpression); return resolvedCall; } @@ -361,7 +362,7 @@ public final class BindingUtils { @NotNull JetClassOrObject declaration) { ConstructorDescriptor primaryConstructor = ((ClassDescriptorFromSource) getClassDescriptor(bindingContext, declaration)).getUnsubstitutedPrimaryConstructor(); - assert primaryConstructor != null : "Traits do not have initialize methods at " + DiagnosticUtils.atLocation(declaration) + "."; + assert primaryConstructor != null : message(declaration, "Traits do not have initialize methods"); return primaryConstructor; } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/ErrorReportingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/ErrorReportingUtils.java new file mode 100644 index 00000000000..6ef206c31e8 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/ErrorReportingUtils.java @@ -0,0 +1,66 @@ +/* + * 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.k2js.translate.utils; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.resolve.BindingContext; + +/** + * @author Pavel Talanov + */ +public final class ErrorReportingUtils { + private ErrorReportingUtils() { + } + + @NotNull + public static RuntimeException reportErrorWithLocation(@NotNull JetExpression selector, @NotNull RuntimeException e) { + return reportErrorWithLocation(e, DiagnosticUtils.atLocation(selector)); + } + + @NotNull + private static RuntimeException reportErrorWithLocation(@NotNull RuntimeException e, @NotNull String location) { + throw new RuntimeException(e.getMessage() + " at " + location, e); + } + + @NotNull + public static String message(@NotNull PsiElement expression, @NotNull String messageText) { + return messageText + " at " + DiagnosticUtils.atLocation(expression) + "."; + } + + @NotNull + public static String message(@NotNull BindingContext context, + @NotNull DeclarationDescriptor descriptor, + @NotNull String explainingMessage) { + return explainingMessage + " at " + DiagnosticUtils.atLocation(context, descriptor) + "."; + } + + @NotNull + public static String message(@NotNull PsiElement element) { + return "Error at " + DiagnosticUtils.atLocation(element) + "."; + } + + @NotNull + public static RuntimeException reportErrorWithLocation(@NotNull RuntimeException e, + @NotNull DeclarationDescriptor descriptor, + @NotNull BindingContext bindingContext) { + throw reportErrorWithLocation(e, DiagnosticUtils.atLocation(bindingContext, descriptor)); + } +}