Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: plugins/org.chromium.sdk.wipbackend.wk118685/src/org/chromium/sdk/internal/wip/WipValueBuilder.java

Issue 11829027: drop old backends (Closed) Base URL: https://chromedevtools.googlecode.com/svn/trunk
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.sdk.internal.wip;
6
7 import static org.chromium.sdk.util.BasicUtil.getSafe;
8
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.SortedMap;
16 import java.util.TreeMap;
17 import java.util.concurrent.atomic.AtomicReference;
18 import java.util.logging.Logger;
19
20 import org.chromium.sdk.FunctionScopeExtension;
21 import org.chromium.sdk.JsArray;
22 import org.chromium.sdk.JsEvaluateContext.EvaluateCallback;
23 import org.chromium.sdk.JsFunction;
24 import org.chromium.sdk.JsObject;
25 import org.chromium.sdk.JsObjectProperty;
26 import org.chromium.sdk.JsScope;
27 import org.chromium.sdk.JsValue;
28 import org.chromium.sdk.JsValue.Type;
29 import org.chromium.sdk.JsVariable;
30 import org.chromium.sdk.RelayOk;
31 import org.chromium.sdk.Script;
32 import org.chromium.sdk.SyncCallback;
33 import org.chromium.sdk.TextStreamPosition;
34 import org.chromium.sdk.internal.wip.WipExpressionBuilder.ObjectPropertyNameBuil der;
35 import org.chromium.sdk.internal.wip.WipExpressionBuilder.PropertyNameBuilder;
36 import org.chromium.sdk.internal.wip.WipExpressionBuilder.QualifiedNameBuilder;
37 import org.chromium.sdk.internal.wip.WipExpressionBuilder.ValueNameBuilder;
38 import org.chromium.sdk.internal.wip.WipValueLoader.Getter;
39 import org.chromium.sdk.internal.wip.WipValueLoader.ObjectProperties;
40 import org.chromium.sdk.internal.wip.protocol.input.debugger.FunctionDetailsValu e;
41 import org.chromium.sdk.internal.wip.protocol.input.debugger.LocationValue;
42 import org.chromium.sdk.internal.wip.protocol.input.debugger.ScopeValue;
43 import org.chromium.sdk.internal.wip.protocol.input.runtime.PropertyDescriptorVa lue;
44 import org.chromium.sdk.internal.wip.protocol.input.runtime.RemoteObjectValue;
45 import org.chromium.sdk.internal.wip.protocol.output.runtime.CallArgumentParam;
46 import org.chromium.sdk.util.AsyncFutureRef;
47 import org.chromium.sdk.util.JavaScriptExpressionBuilder;
48 import org.chromium.sdk.util.MethodIsBlockingException;
49
50 /**
51 * A builder for implementations of {@link JsValue} and {@link JsVariable}.
52 * It works in pair with {@link WipValueLoader}.
53 */
54 class WipValueBuilder {
55 private static final Logger LOGGER = Logger.getLogger(WipValueBuilder.class.ge tName());
56
57 private final WipValueLoader valueLoader;
58
59 WipValueBuilder(WipValueLoader valueLoader) {
60 this.valueLoader = valueLoader;
61 }
62
63 /**
64 * Value that can serialize itself for sending back to server.
65 */
66 interface SerializableValue {
67 CallArgumentParam createCallArgumentParam();
68 /**
69 * Ref id is directly used in {@link EvaluateHack} because sometimes protoco l requires
70 * it for CallFunctionOn.
71 * @return ref id or null
72 */
73 String getRefId();
74
75 class Util {
76 public static SerializableValue wrapRefId(final String refId) {
77 return new SerializableValue() {
78 @Override public CallArgumentParam createCallArgumentParam() {
79 return new CallArgumentParam(false, null, refId);
80 }
81 @Override public String getRefId() {
82 return refId;
83 }
84 };
85 }
86 }
87 }
88
89 static abstract class JsValueBase implements JsValue, SerializableValue {
90 static JsValueBase cast(JsValue value) {
91 if (false == value instanceof JsValueBase) {
92 throw new IllegalArgumentException("Incorrect argument type " + value.ge tClass());
93 }
94 return (JsValueBase) value;
95 }
96 }
97
98 public JsObjectProperty createObjectProperty(final PropertyDescriptorValue pro pertyDescriptor,
99 final String hostObjectRefId, ValueNameBuilder nameBuilder) {
100 final QualifiedNameBuilder qualifiedNameBuilder = nameBuilder.getQualifiedNa meBuilder();
101 JsValue jsValue = wrap(propertyDescriptor.value(), qualifiedNameBuilder);
102
103 final JsValue getter = wrapPropertyDescriptorFunction(propertyDescriptor.get (),
104 qualifiedNameBuilder, "getter");
105
106 final JsValue setter = wrapPropertyDescriptorFunction(propertyDescriptor.set (),
107 qualifiedNameBuilder, "setter");
108
109 return new ObjectPropertyBase(jsValue, nameBuilder) {
110 @Override public boolean isWritable() {
111 return propertyDescriptor.writable();
112 }
113 @Override public JsValue getGetter() {
114 return getter;
115 }
116 @Override public JsValue getSetter() {
117 return setter;
118 }
119 @Override public boolean isConfigurable() {
120 return propertyDescriptor.configurable();
121 }
122 @Override public boolean isEnumerable() {
123 return propertyDescriptor.enumerable();
124 }
125
126 @Override
127 public JsFunction getGetterAsFunction() {
128 JsObject getterObject = getter.asObject();
129 if (getterObject == null) {
130 return null;
131 }
132 return getterObject.asFunction();
133 }
134
135 @Override
136 public RelayOk evaluateGet(EvaluateCallback callback, SyncCallback syncCal lback) {
137 WipContextBuilder.GlobalEvaluateContext evaluateContext =
138 new WipContextBuilder.GlobalEvaluateContext(valueLoader);
139
140 JsFunction getterFunction = getGetterAsFunction();
141 if (getterFunction == null) {
142 throw new RuntimeException("Getter is not a function");
143 }
144
145 Map<String, SerializableValue> context = new HashMap<String, Serializabl eValue>(2);
146 context.put(GETTER_VAR_NAME, (SerializableValue) getterFunction);
147 context.put(OBJECT_VAR_NAME, SerializableValue.Util.wrapRefId(hostObject RefId));
148 final QualifiedNameBuilder pseudoPropertyNameBuilder =
149 createPseudoPropertyNameBuilder(qualifiedNameBuilder, "value");
150 ValueNameBuilder valueNameBuilder = new ValueNameBuilder() {
151 @Override
152 public String getShortName() {
153 return "value";
154 }
155
156 @Override
157 public QualifiedNameBuilder getQualifiedNameBuilder() {
158 return pseudoPropertyNameBuilder;
159 }
160 };
161
162 return evaluateContext.evaluateAsyncImpl(EVALUATE_EXPRESSION, valueNameB uilder,
163 context, valueLoader, callback, syncCallback);
164 }
165 private static final String GETTER_VAR_NAME = "gttr";
166 private static final String OBJECT_VAR_NAME = "obj";
167 private static final String EVALUATE_EXPRESSION =
168 GETTER_VAR_NAME + ".call(" + OBJECT_VAR_NAME + ")";
169 };
170 }
171
172 private static QualifiedNameBuilder createPseudoPropertyNameBuilder(
173 final QualifiedNameBuilder propertyValueNameBuilder, final String symbolic Name) {
174 return new QualifiedNameBuilder() {
175 @Override public boolean needsParentheses() {
176 return false;
177 }
178
179 @Override
180 public void append(StringBuilder output) {
181 propertyValueNameBuilder.append(output);
182 output.append("::[[").append(symbolicName).append("]]");
183 }
184 };
185 }
186
187 private JsValue wrapPropertyDescriptorFunction(RemoteObjectValue value,
188 QualifiedNameBuilder propertyValueNameBuilder, String symbolicName) {
189 if (value == null) {
190 return null;
191 }
192
193 QualifiedNameBuilder qualifiedNameBuilder =
194 createPseudoPropertyNameBuilder(propertyValueNameBuilder, symbolicName);
195
196 return wrap(value, qualifiedNameBuilder);
197 }
198
199 public JsVariable createVariable(RemoteObjectValue valueData, ValueNameBuilder nameBuilder) {
200 QualifiedNameBuilder qualifiedNameBuilder;
201 if (nameBuilder == null) {
202 qualifiedNameBuilder = null;
203 } else {
204 qualifiedNameBuilder = nameBuilder.getQualifiedNameBuilder();
205 }
206 JsValue jsValue = wrap(valueData, qualifiedNameBuilder);
207 return createVariable(jsValue, nameBuilder);
208 }
209
210 public JsValue wrap(RemoteObjectValue valueData, QualifiedNameBuilder nameBuil der) {
211 if (valueData == null) {
212 return null;
213 }
214 return getValueType(valueData).build(valueData, valueLoader, nameBuilder);
215 }
216
217 public static JsVariable createVariable(JsValue jsValue,
218 ValueNameBuilder nameBuilder) {
219 return new VariableImpl(jsValue, nameBuilder);
220 }
221
222 private static ValueType getValueType(RemoteObjectValue valueData) {
223 RemoteObjectValue.Type protocolType = valueData.type();
224 ValueType result = getSafe(PROTOCOL_TYPE_TO_VALUE_TYPE, protocolType);
225
226 if (result == null) {
227 LOGGER.severe("Unexpected value type: " + protocolType);
228 result = DEFAULT_VALUE_TYPE;
229 }
230 return result;
231 }
232
233 private static abstract class ValueType {
234 abstract JsValue build(RemoteObjectValue valueData, WipValueLoader valueLoad er,
235 QualifiedNameBuilder qualifiedNameBuilder);
236 }
237
238 private static abstract class PrimitiveType extends ValueType {
239 private final JsValue.Type jsValueType;
240
241 PrimitiveType(JsValue.Type jsValueType) {
242 this.jsValueType = jsValueType;
243 }
244
245 protected abstract String getValueString(RemoteObjectValue valueData);
246
247 @Override
248 JsValue build(RemoteObjectValue valueData, WipValueLoader valueLoader,
249 QualifiedNameBuilder qualifiedNameBuilder) {
250 final Object value = valueData.value();
251 final String valueString = getValueString(valueData);
252 return new JsValueBase() {
253 @Override public Type getType() {
254 return jsValueType;
255 }
256 @Override public String getValueString() {
257 return valueString;
258 }
259 @Override public JsObject asObject() {
260 return null;
261 }
262 @Override public boolean isTruncated() {
263 return false;
264 }
265 @Override public String getRefId() {
266 return null;
267 }
268 @Override public RelayOk reloadHeavyValue(ReloadBiggerCallback callback,
269 SyncCallback syncCallback) {
270 throw new UnsupportedOperationException();
271 }
272 @Override
273 public CallArgumentParam createCallArgumentParam() {
274 if (jsValueType == JsValue.Type.TYPE_NULL) {
275 return new CallArgumentParam(true, null, null);
276 } else if (jsValueType == JsValue.Type.TYPE_UNDEFINED) {
277 return new CallArgumentParam(false, null, null);
278 } else {
279 return new CallArgumentParam(true, value, null);
280 }
281 }
282 };
283 }
284 }
285
286 private static class SingletonPrimitiveType extends PrimitiveType {
287 private final String stringValue;
288
289 SingletonPrimitiveType(Type jsValueType, String stringValue) {
290 super(jsValueType);
291 this.stringValue = stringValue;
292 }
293
294 @Override
295 protected String getValueString(RemoteObjectValue valueData) {
296 return stringValue;
297 }
298 }
299
300 private static class PrimitiveTypeWithDescription extends PrimitiveType {
301 PrimitiveTypeWithDescription(Type jsValueType) {
302 super(jsValueType);
303 }
304
305 @Override
306 protected String getValueString(RemoteObjectValue valueData) {
307 return valueData.description();
308 }
309 }
310
311 private static class PrimitiveTypeWithValue extends PrimitiveType {
312 PrimitiveTypeWithValue(Type jsValueType) {
313 super(jsValueType);
314 }
315
316 @Override
317 protected String getValueString(RemoteObjectValue valueData) {
318 return valueData.value().toString();
319 }
320 }
321
322
323 private static abstract class ObjectTypeBase extends ValueType {
324 private final JsValue.Type jsValueType;
325
326 ObjectTypeBase(Type jsValueType) {
327 this.jsValueType = jsValueType;
328 }
329
330 @Override
331 JsValue build(RemoteObjectValue valueData, WipValueLoader valueLoader,
332 QualifiedNameBuilder qualifiedNameBuilder) {
333 // TODO: Implement caching here.
334 return buildNewInstance(valueData, valueLoader, qualifiedNameBuilder);
335 }
336
337 abstract JsValue buildNewInstance(RemoteObjectValue valueData, WipValueLoade r valueLoader,
338 QualifiedNameBuilder qualifiedNameBuilder);
339
340 abstract class JsObjectBase extends JsValueBase implements JsObject {
341 private final RemoteObjectValue valueData;
342 private final WipValueLoader valueLoader;
343 private final QualifiedNameBuilder nameBuilder;
344 private final AsyncFutureRef<Getter<ObjectProperties>> loadedPropertiesRef =
345 new AsyncFutureRef<Getter<ObjectProperties>>();
346
347 JsObjectBase(RemoteObjectValue valueData, WipValueLoader valueLoader,
348 QualifiedNameBuilder nameBuilder) {
349 this.valueData = valueData;
350 this.valueLoader = valueLoader;
351 this.nameBuilder = nameBuilder;
352 }
353
354 @Override
355 public Type getType() {
356 return jsValueType;
357 }
358
359 @Override
360 public String getValueString() {
361 return valueData.description();
362 }
363
364 @Override
365 public JsObject asObject() {
366 return this;
367 }
368
369 @Override
370 public boolean isTruncated() {
371 return false;
372 }
373
374 @Override
375 public String getClassName() {
376 return valueData.className();
377 }
378
379 @Override
380 public RelayOk reloadHeavyValue(ReloadBiggerCallback callback,
381 SyncCallback syncCallback) {
382 throw new UnsupportedOperationException();
383 }
384
385 @Override
386 public Collection<? extends JsObjectProperty> getProperties()
387 throws MethodIsBlockingException {
388 return getLoadedProperties().properties();
389 }
390
391 @Override
392 public Collection<? extends JsVariable> getInternalProperties()
393 throws MethodIsBlockingException {
394 return getLoadedProperties().internalProperties();
395 }
396
397 @Override
398 public JsVariable getProperty(String name) throws MethodIsBlockingExceptio n {
399 return getLoadedProperties().getProperty(name);
400 }
401
402 @Override
403 public String getRefId() {
404 return valueData.objectId();
405 }
406
407 @Override
408 public WipValueLoader getRemoteValueMapping() {
409 return valueLoader;
410 }
411
412 protected RemoteObjectValue getValueData() {
413 return valueData;
414 }
415
416 @Override
417 public CallArgumentParam createCallArgumentParam() {
418 return new CallArgumentParam(false, null, valueData.objectId());
419 }
420
421 protected ObjectProperties getLoadedProperties() throws MethodIsBlockingEx ception {
422 int currentCacheState = getRemoteValueMapping().getCacheState();
423 if (loadedPropertiesRef.isInitialized()) {
424 ObjectProperties result = loadedPropertiesRef.getSync().get();
425 if (currentCacheState == result.getCacheState()) {
426 return result;
427 }
428 doLoadProperties(true, currentCacheState);
429 } else {
430 doLoadProperties(false, currentCacheState);
431 }
432 return loadedPropertiesRef.getSync().get();
433 }
434
435 private void doLoadProperties(boolean reload, int currentCacheState)
436 throws MethodIsBlockingException {
437 PropertyNameBuilder innerNameBuilder;
438 if (nameBuilder == null) {
439 innerNameBuilder = null;
440 } else {
441 innerNameBuilder = new ObjectPropertyNameBuilder(nameBuilder);
442 }
443 valueLoader.loadJsObjectPropertiesInFuture(valueData.objectId(), innerNa meBuilder,
444 reload, currentCacheState, loadedPropertiesRef);
445 }
446 }
447 }
448
449 private static class ObjectSubtype extends ObjectTypeBase {
450 ObjectSubtype(JsValue.Type type) {
451 super(type);
452 }
453
454 @Override
455 JsValue buildNewInstance(RemoteObjectValue valueData, WipValueLoader valueLo ader,
456 QualifiedNameBuilder qualifiedNameBuilder) {
457 return new ObjectTypeBase.JsObjectBase(valueData, valueLoader, qualifiedNa meBuilder) {
458 @Override public JsArray asArray() {
459 return null;
460 }
461
462 @Override public JsFunction asFunction() {
463 return null;
464 }
465 };
466 }
467 }
468
469 private static class ArrayType extends ObjectTypeBase {
470 ArrayType() {
471 super(JsValue.Type.TYPE_ARRAY);
472 }
473
474 @Override
475 JsValue buildNewInstance(RemoteObjectValue valueData, WipValueLoader valueLo ader,
476 QualifiedNameBuilder nameBuilder) {
477 return new Array(valueData, valueLoader, nameBuilder);
478 }
479
480 private class Array extends JsObjectBase implements JsArray {
481 private final AtomicReference<ArrayProperties> arrayPropertiesRef =
482 new AtomicReference<ArrayProperties>(null);
483
484 Array(RemoteObjectValue valueData, WipValueLoader valueLoader,
485 QualifiedNameBuilder nameBuilder) {
486 super(valueData, valueLoader, nameBuilder);
487 }
488
489 @Override
490 public JsArray asArray() {
491 return this;
492 }
493
494 @Override
495 public JsFunction asFunction() {
496 return null;
497 }
498
499 @Override
500 public long getLength() throws MethodIsBlockingException {
501 return getArrayProperties().getLength();
502 }
503
504 @Override
505 public JsVariable get(long index) throws MethodIsBlockingException {
506 return getSafe(getArrayProperties().getSparseArrayMap(), index);
507 }
508
509 @Override
510 public SortedMap<Long, ? extends JsVariable> toSparseArray()
511 throws MethodIsBlockingException {
512 return getArrayProperties().getPublicSparseArrayMap();
513 }
514
515 private ArrayProperties getArrayProperties() throws MethodIsBlockingExcept ion {
516 ArrayProperties result = arrayPropertiesRef.get();
517 if (result == null) {
518 ArrayProperties arrayProperties = buildArrayProperties();
519 // Only set if concurrent thread hasn't set its version
520 arrayPropertiesRef.compareAndSet(null, arrayProperties);
521 return arrayPropertiesRef.get();
522 } else {
523 return result;
524 }
525 }
526
527 private ArrayProperties buildArrayProperties() throws MethodIsBlockingExce ption {
528 ObjectProperties loadedProperties = getLoadedProperties();
529 final TreeMap<Long, JsVariable> map = new TreeMap<Long, JsVariable>();
530 JsValue lengthValue = null;
531 for (JsVariable variable : loadedProperties.properties()) {
532 String name = variable.getName();
533 Long index = JavaScriptExpressionBuilder.parsePropertyNameAsArrayIndex (name);
534 if (index != null) {
535 map.put(index, variable);
536 } else if ("length".equals(name)) {
537 lengthValue = variable.getValue();
538 }
539 }
540 long length;
541 try {
542 length = Long.parseLong(lengthValue.getValueString());
543 } catch (NumberFormatException e) {
544 length = -1;
545 }
546 return new ArrayProperties(length, map);
547 }
548 }
549
550 private static class ArrayProperties {
551 final long length;
552 final SortedMap<Long, ? extends JsVariable> sparseArrayMap;
553 final SortedMap<Long, ? extends JsVariable> publicSparseArrayMap;
554
555 ArrayProperties(long length,
556 SortedMap<Long, ? extends JsVariable> sparseArrayMap) {
557 this.length = length;
558 this.sparseArrayMap = sparseArrayMap;
559 // We make public map synchronized, because unmodifiable map has its int ernal state.
560 this.publicSparseArrayMap = Collections.synchronizedSortedMap(
561 Collections.unmodifiableSortedMap(sparseArrayMap));
562 }
563 long getLength() {
564 return length;
565 }
566
567 SortedMap<Long, ? extends JsVariable> getSparseArrayMap() {
568 return sparseArrayMap;
569 }
570
571 SortedMap<Long, ? extends JsVariable> getPublicSparseArrayMap() {
572 return publicSparseArrayMap;
573 }
574 }
575 }
576
577 private static class FunctionType extends ObjectTypeBase {
578 FunctionType() {
579 super(JsValue.Type.TYPE_FUNCTION);
580 }
581
582 @Override
583 JsValue buildNewInstance(RemoteObjectValue valueData, WipValueLoader valueLo ader,
584 QualifiedNameBuilder nameBuilder) {
585 return new FunctionValueImpl(valueData, valueLoader, nameBuilder);
586 }
587
588 private class FunctionValueImpl extends ObjectTypeBase.JsObjectBase
589 implements JsFunction, FunctionScopeAccess {
590 private final AsyncFutureRef<Getter<FunctionDetailsValue>> loadedPositionR ef =
591 new AsyncFutureRef<Getter<FunctionDetailsValue>>();
592
593 FunctionValueImpl(RemoteObjectValue valueData,
594 WipValueLoader valueLoader, QualifiedNameBuilder nameBuilder) {
595 super(valueData, valueLoader, nameBuilder);
596 }
597
598 @Override public JsArray asArray() {
599 return null;
600 }
601
602 @Override public JsFunction asFunction() {
603 return this;
604 }
605
606 @Override
607 public Script getScript() throws MethodIsBlockingException {
608 FunctionDetailsValue functionDetails = getFunctionDetails();
609 WipScriptManager scriptManager = getRemoteValueMapping().getTabImpl().ge tScriptManager();
610 return scriptManager.getScript(functionDetails.location().scriptId());
611 }
612
613 @Override
614 public TextStreamPosition getOpenParenPosition()
615 throws MethodIsBlockingException {
616 final LocationValue functionPosition = getFunctionDetails().location();
617 return new TextStreamPosition() {
618 @Override public int getOffset() {
619 return WipBrowserImpl.throwUnsupported();
620 }
621
622 @Override public int getLine() {
623 return (int) functionPosition.lineNumber();
624 }
625
626 @Override
627 public int getColumn() {
628 Long columnObject = functionPosition.columnNumber();
629 if (columnObject == null) {
630 return NO_POSITION;
631 }
632 return columnObject.intValue();
633 }
634 };
635 }
636
637 @Override
638 public List<? extends JsScope> getScopes() {
639 List<ScopeValue> data = getFunctionDetails().scopeChain();
640 if (data == null) {
641 return Collections.emptyList();
642 }
643 List<JsScope> result = new ArrayList<JsScope>(data.size());
644 for (ScopeValue scopeValue : data) {
645 result.add(WipContextBuilder.createScope(scopeValue, getRemoteValueMap ping()));
646 }
647 return result;
648 }
649
650 private FunctionDetailsValue getFunctionDetails() throws MethodIsBlockingE xception {
651 if (!loadedPositionRef.isInitialized()) {
652 getRemoteValueMapping().loadFunctionLocationInFuture(getValueData().ob jectId(),
653 loadedPositionRef);
654 }
655 return loadedPositionRef.getSync().get();
656 }
657 }
658 }
659
660 private interface FunctionScopeAccess {
661 List<? extends JsScope> getScopes();
662 }
663
664 static final FunctionScopeExtension FUNCTION_SCOPE_EXTENSION = new FunctionSco peExtension() {
665 @Override
666 public List<? extends JsScope> getScopes(JsFunction function)
667 throws MethodIsBlockingException {
668 FunctionScopeAccess functionScopeAccess = (FunctionScopeAccess) function;
669 return functionScopeAccess.getScopes();
670 }
671 };
672
673 private static abstract class VariableBase implements JsVariable {
674 private final JsValue jsValue;
675 private final ValueNameBuilder nameBuilder;
676 private volatile String qualifiedName = null;
677
678 VariableBase(JsValue jsValue, ValueNameBuilder nameBuilder) {
679 this.jsValue = jsValue;
680 this.nameBuilder = nameBuilder;
681 }
682
683 @Override
684 public boolean isReadable() {
685 return true;
686 }
687
688 @Override
689 public JsValue getValue() {
690 return jsValue;
691 }
692
693 @Override
694 public String getName() {
695 return nameBuilder.getShortName();
696 }
697
698 @Override
699 public boolean isMutable() {
700 return false;
701 }
702
703 @Override
704 public void setValue(String newValue, SetValueCallback callback)
705 throws UnsupportedOperationException {
706 throw new UnsupportedOperationException();
707 }
708
709 public String getFullyQualifiedName() {
710 String result = qualifiedName;
711 if (result == null) {
712 QualifiedNameBuilder qualifiedNameBuilder = nameBuilder.getQualifiedName Builder();
713 if (qualifiedNameBuilder == null) {
714 return null;
715 }
716 StringBuilder builder = new StringBuilder();
717 qualifiedNameBuilder.append(builder);
718 result = builder.toString();
719 qualifiedName = result;
720 }
721 return result;
722 }
723 }
724
725 private static class VariableImpl extends VariableBase {
726 VariableImpl(JsValue jsValue, ValueNameBuilder nameBuilder) {
727 super(jsValue, nameBuilder);
728 }
729
730 @Override public JsObjectProperty asObjectProperty() {
731 return null;
732 }
733 }
734
735 private static abstract class ObjectPropertyBase
736 extends VariableBase implements JsObjectProperty {
737 ObjectPropertyBase(JsValue jsValue, ValueNameBuilder nameBuilder) {
738 super(jsValue, nameBuilder);
739 }
740
741 @Override public JsObjectProperty asObjectProperty() {
742 return this;
743 }
744 }
745
746 private static class ObjectType extends ValueType {
747 @Override
748 JsValue build(RemoteObjectValue valueData, WipValueLoader valueLoader,
749 QualifiedNameBuilder nameBuilder) {
750 ValueType secondLevelValueType =
751 getSafe(PROTOCOL_SUBTYPE_TO_VALUE_TYPE, valueData.subtype());
752
753 if (secondLevelValueType == null) {
754 LOGGER.severe("Unexpected value type: " + valueData.type() + " " + value Data.subtype());
755 secondLevelValueType = DEFAULT_VALUE_TYPE;
756 }
757
758 return secondLevelValueType.build(valueData, valueLoader, nameBuilder);
759 }
760
761 private static final Map<RemoteObjectValue.Subtype, ValueType> PROTOCOL_SUBT YPE_TO_VALUE_TYPE;
762 static {
763 PROTOCOL_SUBTYPE_TO_VALUE_TYPE = new HashMap<RemoteObjectValue.Subtype, Va lueType>();
764 ObjectSubtype objectSubtype = new ObjectSubtype(JsValue.Type.TYPE_OBJECT);
765 // TODO: null?
766 PROTOCOL_SUBTYPE_TO_VALUE_TYPE.put(null, objectSubtype);
767 PROTOCOL_SUBTYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Subtype.NULL,
768 new SingletonPrimitiveType(JsValue.Type.TYPE_NULL, "null"));
769 PROTOCOL_SUBTYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Subtype.ARRAY, new Ar rayType());
770 PROTOCOL_SUBTYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Subtype.REGEXP, objec tSubtype);
771 PROTOCOL_SUBTYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Subtype.DATE, objectS ubtype);
772
773 PROTOCOL_SUBTYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Subtype.NODE, objectS ubtype);
774 // Plus 1 for null - object.
775 assert PROTOCOL_SUBTYPE_TO_VALUE_TYPE.size() ==
776 RemoteObjectValue.Subtype.values().length + 1;
777 }
778 }
779
780 private static final Map<RemoteObjectValue.Type, ValueType> PROTOCOL_TYPE_TO_V ALUE_TYPE;
781 static {
782 PROTOCOL_TYPE_TO_VALUE_TYPE = new HashMap<RemoteObjectValue.Type, ValueType> ();
783 PROTOCOL_TYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Type.STRING,
784 new PrimitiveTypeWithValue(JsValue.Type.TYPE_STRING));
785 PROTOCOL_TYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Type.BOOLEAN,
786 new PrimitiveTypeWithValue(JsValue.Type.TYPE_BOOLEAN));
787 PROTOCOL_TYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Type.NUMBER,
788 new PrimitiveTypeWithDescription(JsValue.Type.TYPE_NUMBER));
789 PROTOCOL_TYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Type.UNDEFINED,
790 new SingletonPrimitiveType(JsValue.Type.TYPE_UNDEFINED, "undefined"));
791
792 PROTOCOL_TYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Type.OBJECT, new ObjectTyp e());
793 PROTOCOL_TYPE_TO_VALUE_TYPE.put(RemoteObjectValue.Type.FUNCTION, new Functio nType());
794
795 assert PROTOCOL_TYPE_TO_VALUE_TYPE.size() == RemoteObjectValue.Type.values() .length;
796 }
797
798 private static final ValueType DEFAULT_VALUE_TYPE = new ObjectSubtype(JsValue. Type.TYPE_OBJECT);
799 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698