blob: dd947f9c4c8ffade00bf5b790d2e435778263543 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* 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 com.google.gwt.lang;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.impl.StackTraceCreator;
import javaemul.internal.annotations.DoNotInline;
/**
* This is a magic class the compiler uses to throw and check exceptions.
*/
final class Exceptions {
@DoNotInline // This frame can be useful in understanding the native stack
static Object toJava(Object e) {
// Although this is impossible to happen in code generated from Java (as we always unwrap
// before throwing), there are code out there where the Java exception is instantiated and
// thrown in native code, hence we may receive it already wrapped.
if (e instanceof Throwable) {
return e;
}
Throwable javaException = getJavaException(e);
if (javaException == null) {
javaException = new JavaScriptException(e);
StackTraceCreator.captureStackTrace(javaException);
}
return javaException;
}
@DoNotInline // This method shouldn't be inlined and pruned as JsStackEmulator needs it.
static native Object toJs(Object t)/*-{
return t.@Throwable::backingJsObject;
}-*/;
private static native Throwable getJavaException(Object e)/*-{
return e && e.__java$exception;
}-*/;
static AssertionError makeAssertionError() {
return new AssertionError();
}
/*
* We use nonstandard naming here so it's easy for the compiler to map to
* method names based on primitive type name.
*/
// CHECKSTYLE_OFF
static AssertionError makeAssertionError_boolean(boolean message) {
return new AssertionError(message);
}
static AssertionError makeAssertionError_char(char message) {
return new AssertionError(message);
}
static AssertionError makeAssertionError_double(double message) {
return new AssertionError(message);
}
static AssertionError makeAssertionError_float(float message) {
return new AssertionError(message);
}
static AssertionError makeAssertionError_int(int message) {
return new AssertionError(message);
}
static AssertionError makeAssertionError_long(long message) {
return new AssertionError(message);
}
static AssertionError makeAssertionError_Object(Object message) {
return new AssertionError(message);
}
/**
* Throws a TypeError if the argument is null. Otherwise,
* returns the argument.
*
* <p>The GWT compiler inserts calls to this method as a debugging aid, but
* they will be removed in production compiles. We don't throw a
* NullPointerException to make it harder to accidentally write code that
* works in development and fails in production.
*
* <p> Instead of attempting to catch this exception, we recommend adding
* an explicit null check and throwing java.lang.NullPointerException,
* so that the GWT compiler doesn't remove the null check you're depending on.
*/
static native <T> T checkNotNull(T arg) /*-{
if (arg == null) {
throw new TypeError("null pointer");
}
return arg;
}-*/;
/**
* Use by the try-with-resources construct. Look at
* {@link com.google.gwt.dev.jjs.impl.GwtAstBuilder.createCloseBlockFor}.
*
* @param resource a resource implementing the AutoCloseable interface.
* @param mainException an exception being propagated.
* @return an exception to propagate or {@code null} if none.
*/
static Throwable safeClose(AutoCloseable resource, Throwable mainException) {
if (resource == null) {
return mainException;
}
try {
resource.close();
} catch (Throwable e) {
if (mainException == null) {
return e;
}
mainException.addSuppressed(e);
}
return mainException;
}
// CHECKSTYLE_ON
}