npe() runtime intrinsic method.
This commit is contained in:
@@ -87,6 +87,7 @@ public class IntrinsicMethods {
|
|||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
|
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
||||||
|
declareOverload(myStdLib.getLibraryScope().getFunctions("npe"), 0, new NPE());
|
||||||
|
|
||||||
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
||||||
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class NPE implements IntrinsicMethod {
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||||
|
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||||
|
v.invokestatic("jet/runtime/Intrinsics", "npe", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||||
|
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v);
|
||||||
|
return StackValue.onStack(expectedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,9 +42,7 @@ fun Any?.equals(other : Any?) : Boolean// = this === other
|
|||||||
// Returns "null" for null
|
// Returns "null" for null
|
||||||
fun Any?.toString() : String// = this === other
|
fun Any?.toString() : String// = this === other
|
||||||
|
|
||||||
// fun <T> array(vararg elements : T) : Array<T>
|
fun <T : Any> T?.npe() : T
|
||||||
|
|
||||||
// fun array(vararg elements : Int) : IntArray
|
|
||||||
|
|
||||||
fun String?.plus(other: Any?) : String
|
fun String?.plus(other: Any?) : String
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.jetbrains.jet.runtime;
|
||||||
|
|
||||||
|
import jet.runtime.Intrinsics;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.jetbrains.jet.codegen.CodegenTestCase;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class JetNpeTest extends CodegenTestCase {
|
||||||
|
public void testStackTrace () {
|
||||||
|
try {
|
||||||
|
Intrinsics.npe(null);
|
||||||
|
fail("No NPE thrown");
|
||||||
|
}
|
||||||
|
catch (NullPointerException e) {
|
||||||
|
StackTraceElement stackTraceElement = e.getStackTrace()[0];
|
||||||
|
assertEquals(stackTraceElement.getMethodName(), "testStackTrace");
|
||||||
|
assertEquals(stackTraceElement.getClassName(), "org.jetbrains.jet.runtime.JetNpeTest");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNotNull () throws Exception {
|
||||||
|
loadText("fun box() = if(10.npe() == 10) \"OK\" else \"fail\"");
|
||||||
|
blackBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNull () throws Exception {
|
||||||
|
loadText("fun box() = if(null.npe() == 10) \"OK\" else \"fail\"");
|
||||||
|
Method box = generateFunction("box");
|
||||||
|
assertThrows(box, NullPointerException.class, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,4 +10,14 @@ public class Intrinsics {
|
|||||||
public static String stringPlus(String self, Object other) {
|
public static String stringPlus(String self, Object other) {
|
||||||
return ((self == null) ? "null" : self) + ((other == null) ? "null" : other.toString());
|
return ((self == null) ? "null" : self) + ((other == null) ? "null" : other.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object npe(Object self) {
|
||||||
|
if(self == null)
|
||||||
|
return throwNpe();
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object throwNpe() {
|
||||||
|
throw new JetNullPointerException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package jet.runtime;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
class JetNullPointerException extends NullPointerException {
|
||||||
|
@Override
|
||||||
|
public synchronized Throwable fillInStackTrace() {
|
||||||
|
super.fillInStackTrace();
|
||||||
|
StackTraceElement[] stackTrace = getStackTrace();
|
||||||
|
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
|
||||||
|
boolean skip = true;
|
||||||
|
for(StackTraceElement ste : stackTrace) {
|
||||||
|
if(!skip) {
|
||||||
|
list.add(ste);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if("jet.runtime.Intrinsics".equals(ste.getClassName()) && "npe".equals(ste.getMethodName())) {
|
||||||
|
skip = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setStackTrace(list.toArray(new StackTraceElement[list.size()]));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Intrinsics.npe(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user