All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.dev.jjs.intrinsic.com.google.gwt.lang.Array Maven / Gradle / Ivy

Go to download

Vaadin is a web application framework for Rich Internet Applications (RIA). Vaadin enables easy development and maintenance of fast and secure rich web applications with a stunning look and feel and a wide browser support. It features a server-side architecture with the majority of the logic running on the server. Ajax technology is used at the browser-side to ensure a rich and interactive user experience.

There is a newer version: 8.25.2
Show newest version
/*
 * 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.JavaScriptObject;
import com.google.gwt.core.client.impl.DoNotInline;

/**
 * This is an intrinsic class that contains the implementation details for Java arrays. 

* * This class should contain only static methods or fields. */ public final class Array { // Array element type classes private static final int TYPE_JAVA_OBJECT = 0; private static final int TYPE_JAVA_OBJECT_OR_JSO = 1; private static final int TYPE_JSO = 2; private static final int TYPE_JAVA_LANG_OBJECT = 3; private static final int TYPE_JAVA_LANG_STRING = 4; private static final int TYPE_JS_INTERFACE = 5; private static final int TYPE_PRIMITIVE_LONG = 6; private static final int TYPE_PRIMITIVE_NUMBER = 7; private static final int TYPE_PRIMITIVE_BOOLEAN = 8; /** * Creates a copy of the specified array. */ public static T[] clone(T[] array) { return cloneSubrange(array, 0, array.length); } /** * Creates a copy of a subrange of the specified array. */ public static T[] cloneSubrange(T[] array, int fromIndex, int toIndex) { Object result = arraySlice(array, fromIndex, toIndex); initValues(array.getClass(), Util.getCastableTypeMap(array), Array.getElementTypeId(array), Array.getElementTypeCategory(array), result); // implicit type arg not inferred (as of JDK 1.5.0_07) return Array. asArray(result); } /** * Creates a new array of the exact same type and length as a given array. */ public static T[] createFrom(T[] array) { return createFrom(array, array.length); } /** * Creates an empty array of the exact same type as a given array, with the * specified length. */ public static T[] createFrom(T[] array, int length) { // TODO(rluble): The behaviour here seems erroneous as the array elements will not be // initialized but left undefined. However the usages seem to be safe and changing here // might have performace penalty. Maybe rename to createUninitializedFrom(), to make // the meaning clearer. Object result = initializeArrayElementsWithDefaults(TYPE_JAVA_OBJECT, length); initValues(array.getClass(), Util.getCastableTypeMap(array), Array.getElementTypeId(array), Array.getElementTypeCategory(array), result); // implicit type arg not inferred (as of JDK 1.5.0_07) return Array. asArray(result); } /** * Creates an array like "new T[a][b][c][][]" by passing in a native JSON * array, [a, b, c]. * * @param leafClassLiteral the class literal for the leaf class * @param castableTypeMap the map of types to which this array can be casted, * in the form of a JSON map object * @param elementTypeId the typeId of array elements * @param elementTypeCategory whether the element type is java.lang.Object * ({@link TYPE_JAVA_LANG_OBJECT}), is guaranteed to be a java object * ({@link TYPE_JAVA_OBJECT}), is guaranteed to be a JSO * ({@link TYPE_JSO}), can be either ({@link TYPE_JAVA_OBJECT_OR_JSO}) or * or some primitive type {@link TYPE_PRIMITIVE_BOOLEAN}, {@link TYPE_PRIMITIVE_LONG} or * {@link TYPE_PRIMITIVE_NUMBER}. * @param length the length of the array * @param dimensions the number of dimensions of the array * @return the new array */ public static Object initDim(Class leafClassLiteral, JavaScriptObject castableTypeMap, JavaScriptObject elementTypeId, int length, int elementTypeCategory, int dimensions) { Object result = initializeArrayElementsWithDefaults(elementTypeCategory, length); initValues(getClassLiteralForArray(leafClassLiteral, dimensions), castableTypeMap, elementTypeId, elementTypeCategory, result); return result; } /** * Creates an array like "new T[a][b][c][][]" by passing in a native JSON * array, [a, b, c]. * * @param leafClassLiteral the class literal for the leaf class * @param castableTypeMapExprs the JSON castableTypeMap of each dimension, * from highest to lowest * @param elementTypeIds the elementTypeId of each dimension, from highest to lowest * @param leafElementTypeCategory whether the element type is java.lang.Object * ({@link TYPE_JAVA_LANG_OBJECT}), is guaranteed to be a java object * ({@link TYPE_JAVA_OBJECT}), is guaranteed to be a JSO * ({@link TYPE_JSO}), can be either ({@link TYPE_JAVA_OBJECT_OR_JSO}) or * or some primitive type {@link TYPE_PRIMITIVE_BOOLEAN}, {@link TYPE_PRIMITIVE_LONG} or * {@link TYPE_PRIMITIVE_NUMBER}. * @param dimExprs the length of each dimension, from highest to lower * @return the new array */ public static Object initDims(Class leafClassLiteral, JavaScriptObject[] castableTypeMapExprs, JavaScriptObject[] elementTypeIds, int leafElementTypeCategory, int[] dimExprs, int count) { return initDims(leafClassLiteral, castableTypeMapExprs, elementTypeIds, leafElementTypeCategory, dimExprs, 0, count); } /** * Creates an array like "new T[][]{a,b,c,d}" by passing in a native JSON * array, [a, b, c, d]. * * @param arrayClass the class of the array * @param castableTypeMap the map of types to which this array can be casted, * in the form of a JSON map object * @param elementTypeId the typeId of array elements * @param elementTypeCategory whether the element type is java.lang.Object * ({@link TYPE_JAVA_LANG_OBJECT}), is guaranteed to be a java object * ({@link TYPE_JAVA_OBJECT}), is guaranteed to be a JSO * ({@link TYPE_JSO}), can be either ({@link TYPE_JAVA_OBJECT_OR_JSO}) or * or some primitive type {@link TYPE_PRIMITIVE_BOOLEAN}, {@link TYPE_PRIMITIVE_LONG} or * {@link TYPE_PRIMITIVE_NUMBER}. * @param array the JSON array that will be transformed into a GWT array * @return values; having wrapped it for GWT */ public static Object initValues(Class arrayClass, JavaScriptObject castableTypeMap, JavaScriptObject elementTypeId, int elementTypeCategory, Object array) { setClass(array, arrayClass); Util.setCastableTypeMap(array, castableTypeMap); Util.setTypeMarker(array); Array.setElementTypeId(array, elementTypeId); Array.setElementTypeCategory(array, elementTypeCategory); return array; } /** * Copy an array using native Javascript. The destination array must be a real * Java array (ie, already has the GWT type info on it). No error checking is performed -- the * caller is expected to have verified everything first. * * @param src source array for copy * @param srcOfs offset into source array * @param dest destination array for copy * @param destOfs offset into destination array * @param len number of elements to copy */ public static void nativeArraycopy(Object src, int srcOfs, Object dest, int destOfs, int len) { nativeArraySplice(src, srcOfs, dest, destOfs, len, true); } /** * Insert one array into another native Javascript. The destination array must be a real * Java array (ie, already has the GWT type info on it). No error checking is performed -- the * caller is expected to have verified everything first. * * @param src source array where the data is taken from * @param srcOfs offset into source array * @param dest destination array for the data to be inserted * @param destOfs offset into destination array * @param len number of elements to insert */ public static void nativeArrayInsert(Object src, int srcOfs, Object dest, int destOfs, int len) { nativeArraySplice(src, srcOfs, dest, destOfs, len, false); } /** * A replacement for Array.prototype.splice to overcome the limits imposed to the number of * function parameters by browsers. */ private static native void nativeArraySplice( Object src, int srcOfs, Object dest, int destOfs, int len, boolean overwrite) /*-{ // Work around function.prototype.apply call stack size limits. // Performance: http://jsperf.com/java-system-arraycopy/2 if (src === dest) { // copying to the same array, make a copy first src = src.slice(srcOfs, srcOfs + len); srcOfs = 0; } for (var batchStart = srcOfs, end = srcOfs + len; batchStart < end;) { // increment in block var batchEnd = Math.min(batchStart + 10000, end); len = batchEnd - batchStart; Array.prototype.splice.apply(dest, [destOfs, overwrite ? len : 0] .concat(src.slice(batchStart, batchEnd))); batchStart = batchEnd; destOfs += len; } }-*/; /** * Performs an array assignment, after validating the type of the value being * stored. The form of the type check depends on the value of elementTypeId and * elementTypeCategory as follows: *

* If the elementTypeCategory is {@link TYPE_JAVA_OBJECT}, this indicates a normal cast check * should be performed, using the elementTypeId as the cast destination type. * JavaScriptObjects cannot be stored in this case. *

* If the elementTypeId is {@link TYPE_JAVA_LANG_OBJECT}, this is the cast target for the Object * type, in which case all types can be stored, including JavaScriptObject. *

* If the elementTypeId is {@link TYPE_JSO}, this indicates that only JavaScriptObjects can be * stored. *

* If the elementTypeId is {@link TYPE_JAVA_OBJECT_OR_JSO}, this indicates that both * JavaScriptObjects, and Java types can be stored. In the case of Java types, a normal cast check * should be performed, using the elementTypeId as the cast destination type. * This case is provided to support arrays declared with an interface type, which has dual * implementations (i.e. interface types which have both Java and JavaScriptObject * implementations). *

* Attempting to store an object that cannot satisfy the castability check * throws an {@link ArrayStoreException}. */ public static Object setCheck(Object array, int index, Object value) { if (value != null) { switch (Array.getElementTypeCategory(array)) { case TYPE_JAVA_LANG_STRING: if (!Cast.isJavaString(value)) { // value must be a string. throw new ArrayStoreException(); } break; case TYPE_JAVA_OBJECT: { JavaScriptObject elementTypeId = Array.getElementTypeId(array); if (!Cast.canCast(value, elementTypeId)) { // value must be castable to elementType. throw new ArrayStoreException(); } break; } case TYPE_JSO: if (!Cast.isJavaScriptObject(value)) { // value must be a JavaScriptObject throw new ArrayStoreException(); } break; case TYPE_JAVA_OBJECT_OR_JSO: { JavaScriptObject elementTypeId = Array.getElementTypeId(array); if (!Cast.isJavaScriptObject(value) && !Cast.canCast(value, elementTypeId)) { // value must be a JavaScriptObject, or else castable to the elementType. throw new ArrayStoreException(); } break; } } } return set(array, index, value); } private static native Object arraySlice(Object array, int fromIndex, int toIndex) /*-{ return array.slice(fromIndex, toIndex); }-*/; /** * Use JSNI to effect a castless type change. */ private static native T[] asArray(Object array) /*-{ return array; }-*/; /** * Creates a primitive JSON array of a given the element type class. */ private static native Object initializeArrayElementsWithDefaults( int elementTypeCategory, int length) /*-{ var array = new Array(length); var initValue; switch (elementTypeCategory) { case @com.google.gwt.lang.Array::TYPE_PRIMITIVE_LONG: // Fill array with the type used by LongLib // TODO(rluble): This should refer to the zero long value defined in LongLib initValue = {l: 0, m: 0, h:0}; break; case @com.google.gwt.lang.Array::TYPE_PRIMITIVE_NUMBER: initValue = 0; break; case @com.google.gwt.lang.Array::TYPE_PRIMITIVE_BOOLEAN: initValue = false; break; default: // Do not initialize as undefined is equivalent to null return array; } for ( var i = 0; i < length; ++i) { array[i] = initValue; } return array; }-*/; private static Object initDims(Class leafClassLiteral, JavaScriptObject[] castableTypeMapExprs, JavaScriptObject[] elementTypeIds, int leafElementTypeCategory, int[] dimExprs, int index, int count) { int length = dimExprs[index]; boolean isLastDim = (index == (count - 1)); // All dimensions but the last are plain reference types. int elementTypeCategory = isLastDim ? leafElementTypeCategory : TYPE_JAVA_OBJECT; Object result = initializeArrayElementsWithDefaults(elementTypeCategory, length); initValues(getClassLiteralForArray(leafClassLiteral, count - index), castableTypeMapExprs[index], elementTypeIds[index], elementTypeCategory, result); if (!isLastDim) { // Recurse to next dimension. ++index; for (int i = 0; i < length; ++i) { set(result, i, initDims(leafClassLiteral, castableTypeMapExprs, elementTypeIds, leafElementTypeCategory, dimExprs, index, count)); } } return result; } // This method is package protected so that it is indexed. {@link ImplementClassLiteralsAsFields} // will insert calls to this method when array class literals are constructed. // // Inlining is prevented on this very hot method to avoid a subtantial increase in // {@link JsInliner} execution time. @DoNotInline static Class getClassLiteralForArray(Class clazz , int dimensions) { return getClassLiteralForArrayImpl(clazz, dimensions); } // DO NOT INLINE this method into {@link getClassLiteralForArray}. // The purpose of this method is to avoid introducing a public api to {@link java.lang.Class}. private static native Class getClassLiteralForArrayImpl( Class clazz , int dimensions) /*-{ return @java.lang.Class::getClassLiteralForArray(*)(clazz, dimensions); }-*/; /** * Sets a value in the array. */ private static native Object set(Object array, int index, Object value) /*-{ return array[index] = value; }-*/; // violator pattern so that the field remains private private static native void setClass(Object o, Class clazz) /*-{ [email protected]::___clazz = clazz; }-*/; private static native void setElementTypeId(Object array, JavaScriptObject elementTypeId) /*-{ array.__elementTypeId$ = elementTypeId; }-*/; private static native JavaScriptObject getElementTypeId(Object array) /*-{ return array.__elementTypeId$; }-*/; private static native void setElementTypeCategory(Object array, int elementTypeCategory) /*-{ array.__elementTypeCategory$ = elementTypeCategory; }-*/; private static native int getElementTypeCategory(Object array) /*-{ return array.__elementTypeCategory$; }-*/; private Array() { } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy