*/
-public class DataGeneratorWithThread extends Thread implements IDataGenerator {
+public class DataGeneratorWithThread extends Thread
+ implements IDataGenerator
+{
// Request objects are used to serialize the interface calls into objects
// which can then be pushed into a queue.
@@ -61,7 +63,7 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
class ItemRequest extends Request {
final int fIndex;
- ItemRequest(int index, DataRequestMonitor rm) {
+ ItemRequest(int index, DataRequestMonitor rm) {
super(rm);
fIndex = index;
}
@@ -76,7 +78,8 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
// Main request queue of the data generator. The getValue(), getCount(),
// and shutdown() methods write into the queue, while the run() method
// reads from it.
- private final BlockingQueue fQueue = new LinkedBlockingQueue();
+ private final BlockingQueue fQueue =
+ new LinkedBlockingQueue();
// ListenerList class provides thread safety.
private ListenerList fListeners = new ListenerList();
@@ -88,7 +91,8 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
private int fCountResetTrigger = 0;
// Elements which were modified since the last reset.
- private Set fChangedIndexes = Collections.synchronizedSet(new HashSet());
+ private Map fChangedValues =
+ Collections.synchronizedMap(new HashMap());
// Used to determine when to make changes in data.
private long fLastChangeTime = System.currentTimeMillis();
@@ -108,7 +112,8 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
fQueue.add(new ShutdownRequest(rm));
} else {
//
- rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down"));
+ rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID,
+ "Supplier shut down"));
rm.done();
}
}
@@ -117,16 +122,18 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
if (!fShutdown.get()) {
fQueue.add(new CountRequest(rm));
} else {
- rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down"));
+ rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID,
+ "Supplier shut down"));
rm.done();
}
}
- public void getValue(int index, DataRequestMonitor rm) {
+ public void getValue(int index, DataRequestMonitor rm) {
if (!fShutdown.get()) {
fQueue.add(new ItemRequest(index, rm));
} else {
- rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down"));
+ rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID,
+ "Supplier shut down"));
rm.done();
}
}
@@ -150,7 +157,6 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
// If a request was dequeued, process it.
if (request != null) {
// Simulate a processing delay.
- Thread.sleep(PROCESSING_DELAY);
if (request instanceof CountRequest) {
processCountRequest((CountRequest)request);
@@ -162,6 +168,8 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
request.fRequestMonitor.done();
break;
}
+ } else {
+ Thread.sleep(PROCESSING_DELAY);
}
// Simulate data changes.
@@ -173,7 +181,8 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
private void processCountRequest(CountRequest request) {
@SuppressWarnings("unchecked") // Suppress warning about lost type info.
- DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor;
+ DataRequestMonitor rm =
+ (DataRequestMonitor)request.fRequestMonitor;
rm.setData(fCount);
rm.done();
@@ -181,12 +190,13 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
private void processItemRequest(ItemRequest request) {
@SuppressWarnings("unchecked") // Suppress warning about lost type info.
- DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor;
+ DataRequestMonitor rm =
+ (DataRequestMonitor)request.fRequestMonitor;
- if (fChangedIndexes.contains(request.fIndex)) {
- rm.setData("Changed: " + request.fIndex);
+ if (fChangedValues.containsKey(request.fIndex)) {
+ rm.setData(fChangedValues.get(request.fIndex));
} else {
- rm.setData(Integer.toString(request.fIndex));
+ rm.setData(request.fIndex);
}
rm.done();
}
@@ -194,12 +204,14 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
private void randomChanges() {
// Check if enough time is elapsed.
- if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_INTERVAL) {
+ if (System.currentTimeMillis() >
+ fLastChangeTime + RANDOM_CHANGE_INTERVAL)
+ {
fLastChangeTime = System.currentTimeMillis();
// Once every number of changes, reset the count, the rest of the
// times just change certain values.
- if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0){
+ if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0) {
randomCountReset();
} else {
randomDataChange();
@@ -213,7 +225,7 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
fCount = MIN_COUNT + Math.abs(random.nextInt()) % (MAX_COUNT - MIN_COUNT);
// Reset the changed values.
- fChangedIndexes.clear();
+ fChangedValues.clear();
// Notify listeners
for (Object listener : fListeners.getListeners()) {
@@ -224,17 +236,19 @@ public class DataGeneratorWithThread extends Thread implements IDataGenerator {
private void randomDataChange() {
// Calculate the indexes to change.
Random random = new java.util.Random();
- Set set = new HashSet();
+ Map changed = new HashMap();
for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) {
- set.add( new Integer(Math.abs(random.nextInt()) % fCount) );
+ int randomIndex = Math.abs(random.nextInt()) % fCount;
+ int randomValue = Math.abs(random.nextInt()) % fCount;
+ changed.put(randomIndex, randomValue);
}
// Add the indexes to an overall set of changed indexes.
- fChangedIndexes.addAll(set);
+ fChangedValues.putAll(changed);
// Notify listeners
for (Object listener : fListeners.getListeners()) {
- ((Listener)listener).valuesChanged(set);
+ ((Listener)listener).valuesChanged(changed.keySet());
}
}
}
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/IDataGenerator.java b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/IDataGenerator.java
index 398b09a4e88..ef7eb53f27a 100644
--- a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/IDataGenerator.java
+++ b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/IDataGenerator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 Wind River Systems and others.
+ * Copyright (c) 2006, 2011 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -41,11 +41,11 @@ public interface IDataGenerator {
// Changing the count range can stress the scalability of the system, while
// changing of the process delay and random change interval can stress
// its performance.
- final static int MIN_COUNT = 100;
- final static int MAX_COUNT = 200;
- final static int PROCESSING_DELAY = 10;
- final static int RANDOM_CHANGE_INTERVAL = 10000;
- final static int RANDOM_COUNT_CHANGE_INTERVALS = 3;
+ final static int MIN_COUNT = 50;
+ final static int MAX_COUNT = 100;
+ final static int PROCESSING_DELAY = 500;
+ final static int RANDOM_CHANGE_INTERVAL = 4000;
+ final static int RANDOM_COUNT_CHANGE_INTERVALS = 5;
final static int RANDOM_CHANGE_SET_PERCENTAGE = 10;
@@ -58,7 +58,7 @@ public interface IDataGenerator {
// Data access methods.
void getCount(DataRequestMonitor rm);
- void getValue(int index, DataRequestMonitor rm);
+ void getValue(int index, DataRequestMonitor rm);
// Method used to shutdown the data generator including any threads that
// it may use.
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/SyncDataViewer.java b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/SyncDataViewer.java
index 6ce9c06ef4e..335d198415f 100644
--- a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/SyncDataViewer.java
+++ b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/SyncDataViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * Copyright (c) 2008, 2011 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,8 +14,11 @@ package org.eclipse.cdt.examples.dsf.dataviewer;
//#package org.eclipse.cdt.examples.dsf.dataviewer.answers;
//#endif
+import java.util.Arrays;
+import java.util.List;
import java.util.Set;
+import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.Query;
@@ -35,8 +38,8 @@ import org.eclipse.swt.widgets.Shell;
* This viewer implements the {@link IStructuredContentProvider} interface
* which is used by the JFace TableViewer class to populate a Table. This
* interface contains one principal methods for reading data {@link #getElements(Object)},
- * which synchronously returns an array of elements. In order to implement this
- * method using the asynchronous data generator, this provider uses the
+ * which synchronously returns an array of elements. In order to implement
+ * this method using the asynchronous data generator, this provider uses the
* {@link Query} object.
*
*/
@@ -84,27 +87,43 @@ public class SyncDataViewer
return new Object[0];
}
- // Create the array that will be filled with elements.
- // For each index in the array execute a query to get the element at
- // that index.
- final Object[] elements = new Object[count];
-
- for (int i = 0; i < count; i++) {
- final int index = i;
- Query valueQuery = new Query() {
- @Override
- protected void execute(DataRequestMonitor rm) {
- fDataGenerator.getValue(index, rm);
+ final int finalCount = count;
+ Query> valueQuery = new Query>() {
+ @Override
+ protected void execute(final DataRequestMonitor> rm) {
+ final Integer[] retVal = new Integer[finalCount];
+ final CountingRequestMonitor crm = new CountingRequestMonitor(
+ ImmediateExecutor.getInstance(), rm)
+ {
+ @Override
+ protected void handleSuccess() {
+ rm.setData(Arrays.asList(retVal));
+ rm.done();
+ };
+ };
+ for (int i = 0; i < finalCount; i++) {
+ final int finalI = i;
+ fDataGenerator.getValue(
+ i,
+ new DataRequestMonitor(
+ ImmediateExecutor.getInstance(), crm)
+ {
+ @Override
+ protected void handleSuccess() {
+ retVal[finalI] = getData();
+ crm.done();
+ }
+ });
}
- };
- ImmediateExecutor.getInstance().execute(valueQuery);
- try {
- elements[i] = valueQuery.get();
- } catch (Exception e) {
- elements[i] = "error";
- }
+ crm.setDoneCount(finalCount);
+ }
+ };
+ ImmediateExecutor.getInstance().execute(valueQuery);
+ try {
+ return valueQuery.get().toArray(new Integer[0]);
+ } catch (Exception e) {
}
- return elements;
+ return new Object[0];
}
public void dispose() {
@@ -140,6 +159,10 @@ public class SyncDataViewer
});
}
+ /**
+ * The entry point for the example.
+ * @param args Program arguments.
+ */
public static void main(String[] args) {
// Create the shell to hold the viewer.
Display display = new Display();
@@ -162,7 +185,8 @@ public class SyncDataViewer
//#endif
// Create the content provider which will populate the viewer.
- SyncDataViewer contentProvider = new SyncDataViewer(tableViewer, generator);
+ SyncDataViewer contentProvider =
+ new SyncDataViewer(tableViewer, generator);
tableViewer.setContentProvider(contentProvider);
tableViewer.setInput(new Object());
From 02c9e05cd577223b8f7a6320cf600c38b7ae8207 Mon Sep 17 00:00:00 2001
From: Pawel Piech
Date: Thu, 1 Dec 2011 07:27:13 -0800
Subject: [PATCH 14/20] Bug 310345 - [concurrent] Asynchronous Cache
Programming Model (ACPM) - Added missing files from last commit.
---
.../dsf/dataviewer/ACPMSumDataGenerator.java | 234 +++++++++
.../dsf/dataviewer/ACPMSumDataViewer.java | 482 ++++++++++++++++++
.../dsf/dataviewer/AsyncSumDataGenerator.java | 171 +++++++
.../dsf/dataviewer/AsyncSumDataViewer.java | 410 +++++++++++++++
.../dataviewer/DataGeneratorCacheManager.java | 165 ++++++
5 files changed, 1462 insertions(+)
create mode 100644 dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataGenerator.java
create mode 100644 dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataViewer.java
create mode 100644 dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataGenerator.java
create mode 100644 dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataViewer.java
create mode 100644 dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/DataGeneratorCacheManager.java
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataGenerator.java b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataGenerator.java
new file mode 100644
index 00000000000..889d59475dc
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataGenerator.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+//#ifdef exercises
+package org.eclipse.cdt.examples.dsf.dataviewer;
+//#else
+//#package org.eclipse.cdt.examples.dsf.dataviewer.answers;
+//#endif
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
+import org.eclipse.cdt.dsf.concurrent.ICache;
+import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.Transaction;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A data generator which performs a sum computation on data retrieved from a
+ * number of other data generators. The data retrieval from other generators
+ * is performed using ACPM caches and the result is calculated once all caches
+ * are valid.
+ *
+ * Unlike {@link AsyncSumDataGenerator}, this data generator listens to events
+ * from the individual the data providers. Theve events are used to
+ * invalidate caches to make sure that they don't return incorrect data. This
+ * generator also sends out events to its clients to notify them to update, or
+ * invalidate their caches.
+ *
+ */
+public class ACPMSumDataGenerator
+ implements IDataGenerator, IDataGenerator.Listener
+{
+
+ /**
+ * DSF executor used to serialize data access within this data generator.
+ */
+ final private DsfExecutor fExecutor;
+
+ /**
+ * Data generators to retrieve original data to perform calculations on.
+ * The generators are accessed through the cache manager wrappers.
+ */
+ final private DataGeneratorCacheManager[] fDataGeneratorCMs;
+
+ /**
+ * List of listeners for this data generator.
+ */
+ final private List fListeners = new LinkedList();
+
+ public ACPMSumDataGenerator(DsfExecutor executor,
+ IDataGenerator[] generators)
+ {
+ fExecutor = executor;
+
+ // Create wrappers for data generators and add ourselves as listener
+ // to their events.
+ fDataGeneratorCMs = new DataGeneratorCacheManager[generators.length];
+ ImmediateInDsfExecutor immediateExecutor =
+ new ImmediateInDsfExecutor(fExecutor);
+ for (int i = 0; i < generators.length; i++) {
+ fDataGeneratorCMs[i] = new DataGeneratorCacheManager(
+ immediateExecutor, generators[i]);
+ generators[i].addListener(this);
+ }
+ }
+
+ public void getCount(final DataRequestMonitor rm) {
+ // Artificially delay the retrieval of the sum data to simulate
+ // real processing time.
+ fExecutor.schedule( new Runnable() {
+ public void run() {
+ // Create the transaction here to put all the ugly
+ // code in one place.
+ new Transaction() {
+ @Override
+ protected Integer process()
+ throws Transaction.InvalidCacheException,
+ CoreException
+ {
+ return processCount(this);
+ }
+ }.request(rm);
+ }
+ },
+ PROCESSING_DELAY, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Perform the calculation to get the max count for the given transaction.
+ * @param transaction The ACPM transaction to use for calculation.
+ * @return Calculated count.
+ * @throws Transaction.InvalidCacheException {@link Transaction#process}
+ * @throws CoreException See {@link Transaction#process}
+ */
+ private Integer processCount(Transaction transaction)
+ throws Transaction.InvalidCacheException, CoreException
+ {
+ // Assemble all needed count caches into a collection.
+ List> countCaches =
+ new ArrayList>(fDataGeneratorCMs.length);
+ for (DataGeneratorCacheManager dataGeneratorCM : fDataGeneratorCMs) {
+ countCaches.add(dataGeneratorCM.getCount());
+ }
+ // Validate all count caches at once. This executes needed requests
+ // in parallel.
+ transaction.validate(countCaches);
+
+ // Calculate the max value and return.
+ int maxCount = 0;
+ for (ICache countCache : countCaches) {
+ maxCount = Math.max(maxCount, countCache.getData());
+ }
+ return maxCount;
+ }
+
+ public void getValue(final int index, final DataRequestMonitor rm)
+ {
+ // Add a processing delay.
+ fExecutor.schedule( new Runnable() {
+ public void run() {
+ new Transaction() {
+ @Override
+ protected Integer process()
+ throws Transaction.InvalidCacheException,
+ CoreException
+ {
+ return processValue(this, index);
+ }
+ }.request(rm);
+ }
+ },
+ PROCESSING_DELAY, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Perform the calculation to get the sum of values at given index.
+ * @param transaction The ACPM transaction to use for calculation.
+ * @param index Index of value to calculate.
+ * @return Calculated value.
+ * @throws Transaction.InvalidCacheException {@link Transaction#process}
+ * @throws CoreException See {@link Transaction#process}
+ */
+ private Integer processValue(Transaction transaction, int index)
+ throws Transaction.InvalidCacheException, CoreException
+ {
+ List> valueCaches =
+ new ArrayList>(fDataGeneratorCMs.length);
+ for (DataGeneratorCacheManager dataGeneratorCM : fDataGeneratorCMs) {
+ valueCaches.add(dataGeneratorCM.getValue(index));
+ }
+ // Validate all value caches at once. This executes needed requests
+ // in parallel.
+ transaction.validate(valueCaches);
+
+ int sum = 0;
+ for (ICache valueCache : valueCaches) {
+ sum += valueCache.getData();
+ }
+ return sum;
+ }
+
+ public void shutdown(final RequestMonitor rm) {
+ for (DataGeneratorCacheManager dataGeneratorCM : fDataGeneratorCMs) {
+ dataGeneratorCM.getDataGenerator().removeListener(this);
+ dataGeneratorCM.dispose();
+ rm.done();
+ }
+ rm.done();
+ }
+
+ public void addListener(final Listener listener) {
+ // Must access fListeners on executor thread.
+ try {
+ fExecutor.execute( new DsfRunnable() {
+ public void run() {
+ fListeners.add(listener);
+ }
+ });
+ } catch (RejectedExecutionException e) {}
+ }
+
+ public void removeListener(final Listener listener) {
+ // Must access fListeners on executor thread.
+ try {
+ fExecutor.execute( new DsfRunnable() {
+ public void run() {
+ fListeners.remove(listener);
+ }
+ });
+ } catch (RejectedExecutionException e) {}
+ }
+
+ public void countChanged() {
+ // Must access fListeners on executor thread.
+ try {
+ fExecutor.execute( new DsfRunnable() {
+ public void run() {
+ for (Listener listener : fListeners) {
+ listener.countChanged();
+ }
+ }
+ });
+ } catch (RejectedExecutionException e) {}
+ }
+
+ public void valuesChanged(final Set changed) {
+ // Must access fListeners on executor thread.
+ try {
+ fExecutor.execute( new DsfRunnable() {
+ public void run() {
+ for (Object listener : fListeners) {
+ ((Listener)listener).valuesChanged(changed);
+ }
+ }
+ });
+ } catch (RejectedExecutionException e) {}
+ }
+}
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataViewer.java b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataViewer.java
new file mode 100644
index 00000000000..fd526e74f72
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/ACPMSumDataViewer.java
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+//#ifdef exercises
+package org.eclipse.cdt.examples.dsf.dataviewer;
+//#else
+//#package org.eclipse.cdt.examples.dsf.dataviewer.answers;
+//#endif
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DefaultDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.ICache;
+import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
+import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.Query;
+import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
+import org.eclipse.cdt.dsf.concurrent.Transaction;
+import org.eclipse.cdt.dsf.ui.concurrent.DisplayDsfExecutor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ILazyContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * Data viewer based on a table, which reads data from multiple data
+ * providers using ACPM methods and performs a computation on the
+ * retrieved data.
+ *
+ * This example builds on the {@link AsyncSumDataViewer} example. It
+ * demonstrates using ACPM to solve the data consistency problem when
+ * retrieving data from multiple sources asynchronously.
+ *
+ */
+@ConfinedToDsfExecutor("fDisplayExecutor")
+public class ACPMSumDataViewer implements ILazyContentProvider
+{
+ /** View update frequency interval. */
+ final private static int UPDATE_INTERVAL = 10000;
+
+ /** Executor to use instead of Display.asyncExec(). **/
+ @ThreadSafe
+ final private DsfExecutor fDisplayExecutor;
+
+ /** Executor to use when retrieving data from data providers */
+ @ThreadSafe
+ final private ImmediateInDsfExecutor fDataExecutor;
+
+ // The viewer and generator that this content provider using.
+ final private TableViewer fViewer;
+ final private DataGeneratorCacheManager[] fDataGeneratorCMs;
+ final private DataGeneratorCacheManager fSumGeneratorCM;
+
+ // Fields used in request cancellation logic.
+ private List fItemDataRequestMonitors =
+ new LinkedList();
+ private Set fIndexesToCancel = new HashSet();
+ private int fCancelCallsPending = 0;
+ private Future> fRefreshFuture;
+
+ public ACPMSumDataViewer(TableViewer viewer,
+ ImmediateInDsfExecutor dataExecutor, IDataGenerator[] generators,
+ IDataGenerator sumGenerator)
+ {
+ fViewer = viewer;
+ fDisplayExecutor = DisplayDsfExecutor.getDisplayDsfExecutor(
+ fViewer.getTable().getDisplay());
+ fDataExecutor = dataExecutor;
+
+ // Create wrappers for data generators. Don't need to register as
+ // listeners to generator events because the cache managers ensure data
+ // are already registered for them.
+ fDataGeneratorCMs = new DataGeneratorCacheManager[generators.length];
+ for (int i = 0; i < generators.length; i++) {
+ fDataGeneratorCMs[i] =
+ new DataGeneratorCacheManager(fDataExecutor, generators[i]);
+ }
+ fSumGeneratorCM =
+ new DataGeneratorCacheManager(fDataExecutor, sumGenerator);
+
+ // Schedule a task to refresh the viewer periodically.
+ fRefreshFuture = fDisplayExecutor.scheduleAtFixedRate(
+ new Runnable() {
+ public void run() {
+ queryItemCount();
+ }
+ },
+ UPDATE_INTERVAL, UPDATE_INTERVAL, TimeUnit.MILLISECONDS);
+ }
+
+ public void dispose() {
+ // Cancel the periodic task of refreshing the view.
+ fRefreshFuture.cancel(false);
+
+ // Need to dispose cache managers that were created in this class. This
+ // needs to be done on the cache manager's thread.
+ Query disposeCacheManagersQuery = new Query() {
+ @Override
+ protected void execute(DataRequestMonitor rm) {
+ fSumGeneratorCM.dispose();
+ for (DataGeneratorCacheManager dataGeneratorCM :
+ fDataGeneratorCMs)
+ {
+ dataGeneratorCM.dispose();
+ }
+ rm.setData(new Object());
+ rm.done();
+ }
+ };
+ fDataExecutor.execute(disposeCacheManagersQuery);
+ try {
+ disposeCacheManagersQuery.get();
+ }
+ catch (InterruptedException e) {}
+ catch (ExecutionException e) {}
+
+ // Cancel any outstanding data requests.
+ for (ValueRequestMonitor rm : fItemDataRequestMonitors) {
+ rm.cancel();
+ }
+ fItemDataRequestMonitors.clear();
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // Set the initial count to the viewer after the input is set.
+ queryItemCount();
+ }
+
+ public void updateElement(final int index) {
+ // Calculate the visible index range.
+ final int topIdx = fViewer.getTable().getTopIndex();
+ final int botIdx = topIdx + getVisibleItemCount(topIdx);
+
+ // Request the item for the given index.
+ queryValue(index);
+
+ // Invoke a cancel task with a delay. The delay allows multiple cancel
+ // calls to be combined together improving performance of the viewer.
+ fCancelCallsPending++;
+ fDisplayExecutor.execute(
+ new Runnable() { public void run() {
+ cancelStaleRequests(topIdx, botIdx);
+ }});
+ }
+
+ /**
+ * Calculates the number of visible items based on the top item index and
+ * table bounds.
+ * @param top Index of top item.
+ * @return calculated number of items in viewer
+ */
+ private int getVisibleItemCount(int top) {
+ Table table = fViewer.getTable();
+ int itemCount = table.getItemCount();
+ return Math.min(
+ (table.getBounds().height / table.getItemHeight()) + 2,
+ itemCount - top);
+ }
+
+ /**
+ * Retrieve the current count. When a new count is set to viewer, the viewer
+ * will refresh all items as well.
+ */
+ private void queryItemCount() {
+ // Create the request monitor to collect the count. This request
+ // monitor will be completed by the following transaction.
+ final DataRequestMonitor rm =
+ new DataRequestMonitor(fDisplayExecutor, null)
+ {
+ @Override
+ protected void handleSuccess() {
+ setCountToViewer(getData());
+ }
+ @Override
+ protected void handleRejectedExecutionException() {} // Shutting down, ignore.
+ };
+
+ // Use a transaction, even with a single cache. This will ensure that
+ // if the cache is reset during processing by an event. The request
+ // for data will be re-issued.
+ fDataExecutor.execute(new Runnable() {
+ public void run() {
+ new Transaction() {
+ @Override
+ protected Integer process()
+ throws Transaction.InvalidCacheException, CoreException
+ {
+ return processCount(this);
+ }
+ }.request(rm);
+ }
+ });
+ }
+
+ /**
+ * Perform the count retrieval from the sum data generator.
+ * @param transaction The ACPM transaction to use for calculation.
+ * @return Calculated count.
+ * @throws Transaction.InvalidCacheException {@link Transaction#process}
+ * @throws CoreException See {@link Transaction#process}
+ */
+ private Integer processCount(Transaction transaction)
+ throws Transaction.InvalidCacheException, CoreException
+ {
+ ICache countCache = fSumGeneratorCM.getCount();
+ transaction.validate(countCache);
+ return countCache.getData();
+ }
+
+ /**
+ * Set the givne count to the viewer. This will cause the viewer will
+ * refresh all items' data as well.
+ *
Note: This method must be called in the display thread.
+ * @param count New count to set to viewer.
+ */
+ private void setCountToViewer(int count) {
+ if (!fViewer.getTable().isDisposed()) {
+ fViewer.setItemCount(count);
+ fViewer.getTable().clearAll();
+ }
+ }
+
+ /**
+ * Retrieve the current value for given index.
+ */
+ private void queryValue(final int index) {
+ // Create the request monitor to collect the value. This request
+ // monitor will be completed by the following transaction.
+ final ValueRequestMonitor rm = new ValueRequestMonitor(index) {
+ @Override
+ protected void handleCompleted() {
+ fItemDataRequestMonitors.remove(this);
+ if (isSuccess()) {
+ setValueToViewer(index, getData());
+ }
+ }
+ @Override
+ protected void handleRejectedExecutionException() {
+ // Shutting down, ignore.
+ }
+ };
+
+ // Save the value request monitor, to cancel it if the view is
+ // scrolled.
+ fItemDataRequestMonitors.add(rm);
+
+ // Use a transaction, even with a single cache. This will ensure that
+ // if the cache is reset during processing by an event. The request
+ // for data will be re-issued.
+ fDataExecutor.execute(new Runnable() {
+ public void run() {
+ new Transaction() {
+ @Override
+ protected String process()
+ throws Transaction.InvalidCacheException, CoreException
+ {
+ return processValue(this, index);
+ }
+ }.request(rm);
+ }
+ });
+ }
+
+ /**
+ * Write the view value to the viewer.
+ *
Note: This method must be called in the display thread.
+ * @param index Index of value to set.
+ * @param value New value.
+ */
+ private void setValueToViewer(int index, String value) {
+ if (!fViewer.getTable().isDisposed()) {
+ fViewer.replace(value, index);
+ }
+ }
+
+ /**
+ * Perform the calculation compose the string with data provider values
+ * and the sum. This implementation also validates the result.
+ * @param transaction The ACPM transaction to use for calculation.
+ * @param index Index of value to calculate.
+ * @return Calculated value.
+ * @throws Transaction.InvalidCacheException {@link Transaction#process}
+ * @throws CoreException See {@link Transaction#process}
+ */
+ private String processValue(Transaction transaction, int index)
+ throws Transaction.InvalidCacheException, CoreException
+ {
+ List> valueCaches =
+ new ArrayList>(fDataGeneratorCMs.length);
+ for (DataGeneratorCacheManager dataGeneratorCM : fDataGeneratorCMs) {
+ valueCaches.add(dataGeneratorCM.getValue(index));
+ }
+ // Validate all value caches at once. This executes needed requests
+ // in parallel.
+ transaction.validate(valueCaches);
+
+ // TODO: evaluate sum generator cache in parallel with value caches.
+ ICache sumCache = fSumGeneratorCM.getValue(index);
+ transaction.validate(sumCache);
+
+ // Compose the string with values, sum, and validation result.
+ StringBuilder result = new StringBuilder();
+ int calcSum = 0;
+ for (ICache valueCache : valueCaches) {
+ if (result.length() != 0) result.append(" + ");
+ result.append(valueCache.getData());
+ calcSum += valueCache.getData();
+ }
+ result.append(" = ");
+ result.append(sumCache.getData());
+ if (calcSum != sumCache.getData()) {
+ result.append(" !INCORRECT! ");
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Dedicated class for data item requests. This class holds the index
+ * argument so it can be examined when canceling stale requests.
+ */
+ private class ValueRequestMonitor extends DataRequestMonitor {
+ /** Index is used when canceling stale requests. */
+ int fIndex;
+
+ ValueRequestMonitor(int index) {
+ super(fDisplayExecutor, null);
+ fIndex = index;
+ }
+
+ @Override
+ protected void handleRejectedExecutionException() {
+ // Shutting down, ignore.
+ }
+ }
+
+ /**
+ * Cancels any outstanding value requests for items which are no longer
+ * visible in the viewer.
+ *
+ * @param topIdx Index of top visible item in viewer.
+ * @param botIdx Index of bottom visible item in viewer.
+ */
+ private void cancelStaleRequests(int topIdx, int botIdx) {
+ // Decrement the count of outstanding cancel calls.
+ fCancelCallsPending--;
+
+ // Must check again, in case disposed while re-dispatching.
+ if (fDataGeneratorCMs == null || fViewer.getTable().isDisposed()) {
+ return;
+ }
+
+ // Go through the outstanding requests and cancel any that
+ // are not visible anymore.
+ for (Iterator itr =
+ fItemDataRequestMonitors.iterator(); itr.hasNext();)
+ {
+ ValueRequestMonitor item = itr.next();
+ if (item.fIndex < topIdx || item.fIndex > botIdx) {
+ // Set the item to canceled status, so that the data provider
+ // will ignore it.
+ item.cancel();
+
+ // Add the item index to list of indexes that were canceled,
+ // which will be sent to the table widget.
+ fIndexesToCancel.add(item.fIndex);
+
+ // Remove the item from the outstanding cancel requests.
+ itr.remove();
+ }
+ }
+ if (!fIndexesToCancel.isEmpty() && fCancelCallsPending == 0) {
+ Set canceledIdxs = fIndexesToCancel;
+ fIndexesToCancel = new HashSet();
+
+ // Clear the indexes of the canceled request, so that the
+ // viewer knows to request them again when needed.
+ // Note: clearing using TableViewer.clear(int) seems very
+ // inefficient, it's better to use Table.clear(int[]).
+ int[] canceledIdxsArray = new int[canceledIdxs.size()];
+ int i = 0;
+ for (Integer index : canceledIdxs) {
+ canceledIdxsArray[i++] = index;
+ }
+ fViewer.getTable().clear(canceledIdxsArray);
+ }
+ }
+
+ /**
+ * The entry point for the example.
+ * @param args Program arguments.
+ */
+ public static void main(String[] args) {
+ // Create the shell to hold the viewer.
+ Display display = new Display();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+ shell.setLayout(new GridLayout());
+ GridData data = new GridData(GridData.FILL_BOTH);
+ shell.setLayoutData(data);
+ Font font = new Font(display, "Courier", 10, SWT.NORMAL);
+
+ // Create the table viewer.
+ TableViewer tableViewer =
+ new TableViewer(shell, SWT.BORDER | SWT.VIRTUAL);
+ tableViewer.getControl().setLayoutData(data);
+
+ DsfExecutor executor = new DefaultDsfExecutor("Example executor");
+
+ // Create the data generator.
+ final IDataGenerator[] generators = new IDataGenerator[5];
+ for (int i = 0; i < generators.length; i++) {
+ generators[i] = new DataGeneratorWithExecutor(executor);
+ }
+ final IDataGenerator sumGenerator =
+ new ACPMSumDataGenerator(executor, generators);
+
+ // Create the content provider which will populate the viewer.
+ ACPMSumDataViewer contentProvider = new ACPMSumDataViewer(
+ tableViewer, new ImmediateInDsfExecutor(executor),
+ generators, sumGenerator);
+ tableViewer.setContentProvider(contentProvider);
+ tableViewer.setInput(new Object());
+
+ // Open the shell and service the display dispatch loop until user
+ // closes the shell.
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+
+ // The IDataGenerator.shutdown() method is asynchronous, this requires
+ // using a query again in order to wait for its completion.
+ Query shutdownQuery = new Query() {
+ @Override
+ protected void execute(DataRequestMonitor rm) {
+ CountingRequestMonitor crm = new CountingRequestMonitor(
+ ImmediateExecutor.getInstance(), rm);
+ for (int i = 0; i < generators.length; i++) {
+ generators[i].shutdown(crm);
+ }
+ sumGenerator.shutdown(crm);
+ crm.setDoneCount(generators.length);
+ }
+ };
+
+ executor.execute(shutdownQuery);
+ try {
+ shutdownQuery.get();
+ } catch (Exception e) {}
+
+ // Shut down the display.
+ font.dispose();
+ display.dispose();
+ }
+}
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataGenerator.java b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataGenerator.java
new file mode 100644
index 00000000000..1d8a84c49e3
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataGenerator.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+//#ifdef exercises
+package org.eclipse.cdt.examples.dsf.dataviewer;
+//#else
+//#package org.eclipse.cdt.examples.dsf.dataviewer.answers;
+//#endif
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
+import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
+
+/**
+ * A data generator which performs a sum computation on data retrieved from a
+ * number of other data generators. The data retrieval from other generators
+ * is performed in parallel and the result is calculated once all data is
+ * received.
+ *
+ * This calculating generator does not listen to events from the data
+ * providers so it relies on the client to re-retrieve data as needed.
+ *
+ */
+public class AsyncSumDataGenerator implements IDataGenerator {
+
+ /**
+ * DSF executor used to serialize data access within this data generator.
+ */
+ final private DsfExecutor fExecutor;
+
+ /**
+ * Data generators to retrieve original data to perform calculations on.
+ */
+ final private IDataGenerator[] fDataGenerators;
+
+ public AsyncSumDataGenerator(DsfExecutor executor,
+ IDataGenerator[] generators)
+ {
+ fExecutor = executor;
+ fDataGenerators = generators;
+ }
+
+ public void getCount(final DataRequestMonitor rm) {
+ // Artificially delay the retrieval of the sum data to simulate
+ // real processing time.
+ fExecutor.schedule( new Runnable() {
+ public void run() {
+ doGetCount(rm);
+ }
+ },
+ PROCESSING_DELAY, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Performs the actual count retrieval and calculation.
+ * @param rm Request monitor to complete with data.
+ */
+ private void doGetCount(final DataRequestMonitor rm) {
+ // Array to store counts retrieved asynchronously
+ final int[] counts = new int[fDataGenerators.length];
+
+ // Counting request monitor is called once all data is retrieved.
+ final CountingRequestMonitor crm =
+ new CountingRequestMonitor(fExecutor, rm)
+ {
+ @Override
+ protected void handleSuccess() {
+ // Pick the highest count value.
+ Arrays.sort(counts, 0, counts.length - 1);
+ int maxCount = counts[counts.length - 1];
+ rm.setData(maxCount);
+ rm.done();
+ };
+ };
+
+ // Each call to data generator fills in one value in array.
+ for (int i = 0; i < fDataGenerators.length; i++) {
+ final int finalI = i;
+ fDataGenerators[i].getCount(
+ new DataRequestMonitor(
+ ImmediateExecutor.getInstance(), crm)
+ {
+ @Override
+ protected void handleSuccess() {
+ counts[finalI] = getData();
+ crm.done();
+ }
+ });
+ }
+ crm.setDoneCount(fDataGenerators.length);
+ }
+
+ public void getValue(final int index, final DataRequestMonitor rm)
+ {
+ // Artificially delay the retrieval of the sum data to simulate
+ // real processing time.
+ fExecutor.schedule( new Runnable() {
+ public void run() {
+ doGetValue(index, rm);
+ }
+ },
+ PROCESSING_DELAY, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Performs the actual value retrieval and calculation.
+ * @param rm Request monitor to complete with data.
+ */
+ private void doGetValue(int index, final DataRequestMonitor rm) {
+ // Array to store counts retrieved asynchronously
+ final int[] values = new int[fDataGenerators.length];
+
+ // Counting request monitor is called once all data is retrieved.
+ final CountingRequestMonitor crm =
+ new CountingRequestMonitor(fExecutor, rm)
+ {
+ @Override
+ protected void handleSuccess() {
+ // Sum up values in array.
+ int sum = 0;
+ for (int value : values) {
+ sum += value;
+ }
+ rm.setData(sum);
+ rm.done();
+ };
+ };
+
+ // Each call to data generator fills in one value in array.
+ for (int i = 0; i < fDataGenerators.length; i++) {
+ final int finalI = i;
+ fDataGenerators[i].getValue(
+ index,
+ new DataRequestMonitor(
+ ImmediateExecutor.getInstance(), crm)
+ {
+ @Override
+ protected void handleSuccess() {
+ values[finalI] = getData();
+ crm.done();
+ }
+ });
+ }
+ crm.setDoneCount(fDataGenerators.length);
+ }
+
+ public void shutdown(RequestMonitor rm) {
+ rm.done();
+ }
+
+ public void addListener(final Listener listener) {
+ // no events generated
+ }
+
+ public void removeListener(Listener listener) {
+ // no events generated
+ }
+
+}
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataViewer.java b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataViewer.java
new file mode 100644
index 00000000000..c34252562ee
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/AsyncSumDataViewer.java
@@ -0,0 +1,410 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+//#ifdef exercises
+package org.eclipse.cdt.examples.dsf.dataviewer;
+//#else
+//#package org.eclipse.cdt.examples.dsf.dataviewer.answers;
+//#endif
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DefaultDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
+import org.eclipse.cdt.dsf.concurrent.Query;
+import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
+import org.eclipse.cdt.dsf.ui.concurrent.DisplayDsfExecutor;
+import org.eclipse.jface.viewers.ILazyContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * Data viewer based on a table, which reads data from multiple data
+ * providers using asynchronous methods and performs a compultation
+ * on the retrieved data.
+ *
+ * This example builds on the {@link AsyncDataViewer} example and
+ * demonstrates the pitfalls of retrieving data from multiple sources
+ * asynchronously: The data is retrieved separate from a set of providers
+ * as well as from a data provider that sums the values from the other
+ * providers. The viewer then performs a check to ensure consistency of
+ * retrieved data. If the retrieved data is inconsistent an "INCORRECT"
+ * label is added in the viewer.
+ *
+ *
+ * This viewer is updated periodically every 10 seconds, instead of being
+ * updated with every change in every data provider, which would overwhelm
+ * the viewer.
+ *
+ */
+@ConfinedToDsfExecutor("fDisplayExecutor")
+public class AsyncSumDataViewer implements ILazyContentProvider
+{
+ /** View update frequency interval. */
+ final private static int UPDATE_INTERVAL = 10000;
+
+ /** Executor to use instead of Display.asyncExec(). **/
+ @ThreadSafe
+ final private DsfExecutor fDisplayExecutor;
+
+ // The viewer and generator that this content provider using.
+ final private TableViewer fViewer;
+ final private IDataGenerator[] fDataGenerators;
+ final private IDataGenerator fSumGenerator;
+
+ // Fields used in request cancellation logic.
+ private List fItemDataRequestMonitors =
+ new LinkedList();
+ private Set fIndexesToCancel = new HashSet();
+ private int fCancelCallsPending = 0;
+ private Future> fRefreshFuture;
+
+ public AsyncSumDataViewer(TableViewer viewer,
+ IDataGenerator[] generators, IDataGenerator sumGenerator)
+ {
+ fViewer = viewer;
+ fDisplayExecutor = DisplayDsfExecutor.getDisplayDsfExecutor(
+ fViewer.getTable().getDisplay());
+ fDataGenerators = generators;
+ fSumGenerator = sumGenerator;
+
+ // Schedule a task to refresh the viewer periodically.
+ fRefreshFuture = fDisplayExecutor.scheduleAtFixedRate(
+ new Runnable() {
+ public void run() {
+ queryItemCount();
+ }
+ },
+ UPDATE_INTERVAL, UPDATE_INTERVAL, TimeUnit.MILLISECONDS);
+ }
+
+ public void dispose() {
+ // Cancel the periodic task of refreshing the view.
+ fRefreshFuture.cancel(false);
+
+ // Cancel any outstanding data requests.
+ for (ValueCountingRequestMonitor rm : fItemDataRequestMonitors) {
+ rm.cancel();
+ }
+ fItemDataRequestMonitors.clear();
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // Set the initial count to the viewer after the input is set.
+ queryItemCount();
+ }
+
+ public void updateElement(final int index) {
+ // Calculate the visible index range.
+ final int topIdx = fViewer.getTable().getTopIndex();
+ final int botIdx = topIdx + getVisibleItemCount(topIdx);
+
+ // Request the item for the given index.
+ queryValue(index);
+
+ // Invoke a cancel task with a delay. The delay allows multiple cancel
+ // calls to be combined together improving performance of the viewer.
+ fCancelCallsPending++;
+ fDisplayExecutor.execute(
+ new Runnable() { public void run() {
+ cancelStaleRequests(topIdx, botIdx);
+ }});
+ }
+
+ /**
+ * Calculates the number of visible items based on the top item index and
+ * table bounds.
+ * @param top Index of top item.
+ * @return calculated number of items in viewer
+ */
+ private int getVisibleItemCount(int top) {
+ Table table = fViewer.getTable();
+ int itemCount = table.getItemCount();
+ return Math.min(
+ (table.getBounds().height / table.getItemHeight()) + 2,
+ itemCount - top);
+ }
+
+ /**
+ * Retrieve the up to date count.
+ */
+ private void queryItemCount() {
+ // Note:The count is retrieved from the sum generator only, the sum
+ // generator is responsible for calculating the count based on
+ // individual data providers' counts.
+ fIndexesToCancel.clear();
+ fSumGenerator.getCount(
+ new DataRequestMonitor(fDisplayExecutor, null) {
+ @Override
+ protected void handleSuccess() {
+ setCountToViewer(getData());
+ }
+ @Override
+ protected void handleRejectedExecutionException() {
+ // Shutting down, ignore.
+ }
+ });
+ }
+
+ /**
+ * Set the givne count to the viewer. This will cause the viewer will
+ * refresh all items' data as well.
+ * @param count New count to set to viewer.
+ */
+ private void setCountToViewer(int count) {
+ if (!fViewer.getTable().isDisposed()) {
+ fViewer.setItemCount(count);
+ fViewer.getTable().clearAll();
+ }
+ }
+
+ /**
+ * Retrieves value of an element at given index. When complete the value
+ * is written to the viewer.
+ * @param index Index of value to retrieve.
+ */
+ private void queryValue(final int index) {
+ // Values retrieved asynchronously from providers are stored in local
+ // arrays.
+ final int[] values = new int[fDataGenerators.length];
+ final int[] sum = new int[1];
+
+ // Counting request monitor is invoked when the required number of
+ // value requests is completed.
+ final ValueCountingRequestMonitor crm =
+ new ValueCountingRequestMonitor(index)
+ {
+ @Override
+ protected void handleCompleted() {
+ fItemDataRequestMonitors.remove(this);
+
+ // Check if the request completed successfully, otherwise
+ // ignore it.
+ if (isSuccess()) {
+ StringBuilder result = new StringBuilder();
+ int calcSum = 0;
+ for (int value : values) {
+ if (result.length() != 0) result.append(" + ");
+ result.append(value);
+ calcSum += value;
+ }
+ result.append(" = ");
+ result.append(sum[0]);
+ if (calcSum != sum[0]) {
+ result.append(" !INCORRECT! ");
+ }
+ setValueToViewer(fIndex, result.toString());
+ }
+ };
+ };
+
+ // Request data from each data generator.
+ for (int i = 0; i < fDataGenerators.length; i++) {
+ final int finalI = i;
+ fDataGenerators[i].getValue(
+ index,
+ // Use the display executor to construct the request monitor,
+ // this will cause the handleCompleted() method to be
+ // automatically called on the display thread.
+ new DataRequestMonitor(
+ ImmediateExecutor.getInstance(), crm)
+ {
+ @Override
+ protected void handleSuccess() {
+ values[finalI] = getData();
+ crm.done();
+ }
+ });
+ }
+
+ // Separately request data from the sum data generator.
+ fSumGenerator.getValue(
+ index,
+ new DataRequestMonitor(
+ ImmediateExecutor.getInstance(), crm)
+ {
+ @Override
+ protected void handleSuccess() {
+ sum[0] = getData();
+ crm.done();
+ }
+ });
+
+ crm.setDoneCount(fDataGenerators.length + 1);
+ fItemDataRequestMonitors.add(crm);
+ }
+
+ /**
+ * Write the view value to the viewer.
+ *
Note: This method must be called in the display thread.
+ * @param index Index of value to set.
+ * @param value New value.
+ */
+ private void setValueToViewer(int index, String value) {
+ if (!fViewer.getTable().isDisposed()) {
+ fViewer.replace(value, index);
+ }
+ }
+
+ /**
+ * Dedicated class for data item requests. This class holds the index
+ * argument so it can be examined when canceling stale requests.
+ */
+ private class ValueCountingRequestMonitor extends CountingRequestMonitor {
+ /** Index is used when canceling stale requests. */
+ int fIndex;
+
+ ValueCountingRequestMonitor(int index) {
+ super(fDisplayExecutor, null);
+ fIndex = index;
+ }
+
+ @Override
+ protected void handleRejectedExecutionException() {
+ // Shutting down, ignore.
+ }
+ }
+
+ /**
+ * Cancels any outstanding value requests for items which are no longer
+ * visible in the viewer.
+ *
+ * @param topIdx Index of top visible item in viewer.
+ * @param botIdx Index of bottom visible item in viewer.
+ */
+ private void cancelStaleRequests(int topIdx, int botIdx) {
+ // Decrement the count of outstanding cancel calls.
+ fCancelCallsPending--;
+
+ // Must check again, in case disposed while re-dispatching.
+ if (fDataGenerators == null || fViewer.getTable().isDisposed()) return;
+
+ // Go through the outstanding requests and cancel any that
+ // are not visible anymore.
+ for (Iterator itr =
+ fItemDataRequestMonitors.iterator(); itr.hasNext();)
+ {
+ ValueCountingRequestMonitor item = itr.next();
+ if (item.fIndex < topIdx || item.fIndex > botIdx) {
+ // Set the item to canceled status, so that the data provider
+ // will ignore it.
+ item.cancel();
+
+ // Add the item index to list of indexes that were canceled,
+ // which will be sent to the table widget.
+ fIndexesToCancel.add(item.fIndex);
+
+ // Remove the item from the outstanding cancel requests.
+ itr.remove();
+ }
+ }
+ if (!fIndexesToCancel.isEmpty() && fCancelCallsPending == 0) {
+ Set canceledIdxs = fIndexesToCancel;
+ fIndexesToCancel = new HashSet();
+
+ // Clear the indexes of the canceled request, so that the
+ // viewer knows to request them again when needed.
+ // Note: clearing using TableViewer.clear(int) seems very
+ // inefficient, it's better to use Table.clear(int[]).
+ int[] canceledIdxsArray = new int[canceledIdxs.size()];
+ int i = 0;
+ for (Integer index : canceledIdxs) {
+ canceledIdxsArray[i++] = index;
+ }
+ fViewer.getTable().clear(canceledIdxsArray);
+ }
+ }
+
+ /**
+ * The entry point for the example.
+ * @param args Program arguments.
+ */
+ public static void main(String[] args) {
+ // Create the shell to hold the viewer.
+ Display display = new Display();
+ Shell shell = new Shell(display, SWT.SHELL_TRIM);
+ shell.setLayout(new GridLayout());
+ GridData data = new GridData(GridData.FILL_BOTH);
+ shell.setLayoutData(data);
+ Font font = new Font(display, "Courier", 10, SWT.NORMAL);
+
+ // Create the table viewer.
+ TableViewer tableViewer =
+ new TableViewer(shell, SWT.BORDER | SWT.VIRTUAL);
+ tableViewer.getControl().setLayoutData(data);
+
+ // Single executor (and single thread) is used by all data generators,
+ // including the sum generator.
+ DsfExecutor executor = new DefaultDsfExecutor("Example executor");
+
+ // Create the data generator.
+ final IDataGenerator[] generators = new IDataGenerator[5];
+ for (int i = 0; i < generators.length; i++) {
+ generators[i] = new DataGeneratorWithExecutor(executor);
+ }
+ final IDataGenerator sumGenerator =
+ new AsyncSumDataGenerator(executor, generators);
+
+ // Create the content provider which will populate the viewer.
+ AsyncSumDataViewer contentProvider =
+ new AsyncSumDataViewer(tableViewer, generators, sumGenerator);
+ tableViewer.setContentProvider(contentProvider);
+ tableViewer.setInput(new Object());
+
+ // Open the shell and service the display dispatch loop until user
+ // closes the shell.
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+
+ // The IDataGenerator.shutdown() method is asynchronous, this requires
+ // using a query again in order to wait for its completion.
+ Query shutdownQuery = new Query() {
+ @Override
+ protected void execute(DataRequestMonitor rm) {
+ CountingRequestMonitor crm = new CountingRequestMonitor(
+ ImmediateExecutor.getInstance(), rm);
+ for (int i = 0; i < generators.length; i++) {
+ generators[i].shutdown(crm);
+ }
+ sumGenerator.shutdown(crm);
+ crm.setDoneCount(generators.length);
+ }
+ };
+
+ executor.execute(shutdownQuery);
+ try {
+ shutdownQuery.get();
+ } catch (Exception e) {}
+
+ // Shut down the display.
+ font.dispose();
+ display.dispose();
+ }
+}
diff --git a/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/DataGeneratorCacheManager.java b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/DataGeneratorCacheManager.java
new file mode 100644
index 00000000000..1e1d4e74e89
--- /dev/null
+++ b/dsf/org.eclipse.cdt.examples.dsf/src_preprocess/org/eclipse/cdt/examples/dsf/dataviewer/DataGeneratorCacheManager.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+//#ifdef exercises
+package org.eclipse.cdt.examples.dsf.dataviewer;
+//#else
+//#package org.eclipse.cdt.examples.dsf.dataviewer.answers;
+//#endif
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.ICache;
+import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.RequestCache;
+import org.eclipse.cdt.examples.dsf.DsfExamplesPlugin;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * A wrapper class for the {@link IDataGenerator} interface, which returns
+ * ACPM cache objects to use for data retrieval instead of calling
+ * {@link IDataGenerator} asynchronous methods directly.
+ */
+public class DataGeneratorCacheManager implements IDataGenerator.Listener {
+
+ /** Cache class for retrieving the data generator's count. */
+ private class CountCache extends RequestCache {
+
+ public CountCache() {
+ super(fExecutor);
+ }
+
+ @Override
+ protected void retrieve(DataRequestMonitor rm) {
+ fDataGenerator.getCount(rm);
+ }
+
+ /**
+ * Reset the cache when the count is changed.
+ */
+ public void countChanged() {
+ // Make sure that if clients are currently waiting for a count,
+ // they are notified of the update (their request monitors will be
+ // completed with an error). They shoudl then re-request data
+ // from provider again.
+ setAndReset(null, new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Count changed"));
+ }
+ }
+
+ /** Cache class for retrieving the data generator's values. */
+ private class ValueCache extends RequestCache {
+ private int fIndex;
+
+ public ValueCache(int index) {
+ super(fExecutor);
+ fIndex = index;
+ }
+
+ @Override
+ protected void retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor rm) {
+ fDataGenerator.getValue(fIndex, rm);
+ };
+
+ /**
+ * @see CountCache#countChanged()
+ */
+ public void valueChanged() {
+ setAndReset(null, new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Value changed"));
+ }
+ }
+
+ /**
+ * Executor used to synchronize data access in this cache manager.
+ * It has to be the same executor that is used by the data generators in
+ * order to guarantee data consistency.
+ */
+ private ImmediateInDsfExecutor fExecutor;
+
+ /**
+ * Data generator that this cache manager is a wrapper for.
+ */
+ private IDataGenerator fDataGenerator;
+
+ /** Cache for data generator's count */
+ private CountCache fCountCache;
+
+ /**
+ * Map of caches for retrieving values. Each value index has a separate
+ * cache value object.
+ */
+ private Map fValueCaches = new HashMap();
+
+ public DataGeneratorCacheManager(ImmediateInDsfExecutor executor, IDataGenerator dataGenerator) {
+ fExecutor = executor;
+ fDataGenerator = dataGenerator;
+ fDataGenerator.addListener(this);
+ }
+
+ public void dispose() {
+ fDataGenerator.removeListener(this);
+ }
+
+ /**
+ * Returns the data generator that this cache manager wraps.
+ */
+ public IDataGenerator getDataGenerator() {
+ return fDataGenerator;
+ }
+
+ /**
+ * Returns the cache for data generator count.
+ */
+ public ICache getCount() {
+ if (fCountCache == null) {
+ fCountCache = new CountCache();
+ }
+ return fCountCache;
+ }
+
+ /**
+ * Returns the cache for a value at given index.
+ *
+ * @param index Index of value to return.
+ * @return Cache object for given value.
+ */
+ public ICache getValue(int index) {
+ ValueCache value = fValueCaches.get(index);
+ if (value == null) {
+ value = new ValueCache(index);
+ fValueCaches.put(index, value);
+ }
+
+ return value;
+ }
+
+ public void countChanged() {
+ // Reset the count cache and all the value caches.
+ if (fCountCache != null) {
+ fCountCache.countChanged();
+ }
+ for (ValueCache value : fValueCaches.values()) {
+ value.valueChanged();
+ }
+ }
+
+ public void valuesChanged(Set indexes) {
+ // Reset selected value caches.
+ for (Integer index : indexes) {
+ ValueCache value = fValueCaches.get(index);
+ if (value != null) {
+ value.valueChanged();
+ }
+ }
+ }
+}
From b140bf8ba6e96869a322826338b86beb777db5b5 Mon Sep 17 00:00:00 2001
From: Sergey Prigogin
Date: Mon, 5 Dec 2011 19:40:53 -0800
Subject: [PATCH 15/20] Override annotations.
---
.../org/eclipse/cdt/core/dom/ast/IASTDeclarator.java | 7 ++++---
.../cdt/core/dom/ast/IASTPointerOperator.java | 7 ++++---
.../core/dom/ast/cpp/ICPPASTReferenceOperator.java | 7 ++++---
.../core/dom/parser/cpp/CPPASTReferenceOperator.java | 12 +++++++-----
4 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTDeclarator.java
index cc055191b56..f1d6994bd64 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTDeclarator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTDeclarator.java
@@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Doug Schaefer (IBM) - Initial API and implementation
+ * Doug Schaefer (IBM) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@@ -17,11 +17,10 @@ package org.eclipse.cdt.core.dom.ast;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTDeclarator extends IASTNode, IASTNameOwner {
-
/**
* Constant - empty declarator array
*/
- public static final IASTDeclarator[] EMPTY_DECLARATOR_ARRAY = new IASTDeclarator[0];
+ public static final IASTDeclarator[] EMPTY_DECLARATOR_ARRAY = {};
/**
* POINTER_OPERATOR represents the relationship between an
@@ -111,10 +110,12 @@ public interface IASTDeclarator extends IASTNode, IASTNameOwner {
/**
* @since 5.1
*/
+ @Override
public IASTDeclarator copy();
/**
* @since 5.3
*/
+ @Override
public IASTDeclarator copy(CopyStyle style);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPointerOperator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPointerOperator.java
index fe5a585b3ec..343a115cb88 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPointerOperator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPointerOperator.java
@@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Doug Schaefer (IBM) - Initial API and implementation
+ * Doug Schaefer (IBM) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@@ -15,19 +15,20 @@ package org.eclipse.cdt.core.dom.ast;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTPointerOperator extends IASTNode {
-
/**
* Constant/sentinel.
*/
- public static final IASTPointerOperator[] EMPTY_ARRAY = new IASTPointerOperator[0];
+ public static final IASTPointerOperator[] EMPTY_ARRAY = {};
/**
* @since 5.1
*/
+ @Override
public IASTPointerOperator copy();
/**
* @since 5.3
*/
+ @Override
public IASTPointerOperator copy(CopyStyle style);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java
index c0145224e29..37c8c0c0808 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java
@@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Doug Schaefer (IBM) - Initial API and implementation
- * Markus Schorn (Wind River Systems)
+ * Doug Schaefer (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPASTReferenceOperator extends IASTPointerOperator {
-
/**
* Returns whether the operator denotes a rvalue reference (e.g. int &&).
* @since 5.2
@@ -30,10 +29,12 @@ public interface ICPPASTReferenceOperator extends IASTPointerOperator {
/**
* @since 5.1
*/
+ @Override
public ICPPASTReferenceOperator copy();
/**
* @since 5.3
*/
+ @Override
public ICPPASTReferenceOperator copy(CopyStyle style);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java
index 3820b979e29..395d54479af 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java
@@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * John Camelon (IBM) - Initial API and implementation
- * Markus Schorn (Wind River Systems)
+ * John Camelon (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -19,21 +19,23 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
* Reference operator for declarators.
*/
public class CPPASTReferenceOperator extends ASTNode implements ICPPASTReferenceOperator {
-
private final boolean fIsRValue;
public CPPASTReferenceOperator(boolean isRValueReference) {
fIsRValue= isRValueReference;
}
+ @Override
public boolean isRValueReference() {
return fIsRValue;
}
+ @Override
public CPPASTReferenceOperator copy() {
return copy(CopyStyle.withoutLocations);
}
+ @Override
public CPPASTReferenceOperator copy(CopyStyle style) {
CPPASTReferenceOperator copy = new CPPASTReferenceOperator(fIsRValue);
copy.setOffsetAndLength(this);
@@ -47,8 +49,8 @@ public class CPPASTReferenceOperator extends ASTNode implements ICPPASTReference
public boolean accept(ASTVisitor action) {
if (action.shouldVisitPointerOperators) {
switch (action.visit(this)) {
- case ASTVisitor.PROCESS_ABORT : return false;
- case ASTVisitor.PROCESS_SKIP : return true;
+ case ASTVisitor.PROCESS_ABORT: return false;
+ case ASTVisitor.PROCESS_SKIP: return true;
}
if (action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
From 693a79de5e0523e50843baa4eac7daa8a183b66d Mon Sep 17 00:00:00 2001
From: Sergey Prigogin
Date: Mon, 5 Dec 2011 19:48:09 -0800
Subject: [PATCH 16/20] Fixed typos.
---
.../internal/core/Configuration.java | 8 ++++----
.../ClassMembersInitializationChecker.java | 14 +++++++-------
.../ClassMembersInitializationCheckerTest.java | 10 +++++-----
.../core/internal/checkers/ReturnCheckerTest.java | 4 ++--
.../cdt/ui/actions/GenerateActionGroup.java | 8 ++++----
.../cdt/ui/dialogs/AbstractErrorParserBlock.java | 2 +-
6 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
index 011aa7ccbe4..102a944c669 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
@@ -337,9 +337,9 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if (parentConfig != null) {
name = parentConfig.getName();
- // If this contructor is called to clone an existing
+ // If this constructor is called to clone an existing
// configuration, the parent of the parent should be stored.
- // As of 2.1, there is still one single level of inheritence to
+ // As of 2.1, there is still one single level of inheritance to
// worry about
parent = parentConfig.getParent() == null ? parentConfig : parentConfig.getParent();
}
@@ -485,7 +485,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
// if(!baseCfg.isExtensionConfig)
// cloneChildren = true;
- // If this contructor is called to clone an existing
+ // If this constructor is called to clone an existing
// configuration, the parent of the cloning config should be stored.
parent = baseCfg.isExtensionConfig || baseCfg.getParent() == null ? baseCfg : baseCfg.getParent();
@@ -633,7 +633,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if(!cloneConfig.isExtensionConfig)
cloneChildren = true;
- // If this contructor is called to clone an existing
+ // If this constructor is called to clone an existing
// configuration, the parent of the cloning config should be stored.
parent = cloneConfig.isExtensionConfig || cloneConfig.getParent() == null ? cloneConfig : cloneConfig.getParent();
parentId = parent.getId();
diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java
index c0d16049b3c..5de06044fcc 100644
--- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java
+++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java
@@ -98,8 +98,8 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
public int visit(IASTExpression expression) {
if (!constructorsStack.empty() && expression instanceof IASTFunctionCallExpression) {
- Set actualContructorFields = constructorsStack.peek();
- if (!actualContructorFields.isEmpty()) {
+ Set actualConstructorFields = constructorsStack.peek();
+ if (!actualConstructorFields.isEmpty()) {
boolean skipCurrentConstructor = false;
IASTFunctionCallExpression fCall = (IASTFunctionCallExpression)expression;
IASTExpression fNameExp = fCall.getFunctionNameExpression();
@@ -108,7 +108,7 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
IBinding fBinding = fName.getName().resolveBinding();
if (fBinding instanceof ICPPMethod) {
ICPPMethod method = (ICPPMethod)fBinding;
- ICompositeType constructorOwner = actualContructorFields.iterator().next().getCompositeTypeOwner();
+ ICompositeType constructorOwner = actualConstructorFields.iterator().next().getCompositeTypeOwner();
if (constructorOwner == method.getClassOwner() && !method.getType().isConst()) {
skipCurrentConstructor = true;
}
@@ -152,12 +152,12 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
public int visit(IASTName name) {
if (!constructorsStack.empty()) {
- Set actualContructorFields = constructorsStack.peek();
- if (!actualContructorFields.isEmpty()) {
+ Set actualConstructorFields = constructorsStack.peek();
+ if (!actualConstructorFields.isEmpty()) {
IBinding binding = name.resolveBinding();
- if (actualContructorFields.contains(binding)) {
+ if (actualConstructorFields.contains(binding)) {
if ((CPPVariableReadWriteFlags.getReadWriteFlags(name) & PDOMName.WRITE_ACCESS) != 0) {
- actualContructorFields.remove(binding);
+ actualConstructorFields.remove(binding);
}
}
}
diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java
index a0b261b1db6..343a37d16ae 100644
--- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java
+++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java
@@ -53,7 +53,7 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
// int m;
// C() { m = 0; } // No warnings.
// };
- public void testAssignmentsInContructorShouldBeChecked() {
+ public void testAssignmentsInConstructorShouldBeChecked() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
@@ -171,7 +171,7 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
// int i1, i2;
// };
// C::C() : i1(0) {} // 1 warning for: i2.
- public void testExternalContructorHandling() {
+ public void testExternalConstructorHandling() {
loadCodeAndRun(getAboveComment());
checkErrorLines(5);
}
@@ -184,7 +184,7 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
// T2 t2;
// };
// C::C() : i1(0), t1(T1()) {} // 1 warning for: i2.
- public void testExternalContructorOfTemplateClassHandling() {
+ public void testExternalConstructorOfTemplateClassHandling() {
loadCodeAndRun(getAboveComment());
checkErrorLines(8);
}
@@ -196,7 +196,7 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
// };
// template
// C::C() : i1(0) {} // 1 warning for: i2.
- public void testExternalTemplateContructorHandling() {
+ public void testExternalTemplateConstructorHandling() {
loadCodeAndRun(getAboveComment());
checkErrorLines(7);
}
@@ -212,7 +212,7 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
// template
// template
// C::C() : i1(0), t1(T1()) {} // 1 warning for: i2.
- public void testExternalTemplateContructorOfTemplateClassHandling() {
+ public void testExternalTemplateConstructorOfTemplateClassHandling() {
loadCodeAndRun(getAboveComment());
checkErrorLines(11);
}
diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java
index 9a09a8c7d8a..95519bf9fb6 100644
--- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java
+++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java
@@ -122,7 +122,7 @@ public class ReturnCheckerTest extends CheckerTestCase {
// return;
// }
// };
- public void testContructorRetValue() {
+ public void testConstructorRetValue() {
loadCodeAndRunCpp(getAboveComment());
checkErrorLine(3, ReturnChecker.RET_ERR_VALUE_ID);
}
@@ -136,7 +136,7 @@ public class ReturnCheckerTest extends CheckerTestCase {
// return;
// }
// };
- public void testContructor_Bug323602() {
+ public void testConstructor_Bug323602() {
IProblemPreference macro = getPreference(ReturnChecker.RET_NO_VALUE_ID, ReturnChecker.PARAM_IMPLICIT);
macro.setValue(Boolean.TRUE);
loadCodeAndRunCpp(getAboveComment());
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/GenerateActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/GenerateActionGroup.java
index 573ff899f32..b7987e54557 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/GenerateActionGroup.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/GenerateActionGroup.java
@@ -192,8 +192,8 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
// editor.setAction("AddDelegateMethods", fAddDelegateMethods); //$NON-NLS-1$
//
// fAddUnimplementedConstructors= new AddUnimplementedConstructorsAction(editor);
-// fAddUnimplementedConstructors.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_UNIMPLEMENTED_CONTRUCTORS);
-// editor.setAction("AddUnimplementedConstructors", fAddUnimplementedConstructors); //$NON-NLS-1$
+// fAddUnimplementedConstructors.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_UNIMPLEMENTED_CONSTRUCTORS);
+// editor.setAction("AddUnimplementedConstructors", fAddUnimplementedConstructors); //$NON-NLS-1$
//
// fGenerateConstructorUsingFields= new GenerateNewConstructorUsingFieldsAction(editor);
// fGenerateConstructorUsingFields.setActionDefinitionId(ICEditorActionDefinitionIds.GENERATE_CONSTRUCTOR_USING_FIELDS);
@@ -277,8 +277,8 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
// fAddDelegateMethods.setActionDefinitionId(ICEditorActionDefinitionIds.CREATE_DELEGATE_METHODS);
//
// fAddUnimplementedConstructors= new AddUnimplementedConstructorsAction(site);
-// fAddUnimplementedConstructors.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_UNIMPLEMENTED_CONTRUCTORS);
-//
+// fAddUnimplementedConstructors.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_UNIMPLEMENTED_CONSTRUCTORS);
+//
// fGenerateConstructorUsingFields= new GenerateNewConstructorUsingFieldsAction(site);
// fGenerateConstructorUsingFields.setActionDefinitionId(ICEditorActionDefinitionIds.GENERATE_CONSTRUCTOR_USING_FIELDS);
//
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractErrorParserBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractErrorParserBlock.java
index 8edd62c37e5..de9da25118b 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractErrorParserBlock.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractErrorParserBlock.java
@@ -80,7 +80,7 @@ public abstract class AbstractErrorParserBlock extends AbstractCOptionPage {
@Deprecated
public AbstractErrorParserBlock(Preferences prefs) {
this();
-// usingDeprecatedContructor = true;
+// usingDeprecatedConstructor = true;
fPrefs = prefs;
}
From 253ba9ddefbf660d5fb0676a99d0b270673674f4 Mon Sep 17 00:00:00 2001
From: Sergey Prigogin
Date: Mon, 5 Dec 2011 19:51:33 -0800
Subject: [PATCH 17/20] Bug 319279. Passing parameter and return value by
reference.
---
.../tests/ast2/ClassTypeHelperTests.java | 9 +
.../cdt/core/dom/rewrite/TypeHelper.java | 5 +-
.../refactoring/GenerateGettersAndSetters.rts | 156 ++++++++------
.../gettersandsetters/FunctionFactory.java | 203 ------------------
.../GetterSetterInsertEditProvider.java | 16 +-
5 files changed, 107 insertions(+), 282 deletions(-)
delete mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java
index f3454e8e5cd..e45445d956a 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java
@@ -14,7 +14,9 @@ import java.io.IOException;
import junit.framework.TestSuite;
+import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.parser.util.ASTPrinter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.parser.ParserException;
@@ -39,6 +41,13 @@ public class ClassTypeHelperTests extends AST2BaseTest {
return new BindingAssertionHelper(code, true);
}
+ // int a;
+ // const int& b;
+ public void testTemp() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ ASTPrinter.print(helper.getTranslationUnit());
+ }
+
// struct A {
// A(const A& a);
// };
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java
index d3c7d53c6e7..222d970da17 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java
@@ -52,10 +52,9 @@ public class TypeHelper {
}
SizeofCalculator calc = ((ASTTranslationUnit) ast).getSizeofCalculator();
SizeAndAlignment sizeofPointer = calc.sizeAndAlignmentOfPointer();
- if (sizeofPointer == null)
- return true;
+ long maxSize = sizeofPointer != null ? sizeofPointer.size : 4;
SizeAndAlignment sizeofType = calc.sizeAndAlignment(type);
- if (sizeofType == null || sizeofType.size > sizeofPointer.size)
+ if (sizeofType == null || sizeofType.size > maxSize)
return true;
}
return false;
diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts
index f81bfc2c568..3afa9b7a863 100644
--- a/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts
+++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts
@@ -30,7 +30,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -53,7 +53,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
#define C_H_
@@ -70,7 +70,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -97,7 +97,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters One Getter Selection with Namespace
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
//@.config
@@ -132,7 +132,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -157,7 +157,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
@@ -177,7 +177,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -206,7 +206,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters One Setter Selection
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
@@ -240,7 +240,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -264,7 +264,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
#define C_H_
@@ -281,7 +281,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -309,7 +309,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters Getter and Setter Selection
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
//@.config
@@ -343,7 +343,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -367,7 +367,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
#define C_H_
@@ -384,7 +384,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -416,7 +416,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters Multiple Selection
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
//@.config
@@ -450,7 +450,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -465,7 +465,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
@@ -499,7 +499,7 @@ public:
this->systemId = systemId;
}
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -514,7 +514,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters Visibility order 1
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
@@ -596,7 +596,7 @@ private:
int /*$*/id/*$$*/;
};
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
@@ -616,7 +616,7 @@ public:
}
};
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters no Methods
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
@@ -704,53 +704,37 @@ class test {
#endif /* TEST_H_ */
-//!Generate Getters and Setters One Getter Selection Separate Definition
+//!Generate Getters and Setters, Pass by Reference, Separate Definition
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
//@.config
filename=C.h
getters=name
+setters=name
definitionSeparate=true
-//@C.cpp
-#include "C.h"
-
-int Person::SocSecNo() {
- return socSecNo;
-}
-
-int main(int argc, char** argv) {
-}
-
-//=
-#include "C.h"
-
-char* Person::getName() const {
- return name;
-}
-
-int Person::SocSecNo() {
- return socSecNo;
-}
-
-int main(int argc, char** argv) {
-}
-
//@C.h
#ifndef C_H_
#define C_H_
+struct FullName {
+ const char* first;
+ const char* last;
+ FullName(const FullName& other);
+ ~FullName();
+};
+
class Person {
private:
int systemId;
protected:
- char* name;
+ FullName name;
public:
const int socSecNo;
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -769,25 +753,33 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
#define C_H_
+struct FullName {
+ const char* first;
+ const char* last;
+ FullName(const FullName& other);
+ ~FullName();
+};
+
class Person {
private:
int systemId;
protected:
- char* name;
+ FullName name;
public:
const int socSecNo;
Person myFriend;
- char* getName() const;
+ const FullName& getName() const;
+ void setName(const FullName& name);
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -806,7 +798,35 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
+//@C.cpp
+#include "C.h"
+
+int Person::SocSecNo() {
+ return socSecNo;
+}
+
+int main(int argc, char** argv) {
+}
+
+//=
+#include "C.h"
+
+const FullName& Person::getName() const {
+ return name;
+}
+
+void Person::setName(const FullName& name) {
+ this->name = name;
+}
+
+int Person::SocSecNo() {
+ return socSecNo;
+}
+
+int main(int argc, char** argv) {
+}
+
//!Generate Getters and Setters One Getter Selection with Namespace Separate Definition
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
//@.config
@@ -863,7 +883,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -888,7 +908,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
@@ -908,7 +928,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -934,7 +954,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters One Setter Selection Separate Definition
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
@@ -984,7 +1004,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -1008,7 +1028,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
#define C_H_
@@ -1025,7 +1045,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -1050,7 +1070,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Getter and Setter Selection Separate Definition
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
//@.config
@@ -1102,7 +1122,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -1126,7 +1146,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
@@ -1144,7 +1164,7 @@ public:
Person myFriend;
- Person(int socSecNo); // contructor
+ Person(int socSecNo); // constructor
~Person(); // destructor
@@ -1170,7 +1190,7 @@ public:
int gooo = 1;
-#endif /*C_H_*/
+#endif /* C_H_ */
//!Generate Getters and Setters no Methods Separate Definition
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
@@ -1188,7 +1208,7 @@ private:
int /*$*/id/*$$*/;
};
-#endif /*C_H_*/
+#endif /* C_H_ */
//=
#ifndef C_H_
@@ -1212,7 +1232,7 @@ inline void Person::setId(int id) {
}
-#endif /*C_H_*/
+#endif /* C_H_ */
//!No Methods Separate Definition
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java
deleted file mode 100644
index fa5f8886718..00000000000
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
- * Rapperswil, University of applied sciences and others
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Institute for Software - initial API and implementation
- * Sergey Prigogin (Google)
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
-
-import java.util.Arrays;
-
-import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
-import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
-import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
-import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
-import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
-import org.eclipse.cdt.core.dom.ast.IASTName;
-import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
-import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
-import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
-import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
-import org.eclipse.cdt.core.parser.Keywords;
-
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionStatement;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
-
-public class FunctionFactory {
-
- public static IASTFunctionDefinition createGetterDefinition(IASTName fieldName,
- IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
- IASTFunctionDefinition getter = new CPPASTFunctionDefinition();
-
- getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations));
- IASTDeclarator getterDeclarator = getGetterDeclarator(fieldName, fieldDeclaration, name);
- // IASTFunctionDefinition. expects the outermost IASTFunctionDeclarator in declarator hierarchy
- while (!(getterDeclarator instanceof IASTFunctionDeclarator)) {
- getterDeclarator = getterDeclarator.getNestedDeclarator();
- }
- getter.setDeclarator((IASTFunctionDeclarator) getterDeclarator);
- getter.setBody(getGetterBody(fieldName));
- return getter;
- }
-
- private static CPPASTCompoundStatement getGetterBody(IASTName fieldName) {
- CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
- CPPASTReturnStatement returnStatement = new CPPASTReturnStatement();
- CPPASTIdExpression idExpr = new CPPASTIdExpression();
- CPPASTName returnVal = new CPPASTName();
- returnVal.setName(fieldName.toCharArray());
- idExpr.setName(returnVal);
- returnStatement.setReturnValue(idExpr);
- compound.addStatement(returnStatement);
- return compound;
- }
-
- private static IASTDeclarator getGetterDeclarator(IASTName fieldName,
- IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
- CPPASTName getterName = new CPPASTName();
- getterName.setName(GetterSetterNameGenerator.generateGetterName(fieldName).toCharArray());
-
- // copy declarator hierarchy
- IASTDeclarator topDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
-
- // find the innermost declarator in hierarchy
- IASTDeclarator innermost = topDeclarator;
- while (innermost.getNestedDeclarator() != null) {
- innermost = innermost.getNestedDeclarator();
- }
-
- // create a new innermost function declarator basing on the field declarator
- CPPASTFunctionDeclarator functionDeclarator = new CPPASTFunctionDeclarator();
- functionDeclarator.setConst(true);
- if (name != null) {
- name.addName(getterName);
- functionDeclarator.setName(name);
- } else {
- functionDeclarator.setName(getterName);
- }
- for (IASTPointerOperator pointer : innermost.getPointerOperators()){
- functionDeclarator.addPointerOperator(pointer.copy(CopyStyle.withLocations));
- }
-
- // replace innermost with functionDeclarator and return the whole declarator tree
- if (innermost == topDeclarator) {
- // no tree
- return functionDeclarator;
- } else {
- IASTDeclarator parent = (IASTDeclarator) innermost.getParent();
- parent.setNestedDeclarator(functionDeclarator);
- return topDeclarator;
- }
- }
-
- public static IASTFunctionDefinition createSetterDefinition(IASTName fieldName,
- IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
- IASTFunctionDefinition setter = new CPPASTFunctionDefinition();
- setter.setDeclSpecifier(getVoidDeclSpec());
- setter.setDeclarator(getSetterDeclarator(fieldName, fieldDeclaration, name));
- setter.setBody(getSetterBody(fieldDeclaration));
- return setter;
- }
-
- private static CPPASTCompoundStatement getSetterBody(IASTSimpleDeclaration fieldDeclaration) {
- CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
- CPPASTExpressionStatement exprStmt = new CPPASTExpressionStatement();
- CPPASTBinaryExpression binExpr = new CPPASTBinaryExpression();
- IASTDeclarator innerDeclarator = fieldDeclaration.getDeclarators()[0];
- while (innerDeclarator.getNestedDeclarator() != null) {
- innerDeclarator = innerDeclarator.getNestedDeclarator();
- }
- IASTName fieldName = innerDeclarator.getName();
- CPPASTName parameterName = getSetterParameterName(fieldName);
- if (Arrays.equals(fieldName.getSimpleID(), parameterName.getSimpleID())) {
- CPPASTFieldReference fieldRef = new CPPASTFieldReference();
- CPPASTLiteralExpression litExpr = new CPPASTLiteralExpression();
- litExpr.setValue(Keywords.cTHIS);
- fieldRef.setFieldOwner(litExpr);
- fieldRef.setIsPointerDereference(true);
- fieldRef.setFieldName(fieldName.copy(CopyStyle.withLocations));
- binExpr.setOperand1(fieldRef);
- } else {
- CPPASTIdExpression idExpr = new CPPASTIdExpression(fieldName.copy(CopyStyle.withLocations));
- binExpr.setOperand1(idExpr);
- }
- binExpr.setOperator(IASTBinaryExpression.op_assign);
- CPPASTIdExpression idExpr = new CPPASTIdExpression(parameterName);
- binExpr.setOperand2(idExpr);
- exprStmt.setExpression(binExpr);
- compound.addStatement(exprStmt);
- return compound;
- }
-
- private static CPPASTFunctionDeclarator getSetterDeclarator(IASTName fieldName,
- IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
- CPPASTName setterName = new CPPASTName();
- setterName.setName(GetterSetterNameGenerator.generateSetterName(fieldName).toCharArray());
- CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator();
- if (name != null) {
- name.addName(setterName);
- declarator.setName(name);
- } else {
- declarator.setName(setterName);
- }
- CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration();
- IASTDeclarator parameterDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
- parameterDeclarator.setName(getSetterParameterName(fieldName));
- parameterDeclaration.setDeclarator(parameterDeclarator);
- parameterDeclaration.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(
- CopyStyle.withLocations));
- declarator.addParameterDeclaration(parameterDeclaration.copy(CopyStyle.withLocations));
- return declarator;
- }
-
- private static CPPASTName getSetterParameterName(IASTName fieldName) {
- String parameterName = GetterSetterNameGenerator.generateSetterParameterName(fieldName);
- return new CPPASTName(parameterName.toCharArray());
- }
-
- private static CPPASTSimpleDeclSpecifier getVoidDeclSpec() {
- CPPASTSimpleDeclSpecifier declSpecifier = new CPPASTSimpleDeclSpecifier();
- declSpecifier.setType(IASTSimpleDeclSpecifier.t_void);
- return declSpecifier;
- }
-
- public static IASTSimpleDeclaration createGetterDeclaration(IASTName fieldName,
- IASTSimpleDeclaration fieldDeclaration) {
- IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration();
- IASTDeclSpecifier declSpec = fieldDeclaration.getDeclSpecifier();
- getter.setDeclSpecifier(declSpec.copy(CopyStyle.withLocations));
- // TODO(sprigogin): Implement return by reference
-// IType type = CPPVisitor.createType(declSpec);
-// if (TypeHelper.shouldBePassedByReference(type, fieldDeclaration.getTranslationUnit())) {
-// declSpec.s
-// }
- getter.addDeclarator(getGetterDeclarator(fieldName, fieldDeclaration, null));
- return getter;
- }
-
- public static IASTSimpleDeclaration createSetterDeclaration(IASTName fieldName,
- IASTSimpleDeclaration fieldDeclaration) {
- IASTSimpleDeclaration setter = new CPPASTSimpleDeclaration();
- setter.setDeclSpecifier(getVoidDeclSpec());
- setter.addDeclarator(getSetterDeclarator(fieldName, fieldDeclaration, null));
- return setter;
- }
-}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java
index eb47fdb3b6a..0956d700277 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java
@@ -31,14 +31,14 @@ public class GetterSetterInsertEditProvider implements Comparable
Date: Tue, 6 Dec 2011 15:21:06 +0100
Subject: [PATCH 18/20] Bug 365605 - Editor should reconcile also on save
---
.../cdt/internal/ui/text/CReconciler.java | 28 ++++++++++---------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconciler.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconciler.java
index f921d4d3ed2..4af23c88ed1 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconciler.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconciler.java
@@ -84,6 +84,7 @@ public class CReconciler extends MonoReconciler {
/*
* @see org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core.runtime.jobs.ISchedulingRule)
*/
+ @Override
public boolean contains(ISchedulingRule rule) {
return rule == this;
}
@@ -91,6 +92,7 @@ public class CReconciler extends MonoReconciler {
/*
* @see org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse.core.runtime.jobs.ISchedulingRule)
*/
+ @Override
public boolean isConflicting(ISchedulingRule rule) {
return rule == this;
}
@@ -104,26 +106,31 @@ public class CReconciler extends MonoReconciler {
/*
* @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partActivated(IWorkbenchPartReference partRef) {
}
/*
* @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partBroughtToTop(IWorkbenchPartReference partRef) {
}
/*
* @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partClosed(IWorkbenchPartReference partRef) {
}
/*
* @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partDeactivated(IWorkbenchPartReference partRef) {
}
/*
* @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partHidden(IWorkbenchPartReference partRef) {
if (partRef.getPart(false) == fTextEditor) {
setEditorActive(false);
@@ -132,16 +139,19 @@ public class CReconciler extends MonoReconciler {
/*
* @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partInputChanged(IWorkbenchPartReference partRef) {
}
/*
* @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partOpened(IWorkbenchPartReference partRef) {
}
/*
* @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference)
*/
+ @Override
public void partVisible(IWorkbenchPartReference partRef) {
if (partRef.getPart(false) == fTextEditor) {
CReconciler.this.scheduleReconciling();
@@ -192,6 +202,7 @@ public class CReconciler extends MonoReconciler {
/*
* @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent)
*/
+ @Override
public void elementChanged(ElementChangedEvent event) {
if (event.getType() == ElementChangedEvent.POST_CHANGE) {
if (isRelevantDelta(event.getDelta())) {
@@ -209,10 +220,7 @@ public class CReconciler extends MonoReconciler {
if ((flags & ICElementDelta.F_CONTENT) != 0) {
if (!fIsReconciling && isRelevantElement(delta.getElement())) {
// mark model changed, but don't update immediately
- fIndexerListener.ignoreChanges(false);
setCModelChanged(true);
- } else if (delta.getElement() instanceof ITranslationUnit) {
- fIndexerListener.ignoreChanges(true);
}
}
if ((flags & (
@@ -237,11 +245,11 @@ public class CReconciler extends MonoReconciler {
private class IndexerListener implements IIndexerStateListener, IIndexChangeListener {
private boolean fIndexChanged;
- private boolean fIgnoreChanges;
/*
* @see org.eclipse.cdt.core.index.IIndexerStateListener#indexChanged(org.eclipse.cdt.core.index.IIndexerStateEvent)
*/
+ @Override
public void indexChanged(IIndexerStateEvent event) {
if (event.indexerIsIdle()) {
if (fIndexChanged || hasCModelChanged()) {
@@ -252,25 +260,18 @@ public class CReconciler extends MonoReconciler {
setCModelChanged(true);
}
}
- fIgnoreChanges= false;
}
}
- public void ignoreChanges(boolean ignore) {
- fIgnoreChanges= ignore;
- }
-
/*
* @see org.eclipse.cdt.core.index.IIndexChangeListener#indexChanged(org.eclipse.cdt.core.index.IIndexChangeEvent)
*/
+ @Override
public void indexChanged(IIndexChangeEvent event) {
if (!fIndexChanged && isRelevantProject(event.getAffectedProject())) {
- if (!fIgnoreChanges || event.isCleared() || event.isReloaded() || event.hasNewFile()) {
- fIndexChanged= true;
- }
+ fIndexChanged= true;
}
}
-
}
/** The reconciler's editor */
@@ -328,6 +329,7 @@ public class CReconciler extends MonoReconciler {
CCorePlugin.getIndexManager().addIndexChangeListener(fIndexerListener);
fTriggerReconcilerJob= new SingletonJob("Trigger Reconciler", new Runnable() { //$NON-NLS-1$
+ @Override
public void run() {
forceReconciling();
}});
From 965c8431401b4335b910b61609eae0ac9aad7554 Mon Sep 17 00:00:00 2001
From: Sergey Prigogin
Date: Tue, 6 Dec 2011 10:07:33 -0800
Subject: [PATCH 19/20] Added file that was missing in the previous commit.
---
.../GetterSetterFactory.java | 218 ++++++++++++++++++
1 file changed, 218 insertions(+)
create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterFactory.java
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterFactory.java
new file mode 100644
index 00000000000..a428917cd12
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterFactory.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
+ * Rapperswil, University of applied sciences and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Institute for Software - initial API and implementation
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
+
+import java.util.Arrays;
+
+import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
+import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
+import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
+import org.eclipse.cdt.core.parser.Keywords;
+
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionStatement;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReferenceOperator;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+
+public class GetterSetterFactory {
+ private final IASTName fieldName;
+ private final IASTSimpleDeclaration fieldDeclaration;
+ private boolean passByReference;
+
+ public GetterSetterFactory(IASTName fieldName, IASTSimpleDeclaration fieldDeclaration) {
+ this.fieldName = fieldName;
+ this.fieldDeclaration = fieldDeclaration;
+ IType type = CPPVisitor.createType(fieldDeclaration.getDeclSpecifier());
+ passByReference = TypeHelper.shouldBePassedByReference(type, fieldDeclaration.getTranslationUnit());
+ }
+
+ public IASTFunctionDefinition createGetterDefinition(ICPPASTQualifiedName qualifiedName) {
+ IASTFunctionDefinition getter = new CPPASTFunctionDefinition();
+
+ getter.setDeclSpecifier(getParamOrReturnDeclSpecifier());
+ IASTDeclarator getterDeclarator = getGetterDeclarator(qualifiedName);
+ // IASTFunctionDefinition expects the outermost IASTFunctionDeclarator in declarator hierarchy
+ while (!(getterDeclarator instanceof IASTFunctionDeclarator)) {
+ getterDeclarator = getterDeclarator.getNestedDeclarator();
+ }
+ getter.setDeclarator((IASTFunctionDeclarator) getterDeclarator);
+ getter.setBody(getGetterBody());
+ return getter;
+ }
+
+ private CPPASTCompoundStatement getGetterBody() {
+ CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
+ CPPASTReturnStatement returnStatement = new CPPASTReturnStatement();
+ CPPASTIdExpression idExpr = new CPPASTIdExpression();
+ CPPASTName returnVal = new CPPASTName();
+ returnVal.setName(fieldName.toCharArray());
+ idExpr.setName(returnVal);
+ returnStatement.setReturnValue(idExpr);
+ compound.addStatement(returnStatement);
+ return compound;
+ }
+
+ private IASTDeclarator getGetterDeclarator(ICPPASTQualifiedName qualifiedName) {
+ CPPASTName getterName = new CPPASTName();
+ getterName.setName(GetterSetterNameGenerator.generateGetterName(fieldName).toCharArray());
+
+ // Copy declarator hierarchy
+ IASTDeclarator topDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
+
+ // Find the innermost declarator in hierarchy
+ IASTDeclarator innermost = topDeclarator;
+ while (innermost.getNestedDeclarator() != null) {
+ innermost = innermost.getNestedDeclarator();
+ }
+
+ // Create a new innermost function declarator based on the field declarator
+ CPPASTFunctionDeclarator functionDeclarator = new CPPASTFunctionDeclarator();
+ functionDeclarator.setConst(true);
+ if (qualifiedName != null) {
+ qualifiedName.addName(getterName);
+ functionDeclarator.setName(qualifiedName);
+ } else {
+ functionDeclarator.setName(getterName);
+ }
+ for (IASTPointerOperator pointer : innermost.getPointerOperators()){
+ functionDeclarator.addPointerOperator(pointer.copy(CopyStyle.withLocations));
+ }
+ if (passByReference) {
+ functionDeclarator.addPointerOperator(new CPPASTReferenceOperator(false));
+ }
+
+ // Replace the innermost with functionDeclarator and return the whole declarator tree
+ if (innermost == topDeclarator) {
+ // No tree
+ return functionDeclarator;
+ } else {
+ IASTDeclarator parent = (IASTDeclarator) innermost.getParent();
+ parent.setNestedDeclarator(functionDeclarator);
+ return topDeclarator;
+ }
+ }
+
+ public IASTFunctionDefinition createSetterDefinition(ICPPASTQualifiedName qualifiedName) {
+ IASTFunctionDefinition setter = new CPPASTFunctionDefinition();
+ setter.setDeclSpecifier(getVoidDeclSpec());
+ setter.setDeclarator(getSetterDeclarator(qualifiedName));
+ setter.setBody(getSetterBody());
+ return setter;
+ }
+
+ private CPPASTCompoundStatement getSetterBody() {
+ CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
+ CPPASTExpressionStatement exprStmt = new CPPASTExpressionStatement();
+ CPPASTBinaryExpression binExpr = new CPPASTBinaryExpression();
+ IASTDeclarator innerDeclarator = fieldDeclaration.getDeclarators()[0];
+ while (innerDeclarator.getNestedDeclarator() != null) {
+ innerDeclarator = innerDeclarator.getNestedDeclarator();
+ }
+ IASTName fieldName = innerDeclarator.getName();
+ CPPASTName parameterName = getSetterParameterName();
+ if (Arrays.equals(fieldName.getSimpleID(), parameterName.getSimpleID())) {
+ CPPASTFieldReference fieldRef = new CPPASTFieldReference();
+ CPPASTLiteralExpression litExpr = new CPPASTLiteralExpression();
+ litExpr.setValue(Keywords.cTHIS);
+ fieldRef.setFieldOwner(litExpr);
+ fieldRef.setIsPointerDereference(true);
+ fieldRef.setFieldName(fieldName.copy(CopyStyle.withLocations));
+ binExpr.setOperand1(fieldRef);
+ } else {
+ CPPASTIdExpression idExpr = new CPPASTIdExpression(fieldName.copy(CopyStyle.withLocations));
+ binExpr.setOperand1(idExpr);
+ }
+ binExpr.setOperator(IASTBinaryExpression.op_assign);
+ CPPASTIdExpression idExpr = new CPPASTIdExpression(parameterName);
+ binExpr.setOperand2(idExpr);
+ exprStmt.setExpression(binExpr);
+ compound.addStatement(exprStmt);
+ return compound;
+ }
+
+ private CPPASTFunctionDeclarator getSetterDeclarator(ICPPASTQualifiedName qualifiedName) {
+ CPPASTName setterName = new CPPASTName();
+ setterName.setName(GetterSetterNameGenerator.generateSetterName(fieldName).toCharArray());
+ CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator();
+ if (qualifiedName != null) {
+ qualifiedName.addName(setterName);
+ declarator.setName(qualifiedName);
+ } else {
+ declarator.setName(setterName);
+ }
+ CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration();
+ IASTDeclarator parameterDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
+ parameterDeclarator.setName(getSetterParameterName());
+ if (passByReference) {
+ parameterDeclarator.addPointerOperator(new CPPASTReferenceOperator(false));
+ }
+ parameterDeclaration.setDeclarator(parameterDeclarator);
+ parameterDeclaration.setDeclSpecifier(getParamOrReturnDeclSpecifier());
+ declarator.addParameterDeclaration(parameterDeclaration.copy(CopyStyle.withLocations));
+ return declarator;
+ }
+
+ private CPPASTName getSetterParameterName() {
+ String parameterName = GetterSetterNameGenerator.generateSetterParameterName(fieldName);
+ return new CPPASTName(parameterName.toCharArray());
+ }
+
+ private static CPPASTSimpleDeclSpecifier getVoidDeclSpec() {
+ CPPASTSimpleDeclSpecifier declSpecifier = new CPPASTSimpleDeclSpecifier();
+ declSpecifier.setType(IASTSimpleDeclSpecifier.t_void);
+ return declSpecifier;
+ }
+
+ public IASTSimpleDeclaration createGetterDeclaration() {
+ IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration();
+ getter.setDeclSpecifier(getParamOrReturnDeclSpecifier());
+ getter.addDeclarator(getGetterDeclarator(null));
+ return getter;
+ }
+
+ private IASTDeclSpecifier getParamOrReturnDeclSpecifier() {
+ IASTDeclSpecifier declSpec = fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations);
+ if (passByReference) {
+ declSpec.setConst(true);
+ }
+ return declSpec;
+ }
+
+ public IASTSimpleDeclaration createSetterDeclaration() {
+ IASTSimpleDeclaration setter = new CPPASTSimpleDeclaration();
+ setter.setDeclSpecifier(getVoidDeclSpec());
+ setter.addDeclarator(getSetterDeclarator(null));
+ return setter;
+ }
+}
From e59cb540dbd31d19cb0d2fdb7c62fc7005d8de4d Mon Sep 17 00:00:00 2001
From: Pawel Piech
Date: Wed, 7 Dec 2011 15:10:47 -0800
Subject: [PATCH 20/20] Bug 310345 - [concurrent] Asynchronous Cache
Programming Model (ACPM) utilities for DSF (Fixed API tooling errors).
---
dsf/org.eclipse.cdt.dsf/.settings/.api_filters | 11 +++++++++++
.../org/eclipse/cdt/dsf/concurrent/AbstractCache.java | 1 +
2 files changed, 12 insertions(+)
create mode 100644 dsf/org.eclipse.cdt.dsf/.settings/.api_filters
diff --git a/dsf/org.eclipse.cdt.dsf/.settings/.api_filters b/dsf/org.eclipse.cdt.dsf/.settings/.api_filters
new file mode 100644
index 00000000000..4cde327ba3a
--- /dev/null
+++ b/dsf/org.eclipse.cdt.dsf/.settings/.api_filters
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/AbstractCache.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/AbstractCache.java
index 84ad02dd935..a4f95756dbc 100644
--- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/AbstractCache.java
+++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/AbstractCache.java
@@ -338,6 +338,7 @@ public abstract class AbstractCache implements ICache {
* invalidated
*
* @see #reset(Object, IStatus)
+ * @since 2.3
*/
protected void setAndReset(V data, IStatus status) {
assert fExecutor.getDsfExecutor().isInExecutorThread();