| Index: plugins/org.chromium.sdk.wipbackend.wk118685/src/org/chromium/sdk/internal/wip/WipValueLoader.java
|
| diff --git a/plugins/org.chromium.sdk.wipbackend.wk118685/src/org/chromium/sdk/internal/wip/WipValueLoader.java b/plugins/org.chromium.sdk.wipbackend.wk118685/src/org/chromium/sdk/internal/wip/WipValueLoader.java
|
| deleted file mode 100644
|
| index 3fb30f045f69a39cc014f14ee8288fe366bb1296..0000000000000000000000000000000000000000
|
| --- a/plugins/org.chromium.sdk.wipbackend.wk118685/src/org/chromium/sdk/internal/wip/WipValueLoader.java
|
| +++ /dev/null
|
| @@ -1,368 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -package org.chromium.sdk.internal.wip;
|
| -
|
| -import java.util.ArrayList;
|
| -import java.util.Arrays;
|
| -import java.util.Collection;
|
| -import java.util.Collections;
|
| -import java.util.HashMap;
|
| -import java.util.List;
|
| -import java.util.Map;
|
| -import java.util.concurrent.atomic.AtomicInteger;
|
| -
|
| -import org.chromium.sdk.CallbackSemaphore;
|
| -import org.chromium.sdk.JsObjectProperty;
|
| -import org.chromium.sdk.JsVariable;
|
| -import org.chromium.sdk.RelayOk;
|
| -import org.chromium.sdk.RemoteValueMapping;
|
| -import org.chromium.sdk.SyncCallback;
|
| -import org.chromium.sdk.internal.wip.WipExpressionBuilder.PropertyNameBuilder;
|
| -import org.chromium.sdk.internal.wip.WipExpressionBuilder.ValueNameBuilder;
|
| -import org.chromium.sdk.internal.wip.protocol.input.debugger.FunctionDetailsValue;
|
| -import org.chromium.sdk.internal.wip.protocol.input.debugger.GetFunctionDetailsData;
|
| -import org.chromium.sdk.internal.wip.protocol.input.debugger.LocationValue;
|
| -import org.chromium.sdk.internal.wip.protocol.input.runtime.GetPropertiesData;
|
| -import org.chromium.sdk.internal.wip.protocol.input.runtime.PropertyDescriptorValue;
|
| -import org.chromium.sdk.internal.wip.protocol.output.debugger.GetFunctionDetailsParams;
|
| -import org.chromium.sdk.internal.wip.protocol.output.runtime.GetPropertiesParams;
|
| -import org.chromium.sdk.util.AsyncFuture;
|
| -import org.chromium.sdk.util.AsyncFuture.Callback;
|
| -import org.chromium.sdk.util.AsyncFutureRef;
|
| -import org.chromium.sdk.util.GenericCallback;
|
| -import org.chromium.sdk.util.MethodIsBlockingException;
|
| -
|
| -/**
|
| - * Responsible for loading values of properties. It works in pair with {@link WipValueBuilder}.
|
| - * TODO: add a cache for already loaded values if remote protocol ever has
|
| - * permanent object ids (same object reported under the same id within a debug context).
|
| - */
|
| -public abstract class WipValueLoader implements RemoteValueMapping {
|
| - private final WipTabImpl tabImpl;
|
| - private final AtomicInteger cacheStateRef = new AtomicInteger(1);
|
| - private final WipValueBuilder valueBuilder = new WipValueBuilder(this);
|
| -
|
| - public WipValueLoader(WipTabImpl tabImpl) {
|
| - this.tabImpl = tabImpl;
|
| - }
|
| -
|
| - @Override
|
| - public void clearCaches() {
|
| - cacheStateRef.incrementAndGet();
|
| - }
|
| -
|
| - WipValueBuilder getValueBuilder() {
|
| - return valueBuilder;
|
| - }
|
| -
|
| - WipTabImpl getTabImpl() {
|
| - return tabImpl;
|
| - }
|
| -
|
| - /**
|
| - * Loads object properties. It starts and executes a load operation of a corresponding
|
| - * {@link AsyncFuture}. The operation is fully synchronous, so this method normally
|
| - * blocks. There is a chance that other thread is already executing load operation.
|
| - * In this case the method will return immediately, but {@link AsyncFuture} will hold
|
| - * thread until the operation finishes.
|
| - * @param innerNameBuilder name builder for qualified names of all properties and subproperties
|
| - * @param futureRef future reference that will hold result of load operation
|
| - */
|
| - void loadJsObjectPropertiesInFuture(final String objectId,
|
| - PropertyNameBuilder innerNameBuilder, boolean reload, int currentCacheState,
|
| - AsyncFutureRef<Getter<ObjectProperties>> futureRef) throws MethodIsBlockingException {
|
| - ObjectPropertyProcessor propertyProcessor =
|
| - new ObjectPropertyProcessor(innerNameBuilder, objectId);
|
| - loadPropertiesInFuture(objectId, propertyProcessor, reload, currentCacheState, futureRef);
|
| - }
|
| -
|
| - int getCacheState() {
|
| - return cacheStateRef.get();
|
| - }
|
| -
|
| - abstract String getObjectGroupId();
|
| -
|
| - /**
|
| - * A utility method that initializes {@link AsyncFuture} of an object without properties.
|
| - */
|
| - static void setEmptyJsObjectProperties(AsyncFutureRef<Getter<ObjectProperties>> output) {
|
| - output.initializeTrivial(EMPTY_OBJECT_PROPERTIES_GETTER);
|
| - }
|
| -
|
| - /**
|
| - * A getter that either returns a value or throws an exception with some failure description.
|
| - * Exception is the only means of passing message about some problem to user in SDK API.
|
| - */
|
| - static abstract class Getter<T> {
|
| - abstract T get();
|
| -
|
| - static <V> Getter<V> newNormal(final V value) {
|
| - return new Getter<V>() {
|
| - @Override
|
| - V get() {
|
| - return value;
|
| - }
|
| - };
|
| - }
|
| -
|
| - static <S> Getter<S> newFailure(final Exception cause) {
|
| - return new Getter<S>() {
|
| - @Override
|
| - S get() {
|
| - throw new RuntimeException("Failed to load properties", cause);
|
| - }
|
| - };
|
| - }
|
| - }
|
| -
|
| - interface ObjectProperties {
|
| - List<? extends JsObjectProperty> properties();
|
| - JsVariable getProperty(String name);
|
| -
|
| - List<? extends JsVariable> internalProperties();
|
| - int getCacheState();
|
| - }
|
| -
|
| - /**
|
| - * An abstract processor that is reads protocol response and creates proper
|
| - * property objects. This may be implemented differently for objects, functions or
|
| - * scopes.
|
| - */
|
| - interface LoadPostprocessor<RES> {
|
| - RES process(List<? extends PropertyDescriptorValue> propertyList, int currentCacheState);
|
| - RES getEmptyResult();
|
| - RES forException(Exception exception);
|
| - }
|
| -
|
| - private class ObjectPropertyProcessor implements LoadPostprocessor<Getter<ObjectProperties>> {
|
| - private final PropertyNameBuilder propertyNameBuilder;
|
| - private final String objectId;
|
| -
|
| - ObjectPropertyProcessor(PropertyNameBuilder propertyNameBuilder, String objectId) {
|
| - this.propertyNameBuilder = propertyNameBuilder;
|
| - this.objectId = objectId;
|
| - }
|
| -
|
| - @Override
|
| - public Getter<ObjectProperties> process(
|
| - List<? extends PropertyDescriptorValue> propertyList, final int currentCacheState) {
|
| - final List<JsObjectProperty> properties =
|
| - new ArrayList<JsObjectProperty>(propertyList.size());
|
| - final List<JsVariable> internalProperties = new ArrayList<JsVariable>(2);
|
| -
|
| - for (PropertyDescriptorValue propertyDescriptor : propertyList) {
|
| - String name = propertyDescriptor.name();
|
| - boolean isInternal = INTERNAL_PROPERTY_NAME.contains(name);
|
| -
|
| - ValueNameBuilder valueNameBuilder =
|
| - WipExpressionBuilder.createValueOfPropertyNameBuilder(name, propertyNameBuilder);
|
| -
|
| - JsObjectProperty property = valueBuilder.createObjectProperty(propertyDescriptor,
|
| - objectId, valueNameBuilder);
|
| - if (isInternal) {
|
| - internalProperties.add(property);
|
| - } else {
|
| - properties.add(property);
|
| - }
|
| - }
|
| -
|
| - final ObjectProperties result = new ObjectProperties() {
|
| - private volatile Map<String, JsVariable> propertyMap = null;
|
| -
|
| - @Override
|
| - public List<? extends JsObjectProperty> properties() {
|
| - return properties;
|
| - }
|
| -
|
| - @Override
|
| - public List<? extends JsVariable> internalProperties() {
|
| - return internalProperties;
|
| - }
|
| -
|
| - @Override
|
| - public JsVariable getProperty(String name) {
|
| - Map<String, JsVariable> map = propertyMap;
|
| - if (map == null) {
|
| - List<? extends JsVariable> list = properties();
|
| - map = new HashMap<String, JsVariable>(list.size());
|
| - for (JsVariable property : list) {
|
| - map.put(property.getName(), property);
|
| - }
|
| - // Possibly overwrite other already created map, but we don't care about instance here.
|
| - propertyMap = map;
|
| - }
|
| - return map.get(name);
|
| - }
|
| -
|
| - @Override
|
| - public int getCacheState() {
|
| - return currentCacheState;
|
| - }
|
| - };
|
| - return Getter.newNormal(result);
|
| - }
|
| -
|
| - @Override
|
| - public Getter<ObjectProperties> getEmptyResult() {
|
| - return EMPTY_OBJECT_PROPERTIES_GETTER;
|
| - }
|
| -
|
| - @Override
|
| - public Getter<ObjectProperties> forException(Exception exception) {
|
| - return Getter.newFailure(exception);
|
| - }
|
| - }
|
| -
|
| - private static final Getter<ObjectProperties> EMPTY_OBJECT_PROPERTIES_GETTER =
|
| - Getter.newNormal(((ObjectProperties) new ObjectProperties() {
|
| - @Override public List<? extends JsObjectProperty> properties() {
|
| - return Collections.emptyList();
|
| - }
|
| - @Override public JsVariable getProperty(String name) {
|
| - return null;
|
| - }
|
| - @Override public List<? extends JsVariable> internalProperties() {
|
| - return Collections.emptyList();
|
| - }
|
| - @Override public int getCacheState() {
|
| - return Integer.MAX_VALUE;
|
| - }
|
| - }));
|
| -
|
| - <RES> void loadPropertiesInFuture(final String objectId,
|
| - final LoadPostprocessor<RES> propertyPostprocessor, boolean reload,
|
| - final int currentCacheState, AsyncFutureRef<RES> futureRef)
|
| - throws MethodIsBlockingException {
|
| - if (objectId == null) {
|
| - futureRef.initializeTrivial(propertyPostprocessor.getEmptyResult());
|
| - return;
|
| - }
|
| -
|
| - // The entire operation that first loads properties from remote and then postprocess them
|
| - // (without occupying Dispatch thread).
|
| - // The operation is sync because we don't want to do postprocessing in Dispatch thread.
|
| - AsyncFuture.SyncOperation<RES> syncOperation = new AsyncFuture.SyncOperation<RES>() {
|
| - @Override
|
| - protected RES runSync() throws MethodIsBlockingException {
|
| - // Get response from remote.
|
| - LoadPropertiesResponse response = loadRawPropertiesSync(objectId);
|
| -
|
| - // Process result.
|
| - return response.accept(new LoadPropertiesResponse.Visitor<RES>() {
|
| - @Override
|
| - public RES visitData(GetPropertiesData data) {
|
| - // TODO: check exception.
|
| - return propertyPostprocessor.process(data.result(), currentCacheState);
|
| - }
|
| -
|
| - @Override
|
| - public RES visitFailure(final Exception exception) {
|
| - return propertyPostprocessor.forException(new RuntimeException(
|
| - "Failed to read properties from remote", exception));
|
| - }
|
| - });
|
| - }
|
| - };
|
| -
|
| - if (reload) {
|
| - futureRef.reinitializeRunning(syncOperation.asAsyncOperation());
|
| - } else {
|
| - futureRef.initializeRunning(syncOperation.asAsyncOperation());
|
| - }
|
| - syncOperation.execute();
|
| - }
|
| -
|
| - void loadFunctionLocationInFuture(final String objectId,
|
| - AsyncFutureRef<Getter<FunctionDetailsValue>> loadedPositionRef)
|
| - throws MethodIsBlockingException {
|
| -
|
| - AsyncFuture.Operation<Getter<FunctionDetailsValue>> operation =
|
| - new AsyncFuture.Operation<Getter<FunctionDetailsValue>>() {
|
| - @Override
|
| - public RelayOk start(final Callback<Getter<FunctionDetailsValue>> callback,
|
| - SyncCallback syncCallback) {
|
| - GetFunctionDetailsParams request = new GetFunctionDetailsParams(objectId);
|
| - GenericCallback<GetFunctionDetailsData> wrappedCallback =
|
| - new GenericCallback<GetFunctionDetailsData>() {
|
| - @Override public void success(GetFunctionDetailsData value) {
|
| - callback.done(Getter.newNormal(value.details()));
|
| - }
|
| -
|
| - @Override public void failure(Exception exception) {
|
| - callback.done(Getter.<FunctionDetailsValue>newFailure(exception));
|
| - }
|
| - };
|
| - return tabImpl.getCommandProcessor().send(request, wrappedCallback, syncCallback);
|
| - }
|
| - };
|
| -
|
| - loadedPositionRef.initializeRunning(operation);
|
| - }
|
| -
|
| - /**
|
| - * Response is either data or error message. We wrap whatever it is for postprocessing
|
| - * that is conducted off Dispatch thread.
|
| - */
|
| - private static abstract class LoadPropertiesResponse {
|
| - interface Visitor<R> {
|
| - R visitData(GetPropertiesData response);
|
| -
|
| - R visitFailure(Exception exception);
|
| - }
|
| - abstract <R> R accept(Visitor<R> visitor);
|
| - }
|
| -
|
| - private LoadPropertiesResponse loadRawPropertiesSync(String objectId)
|
| - throws MethodIsBlockingException {
|
| - final LoadPropertiesResponse[] result = { null };
|
| - GenericCallback<GetPropertiesData> callback =
|
| - new GenericCallback<GetPropertiesData>() {
|
| - @Override
|
| - public void success(final GetPropertiesData value) {
|
| - result[0] = new LoadPropertiesResponse() {
|
| - @Override
|
| - <R> R accept(Visitor<R> visitor) {
|
| - return visitor.visitData(value);
|
| - }
|
| - };
|
| - }
|
| -
|
| - @Override
|
| - public void failure(final Exception exception) {
|
| - result[0] = new LoadPropertiesResponse() {
|
| - @Override
|
| - <R> R accept(Visitor<R> visitor) {
|
| - return visitor.visitFailure(exception);
|
| - }
|
| - };
|
| - }
|
| - };
|
| -
|
| - final GetPropertiesParams request;
|
| - {
|
| - boolean ownProperties = true;
|
| - request = new GetPropertiesParams(objectId, ownProperties);
|
| - }
|
| -
|
| - CallbackSemaphore callbackSemaphore = new CallbackSemaphore();
|
| - RelayOk relayOk =
|
| - tabImpl.getCommandProcessor().send(request, callback, callbackSemaphore);
|
| - callbackSemaphore.acquireDefault(relayOk);
|
| -
|
| - return result[0];
|
| - }
|
| -
|
| - static WipValueLoader castArgument(RemoteValueMapping mapping) {
|
| - try {
|
| - return (WipValueLoader) mapping;
|
| - } catch (ClassCastException e) {
|
| - throw new IllegalArgumentException("Incorrect evaluate context argument", e);
|
| - }
|
| - }
|
| -
|
| - // List is too short to use HashSet.
|
| - private static final Collection<String> INTERNAL_PROPERTY_NAME =
|
| - Arrays.asList("__proto__", "constructor");
|
| -}
|
|
|