Skip to content

Commit a8bd87b

Browse files
tonygermanogbrail
authored andcommitted
Implement String.raw
1 parent 1360ddd commit a8bd87b

3 files changed

Lines changed: 59 additions & 21 deletions

File tree

src/org/mozilla/javascript/NativeString.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ protected Object getInstanceIdValue(int id) {
8181
protected void fillConstructorProperties(IdFunctionObject ctor) {
8282
addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_fromCharCode, "fromCharCode", 1);
8383
addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_fromCodePoint, "fromCodePoint", 1);
84+
addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_raw, "raw", 1);
8485
addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_charAt, "charAt", 2);
8586
addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_charCodeAt, "charCodeAt", 2);
8687
addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_indexOf, "indexOf", 2);
@@ -393,6 +394,9 @@ public Object execIdCall(
393394
return new String(chars);
394395
}
395396

397+
case ConstructorId_raw:
398+
return js_raw(cx, scope, args);
399+
396400
case Id_constructor:
397401
{
398402
CharSequence s;
@@ -1106,6 +1110,47 @@ protected int findPrototypeId(Symbol k) {
11061110
return 0;
11071111
}
11081112

1113+
/**
1114+
*
1115+
*
1116+
* <h1>String.raw (template, ...substitutions)</h1>
1117+
*
1118+
* <p>22.1.2.4 String.raw [Draft ECMA-262 / April 28, 2021]
1119+
*/
1120+
private static CharSequence js_raw(Context cx, Scriptable scope, Object[] args) {
1121+
/* step 1-2 */
1122+
Object arg0 = args.length > 0 ? args[0] : Undefined.instance;
1123+
Scriptable cooked = ScriptRuntime.toObject(cx, scope, arg0);
1124+
/* step 3 */
1125+
Object rawValue = ScriptRuntime.getObjectProp(cooked, "raw", cx);
1126+
Scriptable raw = ScriptRuntime.toObject(cx, scope, rawValue);
1127+
/* step 4-5 */
1128+
long rawLength = NativeArray.getLengthProperty(cx, raw);
1129+
if (rawLength > Integer.MAX_VALUE) {
1130+
throw ScriptRuntime.rangeError("raw.length > " + Integer.toString(Integer.MAX_VALUE));
1131+
}
1132+
int literalSegments = (int) rawLength;
1133+
if (literalSegments <= 0) return "";
1134+
/* step 6-7 */
1135+
StringBuilder elements = new StringBuilder();
1136+
int nextIndex = 0;
1137+
for (; ; ) {
1138+
/* step 8 a-i */
1139+
Object next;
1140+
next = ScriptRuntime.getObjectIndex(raw, nextIndex, cx);
1141+
String nextSeg = ScriptRuntime.toString(next);
1142+
elements.append(nextSeg);
1143+
nextIndex += 1;
1144+
if (nextIndex == literalSegments) {
1145+
break;
1146+
}
1147+
next = args.length > nextIndex ? args[nextIndex] : "";
1148+
String nextSub = ScriptRuntime.toString(next);
1149+
elements.append(nextSub);
1150+
}
1151+
return elements;
1152+
}
1153+
11091154
// #string_id_map#
11101155

11111156
@Override
@@ -1270,6 +1315,7 @@ protected int findPrototypeId(String s) {
12701315

12711316
private static final int ConstructorId_fromCharCode = -1,
12721317
ConstructorId_fromCodePoint = -2,
1318+
ConstructorId_raw = -3,
12731319
Id_constructor = 1,
12741320
Id_toString = 2,
12751321
Id_toSource = 3,

testsrc/jstests/es6/string.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,16 @@ load("testsrc/assert.js");
3737
assertEquals(" abc", " abc ".trimRight())
3838
})();
3939

40-
"success";
40+
(function TestRawTooLarge() {
41+
assertThrows(()=>String.raw({raw: {length: Math.pow(2, 31) + 1}}), RangeError);
42+
})();
43+
44+
(function TestRawPrototypeGet() {
45+
var _raw = ["1",,"3"];
46+
var raw = Object.create(_raw);
47+
raw[2] = "2*";
48+
raw.length = 4;
49+
assertEquals("1.undefined^2*undefined", String.raw(Object.create({raw}), ".", "^"));
50+
})();
51+
52+
"success";

testsrc/test262.properties

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,28 +1101,8 @@ built-ins/String
11011101
! prototype/trimStart/this-value-object-valueof-meth-err.js
11021102
! prototype/trimStart/this-value-object-valueof-meth-priority.js
11031103
! prototype/trimStart/this-value-object-valueof-returns-object-err.js
1104-
! raw/length.js
1105-
! raw/name.js
1106-
! raw/raw.js
1107-
! raw/return-empty-string-from-empty-array-length.js
1108-
! raw/return-empty-string-if-length-is-negative-infinity.js
1109-
! raw/return-empty-string-if-length-is-not-defined.js
1110-
! raw/return-empty-string-if-length-is-undefined.js
1111-
! raw/return-empty-string-if-length-is-zero-boolean.js
1112-
! raw/return-empty-string-if-length-is-zero-NaN.js
1113-
! raw/return-empty-string-if-length-is-zero-null.js
1114-
! raw/return-empty-string-if-length-is-zero-or-less-number.js
1115-
! raw/return-empty-string-if-length-is-zero-or-less-string.js
11161104
! raw/return-the-string-value-from-template.js
1117-
! raw/return-the-string-value.js
1118-
! raw/returns-abrupt-from-next-key-toString.js
1119-
! raw/returns-abrupt-from-next-key.js
1120-
! raw/returns-abrupt-from-substitution.js
11211105
! raw/special-characters.js
1122-
! raw/substitutions-are-appended-on-same-index.js
1123-
! raw/substitutions-are-limited-to-template-raw-length.js
1124-
! raw/template-length-throws.js
1125-
! raw/template-raw-throws.js
11261106
! raw/template-substitutions-are-appended-on-same-index.js
11271107
! raw/zero-literal-segments.js
11281108

0 commit comments

Comments
 (0)