25 |
25 |
26 package jdk.nashorn.internal.ir; |
26 package jdk.nashorn.internal.ir; |
27 |
27 |
28 import java.util.Collections; |
28 import java.util.Collections; |
29 import java.util.List; |
29 import java.util.List; |
|
30 import java.util.RandomAccess; |
30 import jdk.nashorn.internal.codegen.types.Type; |
31 import jdk.nashorn.internal.codegen.types.Type; |
31 import jdk.nashorn.internal.ir.annotations.Immutable; |
32 import jdk.nashorn.internal.ir.annotations.Immutable; |
32 import jdk.nashorn.internal.ir.visitor.NodeVisitor; |
33 import jdk.nashorn.internal.ir.visitor.NodeVisitor; |
33 |
34 |
34 /** |
35 /** |
35 * IR representation of an object literal. |
36 * IR representation of an object literal. |
36 */ |
37 */ |
37 @Immutable |
38 @Immutable |
38 public final class ObjectNode extends Expression { |
39 public final class ObjectNode extends Expression implements LexicalContextNode, Splittable { |
39 private static final long serialVersionUID = 1L; |
40 private static final long serialVersionUID = 1L; |
40 |
41 |
41 /** Literal elements. */ |
42 /** Literal elements. */ |
42 private final List<PropertyNode> elements; |
43 private final List<PropertyNode> elements; |
|
44 |
|
45 /** Ranges for splitting large literals over multiple compile units in codegen. */ |
|
46 private final List<Splittable.SplitRange> splitRanges; |
43 |
47 |
44 /** |
48 /** |
45 * Constructor |
49 * Constructor |
46 * |
50 * |
47 * @param token token |
51 * @param token token |
49 * @param elements the elements used to initialize this ObjectNode |
53 * @param elements the elements used to initialize this ObjectNode |
50 */ |
54 */ |
51 public ObjectNode(final long token, final int finish, final List<PropertyNode> elements) { |
55 public ObjectNode(final long token, final int finish, final List<PropertyNode> elements) { |
52 super(token, finish); |
56 super(token, finish); |
53 this.elements = elements; |
57 this.elements = elements; |
|
58 this.splitRanges = null; |
|
59 assert elements instanceof RandomAccess : "Splitting requires random access lists"; |
54 } |
60 } |
55 |
61 |
56 private ObjectNode(final ObjectNode objectNode, final List<PropertyNode> elements) { |
62 private ObjectNode(final ObjectNode objectNode, final List<PropertyNode> elements, |
|
63 final List<Splittable.SplitRange> splitRanges ) { |
57 super(objectNode); |
64 super(objectNode); |
58 this.elements = elements; |
65 this.elements = elements; |
|
66 this.splitRanges = splitRanges; |
59 } |
67 } |
60 |
68 |
61 @Override |
69 @Override |
62 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { |
70 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { |
|
71 return Acceptor.accept(this, visitor); |
|
72 } |
|
73 |
|
74 @Override |
|
75 public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) { |
63 if (visitor.enterObjectNode(this)) { |
76 if (visitor.enterObjectNode(this)) { |
64 return visitor.leaveObjectNode(setElements(Node.accept(visitor, elements))); |
77 return visitor.leaveObjectNode(setElements(lc, Node.accept(visitor, elements))); |
65 } |
78 } |
66 |
|
67 return this; |
79 return this; |
68 } |
80 } |
69 |
81 |
70 @Override |
82 @Override |
71 public Type getType() { |
83 public Type getType() { |
100 */ |
112 */ |
101 public List<PropertyNode> getElements() { |
113 public List<PropertyNode> getElements() { |
102 return Collections.unmodifiableList(elements); |
114 return Collections.unmodifiableList(elements); |
103 } |
115 } |
104 |
116 |
105 private ObjectNode setElements(final List<PropertyNode> elements) { |
117 private ObjectNode setElements(final LexicalContext lc, final List<PropertyNode> elements) { |
106 if (this.elements == elements) { |
118 if (this.elements == elements) { |
107 return this; |
119 return this; |
108 } |
120 } |
109 return new ObjectNode(this, elements); |
121 return Node.replaceInLexicalContext(lc, this, new ObjectNode(this, elements, this.splitRanges)); |
110 } |
122 } |
|
123 |
|
124 /** |
|
125 * Set the split ranges for this ObjectNode |
|
126 * @see Splittable.SplitRange |
|
127 * @param lc the lexical context |
|
128 * @param splitRanges list of split ranges |
|
129 * @return new or changed object node |
|
130 */ |
|
131 public ObjectNode setSplitRanges(final LexicalContext lc, final List<Splittable.SplitRange> splitRanges) { |
|
132 if (this.splitRanges == splitRanges) { |
|
133 return this; |
|
134 } |
|
135 return Node.replaceInLexicalContext(lc, this, new ObjectNode(this, elements, splitRanges)); |
|
136 } |
|
137 |
|
138 /** |
|
139 * Get the split ranges for this ObjectNode, or null if the object is not split. |
|
140 * @see Splittable.SplitRange |
|
141 * @return list of split ranges |
|
142 */ |
|
143 @Override |
|
144 public List<Splittable.SplitRange> getSplitRanges() { |
|
145 return splitRanges == null ? null : Collections.unmodifiableList(splitRanges); |
|
146 } |
|
147 |
111 } |
148 } |