001 /* 002 * Copyright 2010-2013 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package jet.runtime; 018 019 import jet.Function0; 020 021 import java.util.*; 022 023 @SuppressWarnings("unused") 024 public class Intrinsics { 025 private Intrinsics() { 026 } 027 028 public static String stringPlus(String self, Object other) { 029 return ((self == null) ? "null" : self) + ((other == null) ? "null" : other.toString()); 030 } 031 032 public static void throwNpe() { 033 throw new JetNullPointerException(); 034 } 035 036 public static void checkReturnedValueIsNotNull(Object value, String className, String methodName) { 037 if (value == null) { 038 IllegalStateException exception = 039 new IllegalStateException("Method specified as non-null returned null: " + className + "." + methodName); 040 throw sanitizeStackTrace(exception); 041 } 042 } 043 044 public static void checkFieldIsNotNull(Object value, String className, String fieldName) { 045 if (value == null) { 046 IllegalStateException exception = 047 new IllegalStateException("Field specified as non-null contains null: " + className + "." + fieldName); 048 throw sanitizeStackTrace(exception); 049 } 050 } 051 052 public static void checkParameterIsNotNull(Object value, String paramName) { 053 if (value == null) { 054 StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 055 056 // #0 is Thread.getStackTrace(), #1 is Intrinsics.checkParameterIsNotNull, #2 is our caller 057 StackTraceElement caller = stackTraceElements[2]; 058 String className = caller.getClassName(); 059 String methodName = caller.getMethodName(); 060 061 IllegalArgumentException exception = 062 new IllegalArgumentException("Parameter specified as non-null contains null: " + 063 "method " + className + "." + methodName + 064 ", parameter " + paramName); 065 throw sanitizeStackTrace(exception); 066 } 067 } 068 069 public static <T> Class<T> getJavaClass(T self) { 070 return (Class<T>) self.getClass(); 071 } 072 073 public static int compare(long thisVal, long anotherVal) { 074 return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1)); 075 } 076 077 public static int compare(int thisVal, int anotherVal) { 078 return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1)); 079 } 080 081 public static boolean areEqual(Object first, Object second) { 082 return first == null ? second == null : first.equals(second); 083 } 084 085 public static <R> R stupidSync(Object lock, Function0<R> block) { 086 synchronized (lock) { 087 return block.invoke(); 088 } 089 } 090 091 private static final Set<String> METHOD_NAMES_TO_SKIP = new HashSet<String>(Arrays.asList( 092 "throwNpe", "checkReturnedValueIsNotNull", "checkFieldIsNotNull", "checkParameterIsNotNull" 093 )); 094 095 private static <T extends Throwable> T sanitizeStackTrace(T throwable) { 096 StackTraceElement[] stackTrace = throwable.getStackTrace(); 097 ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>(); 098 boolean skip = true; 099 for(StackTraceElement ste : stackTrace) { 100 if (!skip) { 101 list.add(ste); 102 } 103 else { 104 if ("jet.runtime.Intrinsics".equals(ste.getClassName())) { 105 if (METHOD_NAMES_TO_SKIP.contains(ste.getMethodName())) { 106 skip = false; 107 } 108 } 109 } 110 } 111 throwable.setStackTrace(list.toArray(new StackTraceElement[list.size()])); 112 return throwable; 113 } 114 115 private static class JetNullPointerException extends NullPointerException { 116 @Override 117 public synchronized Throwable fillInStackTrace() { 118 super.fillInStackTrace(); 119 return sanitizeStackTrace(this); 120 } 121 } 122 123 public static class SpreadBuilder extends ArrayList { 124 public void addSpread(Object array) { 125 if (array != null) { 126 if (array instanceof Object[]) { 127 Object[] arr = (Object[]) array; 128 if (arr.length > 0) { 129 ensureCapacity(size() + arr.length); 130 for (int i = 0; i < arr.length; i++) { 131 add(arr[i]); 132 } 133 } 134 } 135 else if (array instanceof Collection) { 136 addAll((Collection) array); 137 } 138 else if (array instanceof Iterable) { 139 for(Iterator iterator = ((Iterable) array).iterator(); iterator.hasNext(); ) { 140 add(iterator.next()); 141 } 142 } 143 else if (array instanceof Iterator) { 144 for(Iterator iterator = ((Iterator) array); iterator.hasNext(); ) { 145 add(iterator.next()); 146 } 147 } 148 else { 149 throw new UnsupportedOperationException("Don't know how to spread " + array.getClass()); 150 } 151 } 152 } 153 } 154 }