Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (102)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (322)
Collections:
Other Resources:
JDK 11 jdk.scripting.nashorn.jmod - Scripting Nashorn Module
JDK 11 jdk.scripting.nashorn.jmod is the JMOD file for JDK 11 Scripting Nashorn module.
JDK 11 Scripting Nashorn module compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\jdk.scripting.nashorn.jmod.
JDK 11 Scripting Nashorn module compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.
JDK 11 Scripting Nashorn module source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\jdk.scripting.nashorn.
You can click and view the content of each source code file in the list below.
✍: FYIcenter
⏎ jdk/nashorn/internal/objects/NativeString.java
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Array;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.linker.GuardedInvocation;
import jdk.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.lookup.MethodHandleFactory.LookupException;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.Getter;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.OptimisticBuiltins;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.linker.NashornGuards;
import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
/**
* ECMA 15.5 String Objects.
*/
@ScriptClass("String")
public final class NativeString extends ScriptObject implements OptimisticBuiltins {
private final CharSequence value;
/** Method handle to create an object wrapper for a primitive string */
static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
/** Method handle to retrieve the String prototype object */
private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
// initialized by nasgen
private static PropertyMap $nasgenmap$;
private NativeString(final CharSequence value) {
this(value, Global.instance());
}
NativeString(final CharSequence value, final Global global) {
this(value, global.getStringPrototype(), $nasgenmap$);
}
private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
super(proto, map);
assert JSType.isString(value);
this.value = value;
}
@Override
public String safeToString() {
return "[String " + toString() + "]";
}
@Override
public String toString() {
return getStringValue();
}
private String getStringValue() {
return value instanceof String ? (String) value : value.toString();
}
private CharSequence getValue() {
return value;
}
@Override
public String getClassName() {
return "String";
}
@Override
public Object getLength() {
return value.length();
}
// This is to support length as method call as well.
@Override
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
final String name = NashornCallSiteDescriptor.getOperand(desc);
// if str.length(), then let the bean linker handle it
if ("length".equals(name) && NashornCallSiteDescriptor.isMethodFirstOperation(desc)) {
return null;
}
return super.findGetMethod(desc, request);
}
// This is to provide array-like access to string characters without creating a NativeString wrapper.
@Override
protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
final Object self = request.getReceiver();
final Class<?> returnType = desc.getMethodType().returnType();
if (returnType == Object.class && JSType.isString(self)) {
try {
return new GuardedInvocation(MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType()), NashornGuards.getStringGuard());
} catch (final LookupException e) {
//empty. Shouldn't happen. Fall back to super
}
}
return super.findGetIndexMethod(desc, request);
}
@SuppressWarnings("unused")
private static Object get(final Object self, final Object key) {
final CharSequence cs = JSType.toCharSequence(self);
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = ArrayIndex.getArrayIndex(primitiveKey);
if (index >= 0 && index < cs.length()) {
return String.valueOf(cs.charAt(index));
}
return ((ScriptObject) Global.toObject(self)).get(primitiveKey);
}
@SuppressWarnings("unused")
private static Object get(final Object self, final double key) {
if (isRepresentableAsInt(key)) {
return get(self, (int)key);
}
return ((ScriptObject) Global.toObject(self)).get(key);
}
@SuppressWarnings("unused")
private static Object get(final Object self, final long key) {
final CharSequence cs = JSType.toCharSequence(self);
if (key >= 0 && key < cs.length()) {
return String.valueOf(cs.charAt((int)key));
}
return ((ScriptObject) Global.toObject(self)).get(key);
}
private static Object get(final Object self, final int key) {
final CharSequence cs = JSType.toCharSequence(self);
if (key >= 0 && key < cs.length()) {
return String.valueOf(cs.charAt(key));
}
return ((ScriptObject) Global.toObject(self)).get(key);
}
// String characters can be accessed with array-like indexing..
@Override
public Object get(final Object key) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = ArrayIndex.getArrayIndex(primitiveKey);
if (index >= 0 && index < value.length()) {
return String.valueOf(value.charAt(index));
}
return super.get(primitiveKey);
}
@Override
public Object get(final double key) {
if (isRepresentableAsInt(key)) {
return get((int)key);
}
return super.get(key);
}
@Override
public Object get(final int key) {
if (key >= 0 && key < value.length()) {
return String.valueOf(value.charAt(key));
}
return super.get(key);
}
@Override
public int getInt(final Object key, final int programPoint) {
return JSType.toInt32MaybeOptimistic(get(key), programPoint);
}
@Override
public int getInt(final double key, final int programPoint) {
return JSType.toInt32MaybeOptimistic(get(key), programPoint);
}
@Override
public int getInt(final int key, final int programPoint) {
return JSType.toInt32MaybeOptimistic(get(key), programPoint);
}
@Override
public double getDouble(final Object key, final int programPoint) {
return JSType.toNumberMaybeOptimistic(get(key), programPoint);
}
@Override
public double getDouble(final double key, final int programPoint) {
return JSType.toNumberMaybeOptimistic(get(key), programPoint);
}
@Override
public double getDouble(final int key, final int programPoint) {
return JSType.toNumberMaybeOptimistic(get(key), programPoint);
}
@Override
public boolean has(final Object key) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = ArrayIndex.getArrayIndex(primitiveKey);
return isValidStringIndex(index) || super.has(primitiveKey);
}
@Override
public boolean has(final int key) {
return isValidStringIndex(key) || super.has(key);
}
@Override
public boolean has(final double key) {
final int index = ArrayIndex.getArrayIndex(key);
return isValidStringIndex(index) || super.has(key);
}
@Override
public boolean hasOwnProperty(final Object key) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = ArrayIndex.getArrayIndex(primitiveKey);
return isValidStringIndex(index) || super.hasOwnProperty(primitiveKey);
}
@Override
public boolean hasOwnProperty(final int key) {
return isValidStringIndex(key) || super.hasOwnProperty(key);
}
@Override
public boolean hasOwnProperty(final double key) {
final int index = ArrayIndex.getArrayIndex(key);
return isValidStringIndex(index) || super.hasOwnProperty(key);
}
@Override
public boolean delete(final int key, final boolean strict) {
return checkDeleteIndex(key, strict)? false : super.delete(key, strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
}
@Override
public boolean delete(final Object key, final boolean strict) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = ArrayIndex.getArrayIndex(primitiveKey);
return checkDeleteIndex(index, strict)? false : super.delete(primitiveKey, strict);
}
private boolean checkDeleteIndex(final int index, final boolean strict) {
if (isValidStringIndex(index)) {
if (strict) {
throw typeError("cant.delete.property", Integer.toString(index), ScriptRuntime.safeToString(this));
}
return true;
}
return false;
}
@Override
public Object getOwnPropertyDescriptor(final Object key) {
final int index = ArrayIndex.getArrayIndex(key);
if (index >= 0 && index < value.length()) {
final Global global = Global.instance();
return global.newDataDescriptor(String.valueOf(value.charAt(index)), false, true, false);
}
return super.getOwnPropertyDescriptor(key);
}
/**
* return a List of own keys associated with the object.
* @param all True if to include non-enumerable keys.
* @param nonEnumerable set of non-enumerable properties seen already.Used
* to filter out shadowed, but enumerable properties from proto children.
* @return Array of keys.
*/
@Override
@SuppressWarnings("unchecked")
protected <T> T[] getOwnKeys(final Class<T> type, final boolean all, final Set<T> nonEnumerable) {
if (type != String.class) {
return super.getOwnKeys(type, all, nonEnumerable);
}
final List<Object> keys = new ArrayList<>();
// add string index keys
for (int i = 0; i < value.length(); i++) {
keys.add(JSType.toString(i));
}
// add super class properties
keys.addAll(Arrays.asList(super.getOwnKeys(type, all, nonEnumerable)));
return keys.toArray((T[]) Array.newInstance(type, keys.size()));
}
/**
* ECMA 15.5.3 String.length
* @param self self reference
* @return value of length property for string
*/
@Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
public static Object length(final Object self) {
return getCharSequence(self).length();
}
/**
* ECMA 15.5.3.2 String.fromCharCode ( [ char0 [ , char1 [ , ... ] ] ] )
* @param self self reference
* @param args array of arguments to be interpreted as char
* @return string with arguments translated to charcodes
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1, where = Where.CONSTRUCTOR)
public static String fromCharCode(final Object self, final Object... args) {
final char[] buf = new char[args.length];
int index = 0;
for (final Object arg : args) {
buf[index++] = (char)JSType.toUint16(arg);
}
return new String(buf);
}
/**
* ECMA 15.5.3.2 - specialization for one char
* @param self self reference
* @param value one argument to be interpreted as char
* @return string with one charcode
*/
@SpecializedFunction
public static Object fromCharCode(final Object self, final Object value) {
if (value instanceof Integer) {
return fromCharCode(self, (int)value);
}
return Character.toString((char)JSType.toUint16(value));
}
/**
* ECMA 15.5.3.2 - specialization for one char of int type
* @param self self reference
* @param value one argument to be interpreted as char
* @return string with one charcode
*/
@SpecializedFunction
public static String fromCharCode(final Object self, final int value) {
return Character.toString((char)(value & 0xffff));
}
/**
* ECMA 15.5.3.2 - specialization for two chars of int type
* @param self self reference
* @param ch1 first char
* @param ch2 second char
* @return string with one charcode
*/
@SpecializedFunction
public static Object fromCharCode(final Object self, final int ch1, final int ch2) {
return Character.toString((char)(ch1 & 0xffff)) + Character.toString((char)(ch2 & 0xffff));
}
/**
* ECMA 15.5.3.2 - specialization for three chars of int type
* @param self self reference
* @param ch1 first char
* @param ch2 second char
* @param ch3 third char
* @return string with one charcode
*/
@SpecializedFunction
public static Object fromCharCode(final Object self, final int ch1, final int ch2, final int ch3) {
return Character.toString((char)(ch1 & 0xffff)) + Character.toString((char)(ch2 & 0xffff)) + Character.toString((char)(ch3 & 0xffff));
}
/**
* ECMA 15.5.3.2 - specialization for four chars of int type
* @param self self reference
* @param ch1 first char
* @param ch2 second char
* @param ch3 third char
* @param ch4 fourth char
* @return string with one charcode
*/
@SpecializedFunction
public static String fromCharCode(final Object self, final int ch1, final int ch2, final int ch3, final int ch4) {
return Character.toString((char)(ch1 & 0xffff)) + Character.toString((char)(ch2 & 0xffff)) + Character.toString((char)(ch3 & 0xffff)) + Character.toString((char)(ch4 & 0xffff));
}
/**
* ECMA 15.5.3.2 - specialization for one char of double type
* @param self self reference
* @param value one argument to be interpreted as char
* @return string with one charcode
*/
@SpecializedFunction
public static String fromCharCode(final Object self, final double value) {
return Character.toString((char)JSType.toUint16(value));
}
/**
* ECMA 15.5.4.2 String.prototype.toString ( )
* @param self self reference
* @return self as string
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String toString(final Object self) {
return getString(self);
}
/**
* ECMA 15.5.4.3 String.prototype.valueOf ( )
* @param self self reference
* @return self as string
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String valueOf(final Object self) {
return getString(self);
}
/**
* ECMA 15.5.4.4 String.prototype.charAt (pos)
* @param self self reference
* @param pos position in string
* @return string representing the char at the given position
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String charAt(final Object self, final Object pos) {
return charAtImpl(checkObjectToString(self), JSType.toInteger(pos));
}
/**
* ECMA 15.5.4.4 String.prototype.charAt (pos) - specialized version for double position
* @param self self reference
* @param pos position in string
* @return string representing the char at the given position
*/
@SpecializedFunction
public static String charAt(final Object self, final double pos) {
return charAt(self, (int)pos);
}
/**
* ECMA 15.5.4.4 String.prototype.charAt (pos) - specialized version for int position
* @param self self reference
* @param pos position in string
* @return string representing the char at the given position
*/
@SpecializedFunction
public static String charAt(final Object self, final int pos) {
return charAtImpl(checkObjectToString(self), pos);
}
private static String charAtImpl(final String str, final int pos) {
return pos < 0 || pos >= str.length() ? "" : String.valueOf(str.charAt(pos));
}
private static int getValidChar(final Object self, final int pos) {
try {
return ((CharSequence)self).charAt(pos);
} catch (final IndexOutOfBoundsException e) {
throw new ClassCastException(); //invalid char, out of bounds, force relink
}
}
/**
* ECMA 15.5.4.5 String.prototype.charCodeAt (pos)
* @param self self reference
* @param pos position in string
* @return number representing charcode at position
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static double charCodeAt(final Object self, final Object pos) {
final String str = checkObjectToString(self);
final int idx = JSType.toInteger(pos);
return idx < 0 || idx >= str.length() ? Double.NaN : str.charAt(idx);
}
/**
* ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for double position
* @param self self reference
* @param pos position in string
* @return number representing charcode at position
*/
@SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
public static int charCodeAt(final Object self, final double pos) {
return charCodeAt(self, (int)pos); //toInt pos is ok
}
/**
* ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for int position
* @param self self reference
* @param pos position in string
* @return number representing charcode at position
*/
@SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
public static int charCodeAt(final Object self, final int pos) {
return getValidChar(self, pos);
}
/**
* ECMA 15.5.4.6 String.prototype.concat ( [ string1 [ , string2 [ , ... ] ] ] )
* @param self self reference
* @param args list of string to concatenate
* @return concatenated string
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object concat(final Object self, final Object... args) {
CharSequence cs = checkObjectToString(self);
if (args != null) {
for (final Object obj : args) {
cs = new ConsString(cs, JSType.toCharSequence(obj));
}
}
return cs;
}
/**
* ECMA 15.5.4.7 String.prototype.indexOf (searchString, position)
* @param self self reference
* @param search string to search for
* @param pos position to start search
* @return position of first match or -1
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static int indexOf(final Object self, final Object search, final Object pos) {
final String str = checkObjectToString(self);
return str.indexOf(JSType.toString(search), JSType.toInteger(pos));
}
/**
* ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for no position parameter
* @param self self reference
* @param search string to search for
* @return position of first match or -1
*/
@SpecializedFunction
public static int indexOf(final Object self, final Object search) {
return indexOf(self, search, 0);
}
/**
* ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for double position parameter
* @param self self reference
* @param search string to search for
* @param pos position to start search
* @return position of first match or -1
*/
@SpecializedFunction
public static int indexOf(final Object self, final Object search, final double pos) {
return indexOf(self, search, (int) pos);
}
/**
* ECMA 15.5.4.7 String.prototype.indexOf (searchString, position) specialized for int position parameter
* @param self self reference
* @param search string to search for
* @param pos position to start search
* @return position of first match or -1
*/
@SpecializedFunction
public static int indexOf(final Object self, final Object search, final int pos) {
return checkObjectToString(self).indexOf(JSType.toString(search), pos);
}
/**
* ECMA 15.5.4.8 String.prototype.lastIndexOf (searchString, position)
* @param self self reference
* @param search string to search for
* @param pos position to start search
* @return last position of match or -1
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static int lastIndexOf(final Object self, final Object search, final Object pos) {
final String str = checkObjectToString(self);
final String searchStr = JSType.toString(search);
final int length = str.length();
int end;
if (pos == UNDEFINED) {
end = length;
} else {
final double numPos = JSType.toNumber(pos);
end = Double.isNaN(numPos) ? length : (int)numPos;
if (end < 0) {
end = 0;
} else if (end > length) {
end = length;
}
}
return str.lastIndexOf(searchStr, end);
}
/**
* ECMA 15.5.4.9 String.prototype.localeCompare (that)
* @param self self reference
* @param that comparison object
* @return result of locale sensitive comparison operation between {@code self} and {@code that}
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static double localeCompare(final Object self, final Object that) {
final String str = checkObjectToString(self);
final Collator collator = Collator.getInstance(Global.getEnv()._locale);
collator.setStrength(Collator.IDENTICAL);
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
return collator.compare(str, JSType.toString(that));
}
/**
* ECMA 15.5.4.10 String.prototype.match (regexp)
* @param self self reference
* @param regexp regexp expression
* @return array of regexp matches
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static ScriptObject match(final Object self, final Object regexp) {
final String str = checkObjectToString(self);
NativeRegExp nativeRegExp;
if (regexp == UNDEFINED) {
nativeRegExp = new NativeRegExp("");
} else {
nativeRegExp = Global.toRegExp(regexp);
}
if (!nativeRegExp.getGlobal()) {
return nativeRegExp.exec(str);
}
nativeRegExp.setLastIndex(0);
final List<Object> matches = new ArrayList<>();
Object result;
// We follow ECMAScript 6 spec here (checking for empty string instead of previous index)
// as the ES5 specification is buggy and causes empty strings to be matched twice.
while ((result = nativeRegExp.exec(str)) != null) {
final String matchStr = JSType.toString(((ScriptObject)result).get(0));
if (matchStr.isEmpty()) {
nativeRegExp.setLastIndex(nativeRegExp.getLastIndex() + 1);
}
matches.add(matchStr);
}
if (matches.isEmpty()) {
return null;
}
return new NativeArray(matches.toArray());
}
/**
* ECMA 15.5.4.11 String.prototype.replace (searchValue, replaceValue)
* @param self self reference
* @param string item to replace
* @param replacement item to replace it with
* @return string after replacement
* @throws Throwable if replacement fails
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String replace(final Object self, final Object string, final Object replacement) throws Throwable {
final String str = checkObjectToString(self);
final NativeRegExp nativeRegExp;
if (string instanceof NativeRegExp) {
nativeRegExp = (NativeRegExp) string;
} else {
nativeRegExp = NativeRegExp.flatRegExp(JSType.toString(string));
}
if (Bootstrap.isCallable(replacement)) {
return nativeRegExp.replace(str, "", replacement);
}
return nativeRegExp.replace(str, JSType.toString(replacement), null);
}
/**
* ECMA 15.5.4.12 String.prototype.search (regexp)
*
* @param self self reference
* @param string string to search for
* @return offset where match occurred
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static int search(final Object self, final Object string) {
final String str = checkObjectToString(self);
final NativeRegExp nativeRegExp = Global.toRegExp(string == UNDEFINED ? "" : string);
return nativeRegExp.search(str);
}
/**
* ECMA 15.5.4.13 String.prototype.slice (start, end)
*
* @param self self reference
* @param start start position for slice
* @param end end position for slice
* @return sliced out substring
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String slice(final Object self, final Object start, final Object end) {
final String str = checkObjectToString(self);
if (end == UNDEFINED) {
return slice(str, JSType.toInteger(start));
}
return slice(str, JSType.toInteger(start), JSType.toInteger(end));
}
/**
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for single int parameter
*
* @param self self reference
* @param start start position for slice
* @return sliced out substring
*/
@SpecializedFunction
public static String slice(final Object self, final int start) {
final String str = checkObjectToString(self);
final int from = start < 0 ? Math.max(str.length() + start, 0) : Math.min(start, str.length());
return str.substring(from);
}
/**
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for single double parameter
*
* @param self self reference
* @param start start position for slice
* @return sliced out substring
*/
@SpecializedFunction
public static String slice(final Object self, final double start) {
return slice(self, (int)start);
}
/**
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for two int parameters
*
* @param self self reference
* @param start start position for slice
* @param end end position for slice
* @return sliced out substring
*/
@SpecializedFunction
public static String slice(final Object self, final int start, final int end) {
final String str = checkObjectToString(self);
final int len = str.length();
final int from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
final int to = end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
return str.substring(Math.min(from, to), to);
}
/**
* ECMA 15.5.4.13 String.prototype.slice (start, end) specialized for two double parameters
*
* @param self self reference
* @param start start position for slice
* @param end end position for slice
* @return sliced out substring
*/
@SpecializedFunction
public static String slice(final Object self, final double start, final double end) {
return slice(self, (int)start, (int)end);
}
/**
* ECMA 15.5.4.14 String.prototype.split (separator, limit)
*
* @param self self reference
* @param separator separator for split
* @param limit limit for splits
* @return array object in which splits have been placed
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static ScriptObject split(final Object self, final Object separator, final Object limit) {
final String str = checkObjectToString(self);
final long lim = limit == UNDEFINED ? JSType.MAX_UINT : JSType.toUint32(limit);
if (separator == UNDEFINED) {
return lim == 0 ? new NativeArray() : new NativeArray(new Object[]{str});
}
if (separator instanceof NativeRegExp) {
return ((NativeRegExp) separator).split(str, lim);
}
// when separator is a string, it is treated as a literal search string to be used for splitting.
return splitString(str, JSType.toString(separator), lim);
}
private static ScriptObject splitString(final String str, final String separator, final long limit) {
if (separator.isEmpty()) {
final int length = (int) Math.min(str.length(), limit);
final Object[] array = new Object[length];
for (int i = 0; i < length; i++) {
array[i] = String.valueOf(str.charAt(i));
}
return new NativeArray(array);
}
final List<String> elements = new LinkedList<>();
final int strLength = str.length();
final int sepLength = separator.length();
int pos = 0;
int n = 0;
while (pos < strLength && n < limit) {
final int found = str.indexOf(separator, pos);
if (found == -1) {
break;
}
elements.add(str.substring(pos, found));
n++;
pos = found + sepLength;
}
if (pos <= strLength && n < limit) {
elements.add(str.substring(pos));
}
return new NativeArray(elements.toArray());
}
/**
* ECMA B.2.3 String.prototype.substr (start, length)
*
* @param self self reference
* @param start start position
* @param length length of section
* @return substring given start and length of section
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String substr(final Object self, final Object start, final Object length) {
final String str = JSType.toString(self);
final int strLength = str.length();
int intStart = JSType.toInteger(start);
if (intStart < 0) {
intStart = Math.max(intStart + strLength, 0);
}
final int intLen = Math.min(Math.max(length == UNDEFINED ? Integer.MAX_VALUE : JSType.toInteger(length), 0), strLength - intStart);
return intLen <= 0 ? "" : str.substring(intStart, intStart + intLen);
}
/**
* ECMA 15.5.4.15 String.prototype.substring (start, end)
*
* @param self self reference
* @param start start position of substring
* @param end end position of substring
* @return substring given start and end indexes
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String substring(final Object self, final Object start, final Object end) {
final String str = checkObjectToString(self);
if (end == UNDEFINED) {
return substring(str, JSType.toInteger(start));
}
return substring(str, JSType.toInteger(start), JSType.toInteger(end));
}
/**
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for int start parameter
*
* @param self self reference
* @param start start position of substring
* @return substring given start and end indexes
*/
@SpecializedFunction
public static String substring(final Object self, final int start) {
final String str = checkObjectToString(self);
if (start < 0) {
return str;
} else if (start >= str.length()) {
return "";
} else {
return str.substring(start);
}
}
/**
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for double start parameter
*
* @param self self reference
* @param start start position of substring
* @return substring given start and end indexes
*/
@SpecializedFunction
public static String substring(final Object self, final double start) {
return substring(self, (int)start);
}
/**
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for int start and end parameters
*
* @param self self reference
* @param start start position of substring
* @param end end position of substring
* @return substring given start and end indexes
*/
@SpecializedFunction
public static String substring(final Object self, final int start, final int end) {
final String str = checkObjectToString(self);
final int len = str.length();
final int validStart = start < 0 ? 0 : start > len ? len : start;
final int validEnd = end < 0 ? 0 : end > len ? len : end;
if (validStart < validEnd) {
return str.substring(validStart, validEnd);
}
return str.substring(validEnd, validStart);
}
/**
* ECMA 15.5.4.15 String.prototype.substring (start, end) specialized for double start and end parameters
*
* @param self self reference
* @param start start position of substring
* @param end end position of substring
* @return substring given start and end indexes
*/
@SpecializedFunction
public static String substring(final Object self, final double start, final double end) {
return substring(self, (int)start, (int)end);
}
/**
* ECMA 15.5.4.16 String.prototype.toLowerCase ( )
* @param self self reference
* @return string to lower case
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String toLowerCase(final Object self) {
return checkObjectToString(self).toLowerCase(Locale.ROOT);
}
/**
* ECMA 15.5.4.17 String.prototype.toLocaleLowerCase ( )
* @param self self reference
* @return string to locale sensitive lower case
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String toLocaleLowerCase(final Object self) {
return checkObjectToString(self).toLowerCase(Global.getEnv()._locale);
}
/**
* ECMA 15.5.4.18 String.prototype.toUpperCase ( )
* @param self self reference
* @return string to upper case
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String toUpperCase(final Object self) {
return checkObjectToString(self).toUpperCase(Locale.ROOT);
}
/**
* ECMA 15.5.4.19 String.prototype.toLocaleUpperCase ( )
* @param self self reference
* @return string to locale sensitive upper case
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String toLocaleUpperCase(final Object self) {
return checkObjectToString(self).toUpperCase(Global.getEnv()._locale);
}
/**
* ECMA 15.5.4.20 String.prototype.trim ( )
* @param self self reference
* @return string trimmed from whitespace
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String trim(final Object self) {
final String str = checkObjectToString(self);
int start = 0;
int end = str.length() - 1;
while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
start++;
}
while (end > start && ScriptRuntime.isJSWhitespace(str.charAt(end))) {
end--;
}
return str.substring(start, end + 1);
}
/**
* Nashorn extension: String.prototype.trimLeft ( )
* @param self self reference
* @return string trimmed left from whitespace
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String trimLeft(final Object self) {
final String str = checkObjectToString(self);
int start = 0;
final int end = str.length() - 1;
while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
start++;
}
return str.substring(start, end + 1);
}
/**
* Nashorn extension: String.prototype.trimRight ( )
* @param self self reference
* @return string trimmed right from whitespace
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static String trimRight(final Object self) {
final String str = checkObjectToString(self);
final int start = 0;
int end = str.length() - 1;
while (end >= start && ScriptRuntime.isJSWhitespace(str.charAt(end))) {
end--;
}
return str.substring(start, end + 1);
}
private static ScriptObject newObj(final CharSequence str) {
return new NativeString(str);
}
/**
* ECMA 15.5.2.1 new String ( [ value ] )
*
* Constructor
*
* @param newObj is this constructor invoked with the new operator
* @param self self reference
* @param args arguments (a value)
*
* @return new NativeString, empty string if no args, extraneous args ignored
*/
@Constructor(arity = 1)
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
final CharSequence str = args.length > 0 ? JSType.toCharSequence(args[0]) : "";
return newObj ? newObj(str) : str.toString();
}
/**
* ECMA 15.5.2.1 new String ( [ value ] ) - special version with no args
*
* Constructor
*
* @param newObj is this constructor invoked with the new operator
* @param self self reference
*
* @return new NativeString ("")
*/
@SpecializedFunction(isConstructor=true)
public static Object constructor(final boolean newObj, final Object self) {
return newObj ? newObj("") : "";
}
/**
* ECMA 15.5.2.1 new String ( [ value ] ) - special version with one arg
*
* Constructor
*
* @param newObj is this constructor invoked with the new operator
* @param self self reference
* @param arg argument
*
* @return new NativeString (arg)
*/
@SpecializedFunction(isConstructor=true)
public static Object constructor(final boolean newObj, final Object self, final Object arg) {
final CharSequence str = JSType.toCharSequence(arg);
return newObj ? newObj(str) : str.toString();
}
/**
* ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code int} arg
*
* Constructor
*
* @param newObj is this constructor invoked with the new operator
* @param self self reference
* @param arg the arg
*
* @return new NativeString containing the string representation of the arg
*/
@SpecializedFunction(isConstructor=true)
public static Object constructor(final boolean newObj, final Object self, final int arg) {
final String str = Integer.toString(arg);
return newObj ? newObj(str) : str;
}
/**
* ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code double} arg
*
* Constructor
*
* @param newObj is this constructor invoked with the new operator
* @param self self reference
* @param arg the arg
*
* @return new NativeString containing the string representation of the arg
*/
@SpecializedFunction(isConstructor=true)
public static Object constructor(final boolean newObj, final Object self, final double arg) {
final String str = JSType.toString(arg);
return newObj ? newObj(str) : str;
}
/**
* ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code boolean} arg
*
* Constructor
*
* @param newObj is this constructor invoked with the new operator
* @param self self reference
* @param arg the arg
*
* @return new NativeString containing the string representation of the arg
*/
@SpecializedFunction(isConstructor=true)
public static Object constructor(final boolean newObj, final Object self, final boolean arg) {
final String str = Boolean.toString(arg);
return newObj ? newObj(str) : str;
}
/**
* ECMA 6 21.1.3.27 String.prototype [ @@iterator ]( )
*
* @param self self reference
* @return a string iterator
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
public static Object getIterator(final Object self) {
return new StringIterator(checkObjectToString(self), Global.instance());
}
/**
* Lookup the appropriate method for an invoke dynamic call.
*
* @param request the link request
* @param receiver receiver of call
* @return Link to be invoked at call site.
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
return PrimitiveLookup.lookupPrimitive(request, NashornGuards.getStringGuard(),
new NativeString((CharSequence)receiver), WRAPFILTER, PROTOFILTER);
}
@SuppressWarnings("unused")
private static NativeString wrapFilter(final Object receiver) {
return new NativeString((CharSequence)receiver);
}
@SuppressWarnings("unused")
private static Object protoFilter(final Object object) {
return Global.instance().getStringPrototype();
}
private static CharSequence getCharSequence(final Object self) {
if (JSType.isString(self)) {
return (CharSequence)self;
} else if (self instanceof NativeString) {
return ((NativeString)self).getValue();
} else if (self != null && self == Global.instance().getStringPrototype()) {
return "";
} else {
throw typeError("not.a.string", ScriptRuntime.safeToString(self));
}
}
private static String getString(final Object self) {
if (self instanceof String) {
return (String)self;
} else if (self instanceof ConsString) {
return self.toString();
} else if (self instanceof NativeString) {
return ((NativeString)self).getStringValue();
} else if (self != null && self == Global.instance().getStringPrototype()) {
return "";
} else {
throw typeError("not.a.string", ScriptRuntime.safeToString(self));
}
}
/**
* Combines ECMA 9.10 CheckObjectCoercible and ECMA 9.8 ToString with a shortcut for strings.
*
* @param self the object
* @return the object as string
*/
private static String checkObjectToString(final Object self) {
if (self instanceof String) {
return (String)self;
} else if (self instanceof ConsString) {
return self.toString();
} else {
Global.checkObjectCoercible(self);
return JSType.toString(self);
}
}
private boolean isValidStringIndex(final int key) {
return key >= 0 && key < value.length();
}
private static MethodHandle findOwnMH(final String name, final MethodType type) {
return MH.findStatic(MethodHandles.lookup(), NativeString.class, name, type);
}
@Override
public LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz) {
if (clazz == CharCodeAtLinkLogic.class) {
return CharCodeAtLinkLogic.INSTANCE;
}
return null;
}
@Override
public boolean hasPerInstanceAssumptions() {
return false;
}
/**
* This is linker logic charCodeAt - when we specialize further methods in NativeString
* It may be expanded. It's link check makes sure that we are dealing with a char
* sequence and that we are in range
*/
private static final class CharCodeAtLinkLogic extends SpecializedFunction.LinkLogic {
private static final CharCodeAtLinkLogic INSTANCE = new CharCodeAtLinkLogic();
@Override
public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
try {
//check that it's a char sequence or throw cce
final CharSequence cs = (CharSequence)self;
//check that the index, representable as an int, is inside the array
final int intIndex = JSType.toInteger(request.getArguments()[2]);
return intIndex >= 0 && intIndex < cs.length(); //can link
} catch (final ClassCastException | IndexOutOfBoundsException e) {
//fallthru
}
return false;
}
/**
* charCodeAt callsites can throw ClassCastException as a mechanism to have them
* relinked - this enabled fast checks of the kind of ((IntArrayData)arrayData).push(x)
* for an IntArrayData only push - if this fails, a CCE will be thrown and we will relink
*/
@Override
public Class<? extends Throwable> getRelinkException() {
return ClassCastException.class;
}
}
}
⏎ jdk/nashorn/internal/objects/NativeString.java
Or download all of them as a single archive file:
File name: jdk.scripting.nashorn-11.0.1-src.zip File size: 1390965 bytes Release date: 2018-11-04 Download
⇒ JDK 11 jdk.scripting.nashorn.shell.jmod - Scripting Nashorn Shell Module
2020-04-25, ≈306🔥, 0💬
Popular Posts:
JRE 8 deploy.jar is the JAR file for JRE 8 Java Control Panel and other deploy tools. JRE (Java Runt...
ANTLR is a powerful parser generator for multiple programming languages including Java. ANTLR contai...
Java-WebSocket Source Code Files are provided in the source package file, java-websocket-1.5.4-src .z...
What Is HttpComponents httpclient-4.2.2.jar? HttpComponents httpclient-4.2.2.jar is the JAR file for...
commons-io-2.6-sources.j aris the source JAR file for Apache Commons IO 2.6, which is a library of u...