forked from mozilla/rhino
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathES6Iterator.java
More file actions
145 lines (123 loc) · 4.8 KB
/
Copy pathES6Iterator.java
File metadata and controls
145 lines (123 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.javascript;
public abstract class ES6Iterator extends IdScriptableObject {
private static final long serialVersionUID = 2438373029140003950L;
static void init(ScriptableObject scope, boolean sealed, IdScriptableObject prototype, String tag) {
if (scope != null) {
prototype.setParentScope(scope);
prototype.setPrototype(getObjectPrototype(scope));
}
prototype.activatePrototypeMap(MAX_PROTOTYPE_ID);
if (sealed) {
prototype.sealObject();
}
// Need to access Iterator prototype when constructing
// Iterator instances, but don't have a iterator constructor
// to use to find the prototype. Use the "associateValue"
// approach instead.
if (scope != null) {
scope.associateValue(tag, prototype);
}
}
protected boolean exhausted = false;
private String tag;
ES6Iterator() {}
ES6Iterator(Scriptable scope, String tag) {
// Set parent and prototype properties. Since we don't have a
// "Iterator" constructor in the top scope, we stash the
// prototype in the top scope's associated value.
this.tag = tag;
Scriptable top = ScriptableObject.getTopLevelScope(scope);
this.setParentScope(top);
IdScriptableObject prototype = (IdScriptableObject)
ScriptableObject.getTopScopeValue(top, tag);
setPrototype(prototype);
}
@Override
protected void initPrototypeId(int id)
{
switch (id) {
case Id_next:
initPrototypeMethod(getTag(), id, NEXT_METHOD, 0);
return;
case SymbolId_iterator:
initPrototypeMethod(getTag(), id, SymbolKey.ITERATOR, "[Symbol.iterator]", DONTENUM | READONLY);
return;
case SymbolId_toStringTag:
initPrototypeValue(SymbolId_toStringTag, SymbolKey.TO_STRING_TAG, getClassName(), DONTENUM | READONLY);
return;
default: throw new IllegalArgumentException(String.valueOf(id));
}
}
@Override
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (!f.hasTag(getTag())) {
return super.execIdCall(f, cx, scope, thisObj, args);
}
int id = f.methodId();
if (!(thisObj instanceof ES6Iterator))
throw incompatibleCallError(f);
ES6Iterator iterator = (ES6Iterator) thisObj;
switch (id) {
case Id_next:
return iterator.next(cx, scope);
case SymbolId_iterator:
return iterator;
default:
throw new IllegalArgumentException(String.valueOf(id));
}
}
@Override
protected int findPrototypeId(Symbol k) {
if (SymbolKey.ITERATOR.equals(k)) {
return SymbolId_iterator;
} else if (SymbolKey.TO_STRING_TAG.equals(k)) {
return SymbolId_toStringTag;
}
return 0;
}
@Override
protected int findPrototypeId(String s) {
if ("next".equals(s)) {
return Id_next;
}
return 0;
}
abstract protected boolean isDone(Context cx, Scriptable scope);
abstract protected Object nextValue(Context cx, Scriptable scope);
protected Object next(Context cx, Scriptable scope) {
Object value = Undefined.instance;
boolean done = isDone(cx, scope) || this.exhausted;
if (!done) {
value = nextValue(cx, scope);
} else {
this.exhausted = true;
}
return makeIteratorResult(cx, scope, done, value);
}
protected String getTag() {
return tag;
}
// 25.1.1.3 The IteratorResult Interface
private Scriptable makeIteratorResult(Context cx, Scriptable scope, boolean done, Object value) {
Scriptable iteratorResult = cx.newObject(scope);
ScriptableObject.putProperty(iteratorResult, VALUE_PROPERTY, value);
ScriptableObject.putProperty(iteratorResult, DONE_PROPERTY, done);
return iteratorResult;
}
private static final int
Id_next = 1,
SymbolId_iterator = 2,
SymbolId_toStringTag = 3,
MAX_PROTOTYPE_ID = SymbolId_toStringTag;
public static final String NEXT_METHOD = "next";
public static final String DONE_PROPERTY = "done";
public static final String RETURN_PROPERTY = "return";
public static final String VALUE_PROPERTY = "value";
}