summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Lindo2012-03-02 22:11:36 (EST)
committerVivian Kong2012-03-02 22:11:36 (EST)
commitbf0e5b4b63fba133bd5a274f72e09169b3601bac (patch)
treeb7b308b5d8f3e520a45d01d1a5855b877a40e42b
parent65de35a1787cebfb393c89358cda6059ace793a0 (diff)
downloadorg.eclipse.ptp-bf0e5b4b63fba133bd5a274f72e09169b3601bac.zip
org.eclipse.ptp-bf0e5b4b63fba133bd5a274f72e09169b3601bac.tar.gz
org.eclipse.ptp-bf0e5b4b63fba133bd5a274f72e09169b3601bac.tar.bz2
Bug 370763 - Remote Semantic Highlighting in the Remote C/C++ Editor and
Bug 373127 - Code Folding in the Remote C/C++ Editor
-rwxr-xr-xrdt/org.eclipse.ptp.rdt.core.remotejars/cdtminer.jardesc80
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/CDTMiner.java124
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/PositionCollector.java314
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/RemoteFoldingRegionsHandler.java354
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlighting.java36
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlightings.java763
-rwxr-xr-xrdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CElement.java8
-rwxr-xr-xrdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CModelBuilder2.java4
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteModelWorkingCopy.java15
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteReconcileWorkingCopyOperation.java4
-rw-r--r--rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/navigation/FoldingRegionsResult.java25
-rwxr-xr-xrdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/subsystems/ICIndexSubsystem.java10
-rw-r--r--rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/internal/rdt/editor/RemoteCEditor.java41
-rw-r--r--rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/rdt/editor/info/IRemoteCEditorInfoProvider.java12
-rw-r--r--rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexServiceProvider.java39
-rw-r--r--rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexSubsystem.java107
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteCCodeFoldingService.java29
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteSemanticHighlightingService.java28
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCCodeFoldingService.java86
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCEditorInfoProvider.java61
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCFoldingStructureProvider.java1528
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCReconcilingStrategy.java21
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingManager.java235
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingReconciler.java295
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingService.java83
-rwxr-xr-xrdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/IIndexServiceProvider2.java14
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/LocalCIndexServiceProvider.java27
-rw-r--r--rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/NullCIndexServiceProvider.java21
-rwxr-xr-xrdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/RSECIndexServiceProvider.java28
-rwxr-xr-xrdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/subsystems/RSECIndexSubsystem.java101
30 files changed, 4422 insertions, 71 deletions
diff --git a/rdt/org.eclipse.ptp.rdt.core.remotejars/cdtminer.jardesc b/rdt/org.eclipse.ptp.rdt.core.remotejars/cdtminer.jardesc
index 09b3ec1..80d2d12 100755
--- a/rdt/org.eclipse.ptp.rdt.core.remotejars/cdtminer.jardesc
+++ b/rdt/org.eclipse.ptp.rdt.core.remotejars/cdtminer.jardesc
@@ -1,42 +1,40 @@
-<?xml version="1.0" encoding="WINDOWS-1252"?><jardesc>
- <jar path="c:/remote_deploy_rdt/cdtminer.jar"/>
- <options buildIfNeeded="true" compress="true" descriptionLocation="/org.eclipse.ptp.rdt.core.remotejars/cdtminer.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
- <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
- <selectedProjects/>
- <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
- <sealing sealJar="false">
- <packagesToSeal/>
- <packagesToUnSeal/>
- </sealing>
- </manifest>
- <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.search"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteScannerInfo.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{TypeHierarchyUtil.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{IndexQueries.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteIndexerInputAdapter.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.navigation{SimpleASTFileLocation.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.navigation{SimpleName.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteIndexerInfoProvider.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.model"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/miners"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.callhierarchy{CElementSet.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{Serializer.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{DummyName.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.contentassist"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.includebrowser{IndexIncludeValue.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.navigation{OpenDeclarationResult.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteUtil.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.rdt.core{IConfigurableLanguage.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{IRemoteIndexerInfoProvider.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{THGraphEdge.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.callhierarchy{CalledByResult.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{DummyFileLocation.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.callhierarchy{CallsToResult.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{RemoteIndexerProgress.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.includebrowser{IIndexIncludeValue.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{DummyFile.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{THGraphNode.java"/>
- <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{THGraph.java"/>
- </selectedElements>
+<?xml version="1.0" encoding="WINDOWS-1252"?><jardesc>
+ <jar path="c:/remote_deploy_rdt/cdtminer.jar"/>
+ <options buildIfNeeded="true" compress="true" descriptionLocation="/org.eclipse.ptp.rdt.core.remotejars/cdtminer.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+ <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+ <selectedProjects/>
+ <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+ <sealing sealJar="false">
+ <packagesToSeal/>
+ <packagesToUnSeal/>
+ </sealing>
+ </manifest>
+ <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.search"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteScannerInfo.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{IndexQueries.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{TypeHierarchyUtil.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteIndexerInputAdapter.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteIndexerInfoProvider.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.model"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/miners"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{Serializer.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.callhierarchy{CElementSet.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{DummyName.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.contentassist"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.includebrowser{IndexIncludeValue.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{RemoteUtil.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.rdt.core{IConfigurableLanguage.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core{IRemoteIndexerInfoProvider.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.navigation"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{THGraphEdge.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.callhierarchy{CalledByResult.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{DummyFileLocation.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.callhierarchy{CallsToResult.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{RemoteIndexerProgress.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.includebrowser{IIndexIncludeValue.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.index{DummyFile.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{THGraphNode.java"/>
+ <javaElement handleIdentifier="=org.eclipse.ptp.rdt.core/src&lt;org.eclipse.ptp.internal.rdt.core.typehierarchy{THGraph.java"/>
+ </selectedElements>
</jardesc> \ No newline at end of file
diff --git a/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/CDTMiner.java b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/CDTMiner.java
index d335f37..659e3b0 100644
--- a/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/CDTMiner.java
+++ b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/CDTMiner.java
@@ -22,6 +22,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Stack;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
@@ -64,6 +65,9 @@ import org.eclipse.ptp.internal.rdt.core.contentassist.RemoteContentAssistInvoca
import org.eclipse.ptp.internal.rdt.core.includebrowser.IIndexIncludeValue;
import org.eclipse.ptp.internal.rdt.core.includebrowser.IndexIncludeValue;
import org.eclipse.ptp.internal.rdt.core.index.IndexQueries;
+import org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.Branch;
+import org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.StatementRegion;
+import org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.StatementVisitor;
import org.eclipse.ptp.internal.rdt.core.model.CModelBuilder2;
import org.eclipse.ptp.internal.rdt.core.model.CProject;
import org.eclipse.ptp.internal.rdt.core.model.IIndexLocationConverterFactory;
@@ -71,6 +75,7 @@ import org.eclipse.ptp.internal.rdt.core.model.RemoteCProjectFactory;
import org.eclipse.ptp.internal.rdt.core.model.RemoteIndexLocationConverterFactory;
import org.eclipse.ptp.internal.rdt.core.model.Scope;
import org.eclipse.ptp.internal.rdt.core.model.WorkingCopy;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
import org.eclipse.ptp.internal.rdt.core.navigation.OpenDeclarationResult;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchMatch;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchQuery;
@@ -85,6 +90,7 @@ import org.eclipse.rse.dstore.universal.miners.UniversalServerUtilities;
public class CDTMiner extends Miner {
public static final String CLASSNAME="org.eclipse.ptp.internal.rdt.core.miners.CDTMiner"; //$NON-NLS-1$
+
// index management
public static final String C_INDEX_REINDEX = "C_INDEX_REINDEX"; //$NON-NLS-1$
public static final String C_INDEX_DELTA = "C_INDEX_DELTA"; //$NON-NLS-1$
@@ -92,6 +98,7 @@ public class CDTMiner extends Miner {
public static final String T_INDEX_STRING_DESCRIPTOR = "Type.Index.String"; //$NON-NLS-1$
public static final String T_INDEX_FILENAME_DESCRIPTOR = "Type.Scope.Filename"; //$NON-NLS-1$
public static final String T_INDEX_INT_DESCRIPTOR = "Type.Index.Int"; //$NON-NLS-1$
+ public static final String T_INDEX_BOOLEAN_DESCRIPTOR = "Type.Index.Boolean"; //$NON-NLS-1$
public static final String T_INDEX_DELTA_CHANGED = "Type.Index.Delta.Changed"; //$NON-NLS-1$
public static final String T_INDEX_DELTA_ADDED = "Type.Index.Delta.Added"; //$NON-NLS-1$
public static final String T_INDEX_DELTA_REMOVED = "Type.Index.Delta.Removed"; //$NON-NLS-1$
@@ -147,6 +154,12 @@ public class CDTMiner extends Miner {
public static final String C_INCLUDES_FIND_INCLUDE = "C_INCLUDES_FIND_INCLUDE"; //$NON-NLS-1$
public static final String T_INCLUDES_FIND_INCLUDE_RESULT = "Type.Includes.Find.Include.Result"; //$NON-NLS-1$
+ //semantic highlighting and code folding
+ public static final String C_SEMANTIC_HIGHTLIGHTING_COMPUTE_POSITIONS = "C_SEMANTIC_HIGHTLIGHTING_COMPUTE_POSITIONS"; //$NON-NLS-1$
+ public static final String T_HIGHTLIGHTING_POSITIONS_RESULT = "Highlighting.Positions.Result"; //$NON-NLS-1$
+ public static final String C_CODE_FOLDING_COMPUTE_REGIONS = "C_CODE_FOLDING_COMPUTE_REGIONS"; //$NON-NLS-1$
+ public static final String T_CODE_FOLDING_RESULT = "Folding.Region.Result"; //$NON-NLS-1$
+
public static String LINE_SEPARATOR;
public static final String DELIMITER = ";;;"; //$NON-NLS-1$
@@ -718,10 +731,117 @@ public class CDTMiner extends Miner {
UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
}
}
+ else if (name.equals(C_SEMANTIC_HIGHTLIGHTING_COMPUTE_POSITIONS)) {
+ try {
+ String scopeName = getString(theCommand, 1);
+ ITranslationUnit tu = (ITranslationUnit) Serializer.deserialize(getString(theCommand, 2));
+
+ hanleComputeSemanticHightlightingPositions(scopeName, tu, status);
+ } catch (IOException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ } catch (ClassNotFoundException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ }
+ }
+ else if (name.equals(C_CODE_FOLDING_COMPUTE_REGIONS)) {
+ try {
+ String scopeName = getString(theCommand, 1);
+ ITranslationUnit tu = (ITranslationUnit) Serializer.deserialize(getString(theCommand, 2));
+ int docSize = getInteger(theCommand, 3);
+ boolean preprocessorFoldingEnabled = getBoolean(theCommand, 4);
+ boolean statementsFoldingEnabled = getBoolean(theCommand, 5);
+
+ hanleComputeCodeFoldingRegions(scopeName, tu, status, statementsFoldingEnabled, preprocessorFoldingEnabled, docSize);
+ } catch (IOException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ } catch (ClassNotFoundException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ }
+ }
return status;
}
+ protected void hanleComputeSemanticHightlightingPositions(String scopeName, ITranslationUnit tu, DataElement status) {
+ try {
+ IIndex index = RemoteIndexManager.getInstance().getIndexForScope(scopeName, _dataStore);
+ index.acquireReadLock();
+ try {
+ IASTTranslationUnit ast = tu.getAST(index, ITranslationUnit.AST_SKIP_ALL_HEADERS | ITranslationUnit.AST_PARSE_INACTIVE_CODE);
+ PositionCollector collector = new PositionCollector(true);
+ ast.accept(collector);
+ ArrayList<ArrayList<Integer>> positionList = collector.getPositions();
+ String clumpedPositions = new String();
+ for (ArrayList<Integer> position : positionList) {
+ clumpedPositions += position.get(0) + "," + position.get(1) + "," + position.get(2) + ","; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ String resultString = Serializer.serialize(clumpedPositions);
+ status.getDataStore().createObject(status, T_HIGHTLIGHTING_POSITIONS_RESULT, resultString);
+ }
+ finally {
+ index.releaseReadLock();
+ }
+ } catch (IOException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ } catch (CoreException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ } catch (InterruptedException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ }
+ finally {
+ statusDone(status);
+ }
+ }
+
+ protected void hanleComputeCodeFoldingRegions(String scopeName, ITranslationUnit tu, DataElement status,
+ boolean statementsFoldingEnabled, boolean preprocessorFoldingEnabled, int docSize) {
+ try {
+ final Stack<StatementRegion> iral = new Stack<StatementRegion>();
+ List<Branch> branches = new ArrayList<Branch>();
+ IIndex index = RemoteIndexManager.getInstance().getIndexForScope(scopeName, _dataStore);
+ index.acquireReadLock();
+ try {
+ IASTTranslationUnit ast = tu.getAST(index, ITranslationUnit.AST_SKIP_ALL_HEADERS | ITranslationUnit.AST_PARSE_INACTIVE_CODE);
+
+ if (ast == null) {
+ return;
+ }
+ String fileName = ast.getFilePath();
+ if (fileName == null) {
+ return;
+ }
+
+ RemoteFoldingRegionsHandler rfrh = new RemoteFoldingRegionsHandler();
+ FoldingRegionsResult result = new FoldingRegionsResult();
+
+ if (statementsFoldingEnabled) {
+ StatementVisitor sv = rfrh.createStatementVisitor(iral);
+ ast.accept(sv);
+ result.iral = iral;
+ }
+ if (preprocessorFoldingEnabled) {
+ rfrh.computePreprocessorFoldingStructure(ast, docSize, branches);
+ result.branches = branches;
+ }
+
+ String resultString = Serializer.serialize(result);
+ status.getDataStore().createObject(status, T_CODE_FOLDING_RESULT, resultString);
+ }
+ finally {
+ index.releaseReadLock();
+ }
+ } catch (IOException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ } catch (CoreException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ } catch (InterruptedException e) {
+ UniversalServerUtilities.logError(LOG_TAG, e.toString(), e, _dataStore);
+ }
+ finally {
+ statusDone(status);
+ }
+ }
+
protected void handleIndexFileMove(String scopeName, String newIndexLocation, DataElement status) throws IOException {
String actualLocation = RemoteIndexManager.getInstance().moveIndexFile(scopeName, newIndexLocation, _dataStore);
status.getDataStore().createObject(status, T_MOVE_INDEX_FILE_RESULT, actualLocation);
@@ -1468,6 +1588,10 @@ public class CDTMiner extends Miner {
createCommandDescriptor(schemaRoot, "Find input from element", C_TYPE_HIERARCHY_FIND_INPUT1, false); //$NON-NLS-1$
createCommandDescriptor(schemaRoot, "Find input from text selection", C_TYPE_HIERARCHY_FIND_INPUT2, false); //$NON-NLS-1$
+ // semantic highlighting and code folding
+ createCommandDescriptor(schemaRoot, "Compute added & removed positions for semantic highlighting", C_SEMANTIC_HIGHTLIGHTING_COMPUTE_POSITIONS, false); //$NON-NLS-1$
+ createCommandDescriptor(schemaRoot, "Compute code folding regions for the Remote C Editor", C_CODE_FOLDING_COMPUTE_REGIONS, false); //$NON-NLS-1$
+
// navigation
createCommandDescriptor(schemaRoot, "Open declaration", C_NAVIGATION_OPEN_DECLARATION, false); //$NON-NLS-1$
diff --git a/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/PositionCollector.java b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/PositionCollector.java
new file mode 100644
index 0000000..3788a88
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/PositionCollector.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.core.miners;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
+import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
+
+import org.eclipse.ptp.internal.rdt.core.miners.SemanticHighlighting;
+import org.eclipse.ptp.internal.rdt.core.miners.SemanticHighlightings;
+
+
+/* Pulled from SemanticHighlightingReconciler with SemanticToken added as a nested class.*/
+public class PositionCollector extends CPPASTVisitor {
+
+ public final class SemanticToken {
+
+ /** AST node */
+ private IASTNode fNode;
+
+ /** Binding */
+ private IBinding fBinding;
+ /** Is the binding resolved? */
+ private boolean fIsBindingResolved= false;
+
+ /** AST root */
+ private IASTTranslationUnit fRoot;
+ private boolean fIsRootResolved= false;
+
+ /**
+ * @return Returns the binding, can be <code>null</code>.
+ */
+ public IBinding getBinding() {
+ if (!fIsBindingResolved) {
+ fIsBindingResolved= true;
+ if (fNode instanceof IASTName)
+ fBinding= ((IASTName)fNode).resolveBinding();
+ }
+
+ return fBinding;
+ }
+
+ /**
+ * @return the AST node
+ */
+ public IASTNode getNode() {
+ return fNode;
+ }
+
+ /**
+ * @return the AST root
+ */
+ public IASTTranslationUnit getRoot() {
+ if (!fIsRootResolved) {
+ fIsRootResolved= true;
+ if (fNode != null) {
+ fRoot= fNode.getTranslationUnit();
+ }
+ }
+ return fRoot;
+ }
+
+ /**
+ * Update this token with the given AST node.
+ * <p>
+ * NOTE: Allowed to be used by {@link SemanticHighlightingReconciler} only.
+ * </p>
+ *
+ * @param node the AST node
+ */
+ public void update(IASTNode node) {
+ clear();
+ fNode= node;
+ }
+
+ /**
+ * Clears this token.
+ * <p>
+ * NOTE: Allowed to be used by {@link SemanticHighlightingReconciler} only.
+ * </p>
+ */
+ public void clear() {
+ fNode= null;
+ fBinding= null;
+ fIsBindingResolved= false;
+ fRoot= null;
+ fIsRootResolved= false;
+ }
+ }
+
+ protected SemanticHighlighting[] fJobSemanticHighlightings;
+
+ ArrayList<ArrayList<Integer>> positionList = new ArrayList<ArrayList<Integer>>();
+
+ /** The semantic token */
+ private SemanticToken fToken= new SemanticToken();
+ private int fMinLocation;
+
+ public PositionCollector(boolean visitImplicitNames) {
+
+ fJobSemanticHighlightings = SemanticHighlightings.getSemanticHighlightings();
+ includeInactiveNodes = true;
+ fMinLocation= -1;
+ shouldVisitTranslationUnit= true;
+ shouldVisitNames= true;
+ shouldVisitDeclarations= true;
+ shouldVisitExpressions= true;
+ shouldVisitStatements= true;
+ shouldVisitDeclarators= true;
+ shouldVisitNamespaces= true;
+ shouldVisitImplicitNames = visitImplicitNames;
+ shouldVisitImplicitNameAlternates = visitImplicitNames;
+ }
+
+ /*
+ * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#leave(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
+ */
+ @Override
+ public int leave(IASTDeclaration declaration) {
+ return PROCESS_CONTINUE;
+ }
+
+
+ /*
+ * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTTranslationUnit)
+ */
+ @Override
+ public int visit(IASTTranslationUnit tu) {
+
+ // visit macro definitions
+ IASTPreprocessorMacroDefinition[] macroDefs= tu.getMacroDefinitions();
+ for (IASTPreprocessorMacroDefinition macroDef : macroDefs) {
+ if (macroDef.isPartOfTranslationUnitFile()) {
+ visitNode(macroDef.getName());
+ }
+ }
+ fMinLocation= -1;
+
+ // visit macro expansions
+ IASTPreprocessorMacroExpansion[] macroExps= tu.getMacroExpansions();
+ for (IASTPreprocessorMacroExpansion macroExp : macroExps) {
+ if (macroExp.isPartOfTranslationUnitFile()) {
+ IASTName macroRef= macroExp.getMacroReference();
+ visitNode(macroRef);
+ IASTName[] nestedMacroRefs= macroExp.getNestedMacroReferences();
+ for (IASTName nestedMacroRef : nestedMacroRefs) {
+ visitNode(nestedMacroRef);
+ }
+ }
+ }
+ fMinLocation= -1;
+
+ // visit ordinary code
+ return super.visit(tu);
+ }
+
+ /*
+ * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
+ */
+ @Override
+ public int visit(IASTDeclaration declaration) {
+ if (!declaration.isPartOfTranslationUnitFile()) {
+ return PROCESS_SKIP;
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ /*
+ * @see org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor#visit(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition)
+ */
+ @Override
+ public int visit(ICPPASTNamespaceDefinition namespace) {
+ if (!namespace.isPartOfTranslationUnitFile()) {
+ return PROCESS_SKIP;
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ /*
+ * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
+ */
+ @Override
+ public int visit(IASTDeclarator declarator) {
+ return PROCESS_CONTINUE;
+ }
+
+ /*
+ * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTStatement)
+ */
+ @Override
+ public int visit(IASTStatement statement) {
+ return PROCESS_CONTINUE;
+ }
+
+ /*
+ * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTName)
+ */
+ @Override
+ public int visit(IASTName name) {
+ if (visitNode(name)) {
+ return PROCESS_SKIP;
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ private boolean visitNode(IASTNode node) {
+ boolean consumed= false;
+ fToken.update(node);
+ for (int i= 0, n= fJobSemanticHighlightings.length; i < n; ++i) {
+ SemanticHighlighting semanticHighlighting= fJobSemanticHighlightings[i];
+ if (semanticHighlighting.consumes(fToken)) {
+ if (node instanceof IASTName) {
+ addNameLocation((IASTName)node, i);
+ } else {
+ addNodeLocation(node.getFileLocation(), i);
+ }
+ consumed= true;
+ break;
+ }
+ }
+ fToken.clear();
+ return consumed;
+ }
+
+ /**
+ * Add the a location range for the given name.
+ *
+ * @param name The name
+ * @param highlighting The highlighting
+ */
+ private void addNameLocation(IASTName name, int highlightingStyleIndex) {
+ IASTImageLocation imageLocation= name.getImageLocation();
+ if (imageLocation != null) {
+ if (imageLocation.getLocationKind() != IASTImageLocation.MACRO_DEFINITION) {
+ int offset= imageLocation.getNodeOffset();
+ if (offset >= fMinLocation) {
+ int length= imageLocation.getNodeLength();
+ if (offset > -1 && length > 0) {
+ fMinLocation= offset + length;
+ addPosition(offset, length, highlightingStyleIndex);
+ }
+ }
+ }
+ } else {
+ // fallback in case no image location available
+ IASTNodeLocation[] nodeLocations= name.getNodeLocations();
+ if (nodeLocations.length == 1 && !(nodeLocations[0] instanceof IASTMacroExpansionLocation)) {
+ addNodeLocation(nodeLocations[0], highlightingStyleIndex);
+ }
+ }
+ }
+
+ /**
+ * Add the a location range for the given highlighting.
+ *
+ * @param nodeLocation The node location
+ * @param highlighting The highlighting
+ */
+ private void addNodeLocation(IASTNodeLocation nodeLocation, int highlightingStyleIndex) {
+ if (nodeLocation == null) {
+ return;
+ }
+ int offset= nodeLocation.getNodeOffset();
+ if (offset >= fMinLocation) {
+ int length= nodeLocation.getNodeLength();
+ if (offset > -1 && length > 0) {
+ fMinLocation= offset + length;
+ addPosition(offset, length, highlightingStyleIndex);
+ }
+ }
+ }
+
+ /**
+ * Add a position with the given range.
+ *
+ * @param offset The range offset
+ * @param length The range length
+ * @param highlighting The highlighting
+ */
+ private void addPosition(int offset, int length, int highlightingStyleIndex) {
+ ArrayList<Integer> u = new ArrayList<Integer>();
+ u.addAll(Arrays.asList(new Integer[]{offset,length,highlightingStyleIndex}));
+ positionList.add(u);
+ }
+
+
+ public ArrayList<ArrayList<Integer>> getPositions(){
+ return positionList;
+ }
+
+} \ No newline at end of file
diff --git a/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/RemoteFoldingRegionsHandler.java b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/RemoteFoldingRegionsHandler.java
new file mode 100644
index 0000000..2adfecf
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/RemoteFoldingRegionsHandler.java
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.core.miners;
+
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Stack;
+
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
+import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
+import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
+import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
+import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
+import org.eclipse.cdt.core.dom.ast.IASTForStatement;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
+import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElseStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfndefStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
+import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
+
+/**
+ * Remote implementation of a {@link ICFoldingStructureProvider}.
+ * <p>
+ * Derived from DefaultCFoldingStructureProvider.
+ * </p>
+ */
+public class RemoteFoldingRegionsHandler {
+
+ /**
+ * Representation of a preprocessor code branch.
+ */
+ public static class Branch extends ModifiableRegion implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private final boolean fTaken;
+ public final String fCondition;
+ public boolean fInclusive;
+
+ Branch(int offset, boolean taken, String key) {
+ this(offset, 0, taken, key);
+ }
+
+ Branch(int offset, int length, boolean taken, String key) {
+ super(offset, length);
+ fTaken= taken;
+ fCondition= key;
+ }
+
+ public void setEndOffset(int endOffset) {
+ setLength(endOffset - getOffset());
+ }
+
+ public boolean taken() {
+ return fTaken;
+ }
+
+ public void setInclusive(boolean inclusive) {
+ fInclusive= inclusive;
+ }
+ }
+
+ /**
+ * Implementation of <code>IRegion</code> that can be reused
+ * by setting the offset and the length.
+ */
+ private static class ModifiableRegion implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private int length;
+ private int offset;
+
+ ModifiableRegion() {
+ }
+
+ ModifiableRegion(int offset, int length) {
+ setLength(length);
+ setOffset(offset);
+ }
+
+ public void setLength(int length) {
+ this.length = length;
+ }
+
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public int getLength() {
+ return length;
+ }
+ }
+
+ public static class StatementRegion extends ModifiableRegion {
+ public final String function;
+ public int level;
+ public boolean inclusive;
+ public StatementRegion(String function, int level) {
+ this.function= function;
+ this.level= level;
+ }
+ }
+
+
+ /**
+ * A visitor to collect compound statement positions.
+ *
+ * @since 5.0
+ */
+ public final class StatementVisitor extends ASTVisitor {
+ {
+ shouldVisitStatements = true;
+ shouldVisitDeclarations = true;
+ }
+ private final Stack<StatementRegion> fStatements;
+ int fLevel= 0;
+ String fFunction= ""; //$NON-NLS-1$
+
+ StatementVisitor(Stack<StatementRegion> statements) {
+ fStatements = statements;
+ includeInactiveNodes = true;
+ }
+
+ @Override
+ public int visit(IASTStatement statement) {
+ ++fLevel;
+ // if it's not part of the displayed - file, we don't need it
+ if (!statement.isPartOfTranslationUnitFile())
+ return PROCESS_SKIP;// we neither need its descendants
+ try {
+ StatementRegion mr;
+ IASTFileLocation fl;
+ if (statement instanceof IASTIfStatement) {
+ IASTIfStatement ifstmt = (IASTIfStatement) statement;
+ fl = ifstmt.getFileLocation();
+ if (fl==null) return PROCESS_CONTINUE;
+ int ifOffset= fl.getNodeOffset();
+ IASTStatement thenStmt;
+ mr = createRegion();
+ thenStmt = ifstmt.getThenClause();
+ if (thenStmt==null) return PROCESS_CONTINUE;
+ fl = thenStmt.getFileLocation();
+ mr.setLength(fl.getNodeOffset() + fl.getNodeLength() - ifOffset);
+ mr.setOffset(ifOffset);
+ mr.inclusive = !(thenStmt instanceof IASTCompoundStatement);
+ IASTStatement elseStmt;
+ elseStmt = ifstmt.getElseClause();
+ if (elseStmt == null) {
+ mr.inclusive = true;
+ fStatements.push(mr);
+ return PROCESS_CONTINUE;
+ }
+ IASTFileLocation elseStmtLocation = elseStmt.getFileLocation();
+ mr.inclusive = mr.inclusive || fl.getEndingLineNumber() < elseStmtLocation.getStartingLineNumber();
+ if (elseStmt instanceof IASTIfStatement) {
+ fStatements.push(mr);
+ return PROCESS_CONTINUE;
+ }
+ fStatements.push(mr);
+ mr = createRegion();
+ mr.setLength(elseStmtLocation.getNodeLength());
+ mr.setOffset(elseStmtLocation.getNodeOffset());
+ mr.inclusive = true;
+ fStatements.push(mr);
+ return PROCESS_CONTINUE;
+ }
+ mr = createRegion();
+ mr.inclusive = true;
+ if (statement instanceof IASTDoStatement)
+ mr.inclusive = false;
+ if (statement instanceof IASTSwitchStatement) {
+ IASTStatement switchstmt = ((IASTSwitchStatement)statement).getBody();
+ if (switchstmt instanceof IASTCompoundStatement) {
+ IASTStatement[] stmts = ((IASTCompoundStatement)switchstmt).getStatements();
+ boolean pushedMR = false;
+ for (IASTStatement tmpstmt : stmts) {
+ StatementRegion tmpmr;
+ if (!(tmpstmt instanceof IASTCaseStatement || tmpstmt instanceof IASTDefaultStatement)) {
+ if (!pushedMR) return PROCESS_SKIP;
+ IASTFileLocation tmpfl = tmpstmt.getFileLocation();
+ tmpmr = fStatements.peek();
+ tmpmr.setLength(tmpfl.getNodeLength()+tmpfl.getNodeOffset()-tmpmr.getOffset());
+ if (tmpstmt instanceof IASTBreakStatement) pushedMR = false;
+ continue;
+ }
+ IASTFileLocation tmpfl;
+ tmpmr = createRegion();
+ tmpmr.level= fLevel+1;
+ tmpmr.inclusive = true;
+ if (tmpstmt instanceof IASTCaseStatement) {
+ IASTCaseStatement casestmt = (IASTCaseStatement) tmpstmt;
+ tmpfl = casestmt.getExpression().getFileLocation();
+ tmpmr.setOffset(tmpfl.getNodeOffset());
+ tmpmr.setLength(tmpfl.getNodeLength());
+ } else if (tmpstmt instanceof IASTDefaultStatement) {
+ IASTDefaultStatement defstmt = (IASTDefaultStatement) tmpstmt;
+ tmpfl = defstmt.getFileLocation();
+ tmpmr.setOffset(tmpfl.getNodeOffset()+tmpfl.getNodeLength());
+ tmpmr.setLength(0);
+ }
+ fStatements.push(tmpmr);
+ pushedMR = true;
+ }
+ }
+ }
+ if (statement instanceof IASTForStatement
+ || statement instanceof IASTWhileStatement
+ || statement instanceof IASTDoStatement
+ || statement instanceof IASTSwitchStatement) {
+ fl = statement.getFileLocation();
+ mr.setLength(fl.getNodeLength());
+ mr.setOffset(fl.getNodeOffset());
+ fStatements.push(mr);
+ }
+ return PROCESS_CONTINUE;
+ } catch (Exception e) {
+ return PROCESS_ABORT;
+ }
+ }
+
+ @Override
+ public int leave(IASTStatement statement) {
+ --fLevel;
+ return PROCESS_CONTINUE;
+ }
+
+ @Override
+ public int visit(IASTDeclaration declaration) {
+ if (!declaration.isPartOfTranslationUnitFile())
+ return PROCESS_SKIP;// we neither need its descendants
+ if (declaration instanceof IASTFunctionDefinition) {
+ final IASTFunctionDeclarator declarator = ((IASTFunctionDefinition)declaration).getDeclarator();
+ if (declarator != null) {
+ fFunction= new String(ASTQueries.findInnermostDeclarator(declarator).getName().toCharArray());
+ fLevel= 0;
+ }
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ @Override
+ public int leave(IASTDeclaration declaration) {
+ if (declaration instanceof IASTFunctionDefinition) {
+ fFunction= ""; //$NON-NLS-1$
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ private StatementRegion createRegion() {
+ return new StatementRegion(fFunction, fLevel);
+ }
+ }
+
+ public StatementVisitor createStatementVisitor(Stack<StatementRegion> iral) {
+ return new StatementVisitor(iral);
+ }
+
+ /**
+ * Computes folding structure for preprocessor branches for the given AST.
+ *
+ * @param ast
+ */
+ void computePreprocessorFoldingStructure(IASTTranslationUnit ast, int docSize, List<Branch> branches) {
+ Stack<Branch> branchStack = new Stack<Branch>();
+
+ IASTPreprocessorStatement[] preprocStmts = ast.getAllPreprocessorStatements();
+
+ for (IASTPreprocessorStatement statement : preprocStmts) {
+ if (!statement.isPartOfTranslationUnitFile()) {
+ // preprocessor directive is from a different file
+ continue;
+ }
+ IASTNodeLocation stmtLocation= statement.getFileLocation();
+ if (stmtLocation == null) {
+ continue;
+ }
+ if (statement instanceof IASTPreprocessorIfStatement) {
+ IASTPreprocessorIfStatement ifStmt = (IASTPreprocessorIfStatement)statement;
+ branchStack.push(new Branch(stmtLocation.getNodeOffset(), ifStmt.taken(), "#if " + new String(ifStmt.getCondition()))); //$NON-NLS-1$
+ } else if (statement instanceof IASTPreprocessorIfdefStatement) {
+ IASTPreprocessorIfdefStatement ifdefStmt = (IASTPreprocessorIfdefStatement)statement;
+ branchStack.push(new Branch(stmtLocation.getNodeOffset(), ifdefStmt.taken(), "#ifdef " + new String(ifdefStmt.getCondition()))); //$NON-NLS-1$
+ } else if (statement instanceof IASTPreprocessorIfndefStatement) {
+ IASTPreprocessorIfndefStatement ifndefStmt = (IASTPreprocessorIfndefStatement)statement;
+ branchStack.push(new Branch(stmtLocation.getNodeOffset(), ifndefStmt.taken(), "#ifndef " + new String(ifndefStmt.getCondition()))); //$NON-NLS-1$
+ } else if (statement instanceof IASTPreprocessorElseStatement) {
+ if (branchStack.isEmpty()) {
+ // #else without #if
+ continue;
+ }
+ Branch branch= branchStack.pop();
+ IASTPreprocessorElseStatement elseStmt = (IASTPreprocessorElseStatement)statement;
+ branchStack.push(new Branch(stmtLocation.getNodeOffset(), elseStmt.taken(), branch.fCondition));
+ branch.setEndOffset(stmtLocation.getNodeOffset());
+ branches.add(branch);
+ } else if (statement instanceof IASTPreprocessorElifStatement) {
+ if (branchStack.isEmpty()) {
+ // #elif without #if
+ continue;
+ }
+ Branch branch= branchStack.pop();
+ IASTPreprocessorElifStatement elifStmt = (IASTPreprocessorElifStatement) statement;
+ branchStack.push(new Branch(stmtLocation.getNodeOffset(), elifStmt.taken(), branch.fCondition));
+ branch.setEndOffset(stmtLocation.getNodeOffset());
+ branches.add(branch);
+ } else if (statement instanceof IASTPreprocessorEndifStatement) {
+ if (branchStack.isEmpty()) {
+ // #endif without #if
+ continue;
+ }
+ Branch branch= branchStack.pop();
+ branch.setEndOffset(stmtLocation.getNodeOffset() + stmtLocation.getNodeLength());
+ branch.setInclusive(true);
+ branches.add(branch);
+ }
+ }
+
+ if (!branchStack.isEmpty()) {
+ // unterminated #if
+ Branch branch= branchStack.pop();
+ branch.setEndOffset(docSize);
+ branch.setInclusive(true);
+ branches.add(branch);
+ }
+ }
+
+}
+
+
diff --git a/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlighting.java b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlighting.java
new file mode 100644
index 0000000..65e816a
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlighting.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems) - Adapted for CDT
+ * Markus Schorn (Wind River Systems)
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.core.miners;
+
+
+/**
+ * Semantic highlighting.
+ * Cloned from JDT.
+ *
+ * @since 4.0
+ */
+public abstract class SemanticHighlighting {
+
+ /**
+ * Returns <code>true</code> iff the semantic highlighting consumes the semantic token.
+ * <p>
+ * NOTE: Implementors are not allowed to keep a reference on the token or on any object
+ * retrieved from the token.
+ * </p>
+ *
+ * @param fToken the semantic token for a {@link org.eclipse.cdt.core.dom.ast.IASTName}
+ * @return <code>true</code> iff the semantic highlighting consumes the semantic token
+ */
+ public abstract boolean consumes(org.eclipse.ptp.internal.rdt.core.miners.PositionCollector.SemanticToken fToken);
+}
diff --git a/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlightings.java b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlightings.java
new file mode 100644
index 0000000..6ac0a8a
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.core/miners/org/eclipse/ptp/internal/rdt/core/miners/SemanticHighlightings.java
@@ -0,0 +1,763 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems) - Adapted for CDT
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.core.miners;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTProblem;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IEnumeration;
+import org.eclipse.cdt.core.dom.ast.IEnumerator;
+import org.eclipse.cdt.core.dom.ast.IField;
+import org.eclipse.cdt.core.dom.ast.IFunction;
+import org.eclipse.cdt.core.dom.ast.ILabel;
+import org.eclipse.cdt.core.dom.ast.IMacroBinding;
+import org.eclipse.cdt.core.dom.ast.IParameter;
+import org.eclipse.cdt.core.dom.ast.IProblemBinding;
+import org.eclipse.cdt.core.dom.ast.IScope;
+import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.IVariable;
+import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding;
+import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexFile;
+import org.eclipse.cdt.core.index.IIndexName;
+
+import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
+import org.eclipse.ptp.internal.rdt.core.miners.PositionCollector.SemanticToken;
+
+
+/**
+ * Semantic highlightings.
+ * Derived from JDT.
+ *
+ * @since 4.0
+ */
+public class SemanticHighlightings {
+ /**
+ * Semantic highlightings
+ */
+ private static SemanticHighlighting[] fgSemanticHighlightings;
+
+ /**
+ * Semantic highlighting for static fields.
+ */
+ private static final class StaticFieldHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName && name.isReference()) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof IField && !(binding instanceof IProblemBinding)) {
+ try {
+ return ((IField)binding).isStatic();
+ } catch (Error e) /* PDOMNotImplementedError */ {
+ // ignore
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for fields.
+ */
+ private static final class FieldHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName && name.isReference()) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof IField) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for method declarations.
+ */
+ private static final class MethodDeclarationHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (!name.isReference()) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof ICPPMethod) {
+ return true;
+ } else if (binding instanceof IProblemBinding) {
+ // try to be derive from AST
+ node= name.getParent();
+ while (node instanceof IASTName) {
+ node= node.getParent();
+ }
+ if (node instanceof ICPPASTFunctionDeclarator) {
+ if (name instanceof ICPPASTQualifiedName) {
+ ICPPASTQualifiedName qName= (ICPPASTQualifiedName)name;
+ IASTName[] names= qName.getNames();
+ if (names.length > 1) {
+ if (names[names.length - 2].getBinding() instanceof ICPPClassType) {
+ return true;
+ }
+ }
+ } else {
+ while (node != token.getRoot() && !(node.getParent() instanceof IASTDeclSpecifier)) {
+ node= node.getParent();
+ }
+ if (node instanceof ICPPASTCompositeTypeSpecifier) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for static method invocations.
+ */
+ private static final class StaticMethodInvocationHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName) {
+ return false;
+ }
+ if (!name.isReference()) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof ICPPMethod && !(binding instanceof IProblemBinding)) {
+ try {
+ return ((ICPPMethod)binding).isStatic();
+ } catch (Error e) /* PDOMNotImplementedError */ {
+ // ignore
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for methods.
+ */
+ private static final class MethodHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTImplicitName)
+ return false;
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName && name.isReference()) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof ICPPMethod) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }
+
+ /**
+ * Semantic highlighting for function declarations.
+ */
+ private static final class FunctionDeclarationHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name.isDeclaration()) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof IFunction
+ && !(binding instanceof ICPPMethod)) {
+ return true;
+ } else if (binding instanceof IProblemBinding) {
+ // try to derive from AST
+ if (name instanceof ICPPASTQualifiedName) {
+ return false;
+ }
+ node= name.getParent();
+ while (node instanceof IASTName) {
+ node= node.getParent();
+ }
+ if (node instanceof IASTFunctionDeclarator) {
+ while (node != token.getRoot() && !(node.getParent() instanceof IASTDeclSpecifier)) {
+ node= node.getParent();
+ }
+ if (node instanceof ICPPASTCompositeTypeSpecifier) {
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for functions.
+ */
+ private static final class FunctionHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTImplicitName)
+ return false;
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName && name.isReference()) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof IFunction && !(binding instanceof ICPPMethod)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for local variable declarations.
+ */
+ private static final class LocalVariableDeclarationHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name.isDeclaration()) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof IVariable
+ && !(binding instanceof IField)
+ && !(binding instanceof IParameter)
+ && !(binding instanceof IProblemBinding)) {
+ try {
+ IScope scope= binding.getScope();
+ if (LocalVariableHighlighting.isLocalScope(scope)) {
+ return true;
+ }
+ } catch (DOMException exc) {
+ } catch (Error e) /* PDOMNotImplementedError */ {
+ // ignore
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+}
+
+ /**
+ * Semantic highlighting for local variables.
+ */
+ private static final class LocalVariableHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name.isReference()) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof IVariable
+ && !(binding instanceof IField)
+ && !(binding instanceof IParameter)
+ && !(binding instanceof IProblemBinding)) {
+ try {
+ IScope scope= binding.getScope();
+ if (isLocalScope(scope)) {
+ return true;
+ }
+ } catch (DOMException exc) {
+ } catch (Error e) /* PDOMNotImplementedError */ {
+ // ignore
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean isLocalScope(IScope scope) {
+ while (scope != null) {
+ if (scope instanceof ICPPFunctionScope ||
+ scope instanceof ICPPBlockScope ||
+ scope instanceof ICFunctionScope) {
+ return true;
+ }
+ try {
+ scope= scope.getParent();
+ } catch (DOMException e) {
+ scope= null;
+ }
+ }
+ return false;
+ }
+}
+
+ /**
+ * Semantic highlighting for global variables.
+ */
+ private static final class GlobalVariableHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof IVariable
+ && !(binding instanceof IField)
+ && !(binding instanceof IParameter)
+ && !(binding instanceof ICPPTemplateNonTypeParameter)
+ && !(binding instanceof IProblemBinding)) {
+ try {
+ IScope scope= binding.getScope();
+ if (!LocalVariableHighlighting.isLocalScope(scope)) {
+ return true;
+ }
+ } catch (DOMException exc) {
+
+ } catch (Error e) /* PDOMNotImplementedError */ {
+ // ignore
+ }
+ }
+ }
+ return false;
+ }
+
+ }
+
+ /**
+ * Semantic highlighting for parameter variables.
+ */
+ private static final class ParameterVariableHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof IParameter) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for template parameters.
+ */
+ private static final class TemplateParameterHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof ICPPTemplateParameter) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for classes.
+ */
+ private static final class ClassHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof ICPPASTQualifiedName || node instanceof ICPPASTTemplateId) {
+ return false;
+ }
+ if (node instanceof IASTName) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof ICPPClassType) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for enums.
+ */
+ private static final class EnumHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof IEnumeration) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for macro references.
+ */
+ private static final class MacroReferenceHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof IMacroBinding) {
+ IASTName name= (IASTName)token.getNode();
+ if (name.isReference()) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for macro definitions.
+ */
+ private static final class MacroDefinitionHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof IMacroBinding) {
+ IASTName name= (IASTName)token.getNode();
+ if (!name.isReference()) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for typedefs.
+ */
+ private static final class TypedefHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof ITypedef) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for namespaces.
+ */
+ private static final class NamespaceHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof ICPPNamespace) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for labels.
+ */
+ private static final class LabelHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IBinding binding= token.getBinding();
+ if (binding instanceof ILabel) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for enumerators.
+ */
+ private static final class EnumeratorHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName) {
+ return false;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof IEnumerator) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for problems.
+ */
+ private static final class ProblemHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTProblem) {
+ return true;
+ }
+ IBinding binding= token.getBinding();
+ if (binding instanceof IProblemBinding) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for external SDK references.
+ */
+ private static final class ExternalSDKHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node= token.getNode();
+ if (node instanceof IASTName) {
+ IASTName name= (IASTName)node;
+ if (name instanceof ICPPASTQualifiedName) {
+ return false;
+ }
+ if (name instanceof IASTImplicitName) {
+ return false;
+ }
+ if (name.isReference()) {
+ IBinding binding= token.getBinding();
+ IIndex index= token.getRoot().getIndex();
+ return isExternalSDKReference(binding, index);
+ }
+ }
+ return false;
+ }
+
+ private boolean isExternalSDKReference(IBinding binding, IIndex index) {
+ if (binding instanceof IFunction) {
+ try {
+ if (binding instanceof IIndexBinding) {
+ if (((IIndexBinding) binding).isFileLocal()) {
+ return false;
+ }
+ }
+ else if (!(binding instanceof ICExternalBinding)) {
+ return false;
+ }
+ IIndexName[] decls= index.findNames(binding, IIndex.FIND_DECLARATIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
+ for (IIndexName decl : decls) {
+ IIndexFile indexFile= decl.getFile();
+ if (indexFile != null && indexFile.getLocation().getFullPath() != null) {
+ return false;
+ }
+ }
+ if (decls.length != 0) {
+ return true;
+ }
+ } catch (CoreException exc) {
+ return false;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Semantic highlighting for functions.
+ */
+ private static final class OverloadedOperatorHighlighting extends SemanticHighlighting {
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.SemanticHighlighting#consumes(org.eclipse.cdt.internal.ui.editor.SemanticToken)
+ */
+ @Override
+ public boolean consumes(SemanticToken token) {
+ IASTNode node = token.getNode();
+ // so far we only have implicit names for overloaded operators and destructors, so this works
+ if(node instanceof IASTImplicitName) {
+ IASTImplicitName name = (IASTImplicitName) node;
+ IBinding binding = name.resolveBinding();
+ if(binding instanceof ICPPMethod && !(binding instanceof IProblemBinding) && ((ICPPMethod)binding).isImplicit()) {
+ return false;
+ }
+ char[] chars = name.toCharArray();
+ if(chars[0] == '~' || OverloadableOperator.isNew(chars) || OverloadableOperator.isDelete(chars)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+
+
+ /**
+ * @return The semantic highlightings, the order defines the precedence of matches, the first match wins.
+ */
+ public static SemanticHighlighting[] getSemanticHighlightings() {
+ if (fgSemanticHighlightings == null)
+ fgSemanticHighlightings= new SemanticHighlighting[] {
+ new MacroReferenceHighlighting(), // before all others!
+ new ProblemHighlighting(),
+ new ExternalSDKHighlighting(),
+ new ClassHighlighting(),
+ new StaticFieldHighlighting(),
+ new FieldHighlighting(), // after all other fields
+ new MethodDeclarationHighlighting(),
+ new StaticMethodInvocationHighlighting(),
+ new ParameterVariableHighlighting(), // before local variables
+ new LocalVariableDeclarationHighlighting(),
+ new LocalVariableHighlighting(),
+ new GlobalVariableHighlighting(),
+ new TemplateParameterHighlighting(), // before template arguments!
+ new OverloadedOperatorHighlighting(), // before both method and function
+ new MethodHighlighting(), // before types to get ctors
+ new EnumHighlighting(),
+ new MacroDefinitionHighlighting(),
+ new FunctionDeclarationHighlighting(),
+ new FunctionHighlighting(),
+ new TypedefHighlighting(),
+ new NamespaceHighlighting(),
+ new LabelHighlighting(),
+ new EnumeratorHighlighting(),
+ };
+ return fgSemanticHighlightings;
+ }
+
+
+ /**
+ * Do not instantiate
+ */
+ private SemanticHighlightings() {
+ }
+}
diff --git a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CElement.java b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CElement.java
index 31ad97d..edd5adc 100755
--- a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CElement.java
+++ b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CElement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation 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
@@ -265,6 +265,12 @@ public abstract class CElement implements ICElement, Serializable, IHasManagedLo
}
}
+ if (o instanceof CElement) {
+ if (((CElement)o).getIndex() != getIndex()) {
+ return false;
+ }
+ }
+
ICElement parent = other.getParent();
if (fParent != null && !fParent.equals(parent)) {
return false;
diff --git a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CModelBuilder2.java b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CModelBuilder2.java
index 8817a7e..6e0afdf 100755
--- a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CModelBuilder2.java
+++ b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/CModelBuilder2.java
@@ -198,7 +198,7 @@ public class CModelBuilder2 {
if (delta == 0) {
delta= info1.getIdStartPos() - info2.getIdStartPos();
}
- return delta;
+ return delta;
}});
if (isCanceled()) {
@@ -751,7 +751,7 @@ public class CModelBuilder2 {
final ICPPASTDeclSpecifier cppSpecifier= (ICPPASTDeclSpecifier)specifier;
fieldInfo.setMutable(cppSpecifier.getStorageClass() == IASTDeclSpecifier.sc_mutable);
}
- fieldInfo.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
+ fieldInfo.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
fieldInfo.setVisibility(getCurrentVisibility());
fieldInfo.setConst(specifier.isConst());
fieldInfo.setVolatile(specifier.isVolatile());
diff --git a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteModelWorkingCopy.java b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteModelWorkingCopy.java
index 571c75c..26ffb1f 100644
--- a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteModelWorkingCopy.java
+++ b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteModelWorkingCopy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation and others.
+ * Copyright (c) 2009, 2012 IBM Corporation 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
@@ -16,6 +16,7 @@ import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.model.CElementInfo;
+import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.cdt.internal.core.model.OpenableInfo;
import org.eclipse.cdt.internal.core.model.Parent;
import org.eclipse.cdt.internal.core.model.WorkingCopy;
@@ -89,4 +90,16 @@ public class RemoteModelWorkingCopy extends WorkingCopy {
}
parent.removeChildren();
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.model.Openable#generateInfos(org.eclipse.cdt.internal.core.model.CElementInfo, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected void generateInfos(CElementInfo info,
+ Map<ICElement, CElementInfo> newElements, IProgressMonitor monitor)
+ throws CModelException {
+ super.generateInfos(info, newElements, monitor);
+ // remove out of sync buffer for this element
+ CModelManager.getDefault().getElementsOutOfSynchWithBuffers().remove(fOriginal);
+ }
}
diff --git a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteReconcileWorkingCopyOperation.java b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteReconcileWorkingCopyOperation.java
index 0341b25..8ed94c1 100644
--- a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteReconcileWorkingCopyOperation.java
+++ b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/model/RemoteReconcileWorkingCopyOperation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2012 IBM Corporation 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
@@ -27,6 +27,7 @@ public class RemoteReconcileWorkingCopyOperation extends ReconcileWorkingCopyOpe
boolean forceProblemDetection;
boolean fComputeAST;
+ public RemoteModelWorkingCopy fRmWorkingCopy;
public RemoteReconcileWorkingCopyOperation(ICElement workingCopy,
boolean computeAST, boolean forceProblemDetection) {
@@ -72,6 +73,7 @@ public class RemoteReconcileWorkingCopyOperation extends ReconcileWorkingCopyOpe
rmWorkingCopy = new RemoteModelWorkingCopy(workingCopy);
rmWorkingCopy.makeConsistent(fMonitor,false);
+ fRmWorkingCopy = rmWorkingCopy;
if (deltaBuilder != null) {
deltaBuilder.buildDeltas();
diff --git a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/navigation/FoldingRegionsResult.java b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/navigation/FoldingRegionsResult.java
new file mode 100644
index 0000000..f52c29e
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/navigation/FoldingRegionsResult.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.core.navigation;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Stack;
+
+import org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.Branch;
+import org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.StatementRegion;
+
+public class FoldingRegionsResult implements Serializable {
+ private static final long serialVersionUID = 1L;
+ public Stack<StatementRegion> iral;
+ public List<Branch> branches;
+}
diff --git a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/subsystems/ICIndexSubsystem.java b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/subsystems/ICIndexSubsystem.java
index 17b98b2..cc83ef1 100755
--- a/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/subsystems/ICIndexSubsystem.java
+++ b/rdt/org.eclipse.ptp.rdt.core/src/org/eclipse/ptp/internal/rdt/core/subsystems/ICIndexSubsystem.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation 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
@@ -25,13 +25,14 @@ import org.eclipse.ptp.internal.rdt.core.callhierarchy.CallsToResult;
import org.eclipse.ptp.internal.rdt.core.contentassist.Proposal;
import org.eclipse.ptp.internal.rdt.core.contentassist.RemoteContentAssistInvocationContext;
import org.eclipse.ptp.internal.rdt.core.includebrowser.IIndexIncludeValue;
-import org.eclipse.ptp.internal.rdt.core.index.RemoteIndexerTask;
import org.eclipse.ptp.internal.rdt.core.index.IRemoteFastIndexerUpdateEvent.EventType;
+import org.eclipse.ptp.internal.rdt.core.index.RemoteIndexerTask;
import org.eclipse.ptp.internal.rdt.core.model.Scope;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
+import org.eclipse.ptp.internal.rdt.core.navigation.OpenDeclarationResult;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchMatch;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchQuery;
import org.eclipse.ptp.internal.rdt.core.typehierarchy.THGraph;
-import org.eclipse.ptp.internal.rdt.core.navigation.OpenDeclarationResult;
@@ -293,4 +294,7 @@ public interface ICIndexSubsystem {
*/
public EventType getReIndexEventType();
+ public String computeHighlightPositions(ITranslationUnit targetUnit);
+
+ public FoldingRegionsResult computeFoldingRegions(ITranslationUnit targetUnit, int docLength, boolean fPreprocessorBranchFoldingEnabled, boolean fStatementsFoldingEnabled);
}
diff --git a/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/internal/rdt/editor/RemoteCEditor.java b/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/internal/rdt/editor/RemoteCEditor.java
index d412a2b..6c63407 100644
--- a/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/internal/rdt/editor/RemoteCEditor.java
+++ b/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/internal/rdt/editor/RemoteCEditor.java
@@ -17,6 +17,8 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.internal.ui.editor.CContentOutlinePage;
import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings;
+import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IMenuManager;
@@ -27,6 +29,7 @@ import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.IVerticalRulerColumn;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ptp.rdt.editor.info.IRemoteCEditorInfoProvider;
import org.eclipse.ptp.rdt.editor.info.RemoteCInfoProviderUtilities;
import org.eclipse.swt.events.HelpEvent;
@@ -48,7 +51,7 @@ public class RemoteCEditor extends CEditor implements HelpListener {
private IEditorInput input;
private List<IRemoteCEditorInfoProvider> infoProviders;
private IRemoteCEditorInfoProvider provider;
-
+ ISourceViewer viewer;
/**
* Default constructor.
*/
@@ -89,8 +92,11 @@ public class RemoteCEditor extends CEditor implements HelpListener {
public void createPartControl(Composite parent) {
super.createPartControl(parent);
- if (provider != null)
+ if (provider != null){
+ if (isSemanticHighlightingEnabled())
+ provider.installSemanticHighlighting(getSourceViewer(), getPreferenceStore());
provider.doPostCreatePartControl(parent);
+ }
}
@SuppressWarnings("rawtypes")
@@ -223,9 +229,7 @@ public class RemoteCEditor extends CEditor implements HelpListener {
@Override
protected boolean isSemanticHighlightingEnabled() {
if (provider != null) {
- Boolean enabled = provider.isSemanticHighlightingEnabled();
- if (enabled != null)
- return enabled.booleanValue();
+ return provider.isSemanticHighlightingEnabled(getPreferenceStore());
}
return super.isSemanticHighlightingEnabled();
}
@@ -281,6 +285,7 @@ public class RemoteCEditor extends CEditor implements HelpListener {
public void dispose() {
if (provider != null)
provider.dispose();
+
super.dispose();
}
@@ -293,9 +298,14 @@ public class RemoteCEditor extends CEditor implements HelpListener {
@Override
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
- ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
+ viewer = super.createSourceViewer(parent, ruler, styles);
// add ability to provide context help
viewer.getTextWidget().addHelpListener(this);
+
+ if(provider != null && isFoldingEnabled()) {
+ provider.installRemoteCodeFolding(viewer);
+ }
+
return viewer;
}
@@ -392,6 +402,25 @@ public class RemoteCEditor extends CEditor implements HelpListener {
return result;
}
+ protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
+ super.handlePreferenceStoreChanged(event);
+
+ if (provider != null && SemanticHighlightings.affectsEnablement(getPreferenceStore(), event )
+ || (isEnableScalablilityMode() && PreferenceConstants.SCALABILITY_SEMANTIC_HIGHLIGHT.equals(event.getProperty()))) {
+ if (isSemanticHighlightingEnabled()) {
+ provider.installSemanticHighlighting(getSourceViewer(), getPreferenceStore());
+ provider.refreshRemoteSemanticManager();
+ } else {
+ provider.uninstallSemanticHighlighting();
+ }
+ return;
+ }
+ }
+
+ public void uninstallProjectionModelUpdater() {
+ super.uninstallProjectionModelUpdater();
+ }
+
/**
* allows the dirty indicator to be reset in the case where a save/upload to a remote host fails.
*/
diff --git a/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/rdt/editor/info/IRemoteCEditorInfoProvider.java b/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/rdt/editor/info/IRemoteCEditorInfoProvider.java
index 5a61458..e448f03 100644
--- a/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/rdt/editor/info/IRemoteCEditorInfoProvider.java
+++ b/rdt/org.eclipse.ptp.rdt.editor/src/org/eclipse/ptp/rdt/editor/info/IRemoteCEditorInfoProvider.java
@@ -17,6 +17,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.ptp.internal.rdt.editor.RemoteCEditor;
@@ -125,6 +126,15 @@ public interface IRemoteCEditorInfoProvider {
public boolean shouldProcessLocalParsingCompletions();
- public Boolean isSemanticHighlightingEnabled();
+ public boolean isSemanticHighlightingEnabled(IPreferenceStore store);
+
+ public void installSemanticHighlighting(ISourceViewer sourceViewer, IPreferenceStore prefStore);
+ public void installRemoteCodeFolding(ISourceViewer sourceViewer);
+
+ public void uninstallRemoteCodeFolding();
+
+ public void uninstallSemanticHighlighting();
+
+ public void refreshRemoteSemanticManager();
}
diff --git a/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexServiceProvider.java b/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexServiceProvider.java
index bc4a031..16b06da 100644
--- a/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexServiceProvider.java
+++ b/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexServiceProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation 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
@@ -24,6 +24,10 @@ import org.eclipse.ptp.internal.rdt.core.typehierarchy.ITypeHierarchyService;
import org.eclipse.ptp.internal.rdt.core.typehierarchy.RemoteTypeHierarchyService;
import org.eclipse.ptp.internal.rdt.ui.contentassist.IContentAssistService;
import org.eclipse.ptp.internal.rdt.ui.contentassist.RemoteContentAssistService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteSemanticHighlightingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.RemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.RemoteSemanticHighlightingService;
import org.eclipse.ptp.internal.rdt.ui.navigation.INavigationService;
import org.eclipse.ptp.internal.rdt.ui.navigation.RemoteNavigationService;
import org.eclipse.ptp.internal.rdt.ui.search.ISearchService;
@@ -51,6 +55,14 @@ public class RemoteToolsCIndexServiceProvider extends ServiceProvider implements
protected IModelBuilderService fModelBuilderService = null;
protected RemoteSearchService fSearchService = null;
protected IContentAssistService fContentAssistService = null;
+ /**
+ * @since 3.0
+ */
+ protected RemoteSemanticHighlightingService fRemoteSemanticHighlightingService = null;
+ /**
+ * @since 3.0
+ */
+ protected RemoteCCodeFoldingService fRemoteCCodeFoldingService = null;
protected RemoteToolsCIndexSubsystem fSubsystem = null;
protected boolean fIsDirty = false;
protected RemoteToolsCIndexServiceProvider fProvider = null;
@@ -433,5 +445,30 @@ public class RemoteToolsCIndexServiceProvider extends ServiceProvider implements
fSubsystem = new RemoteToolsCIndexSubsystem(this);
setConfigured(true);
}
+
+ /**
+ * @since 3.0
+ */
+ public IRemoteSemanticHighlightingService getRemoteSemanticHighlightingService() {
+ if(!isConfigured())
+ return null;
+ if(fRemoteSemanticHighlightingService== null)
+ fRemoteSemanticHighlightingService = new RemoteSemanticHighlightingService(fSubsystem);
+
+ return fRemoteSemanticHighlightingService;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public IRemoteCCodeFoldingService getRemoteCodeFoldingService() {
+ if(!isConfigured())
+ return null;
+
+ if(fRemoteCCodeFoldingService== null)
+ fRemoteCCodeFoldingService = new RemoteCCodeFoldingService(fSubsystem);
+
+ return fRemoteCCodeFoldingService;
+ }
}
diff --git a/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexSubsystem.java b/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexSubsystem.java
index 4a055fe..159e09d 100644
--- a/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexSubsystem.java
+++ b/rdt/org.eclipse.ptp.rdt.server.dstore/src/org/eclipse/ptp/rdt/server/dstore/core/RemoteToolsCIndexSubsystem.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation 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
@@ -16,7 +16,6 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -66,6 +65,7 @@ import org.eclipse.ptp.internal.rdt.core.index.RemoteIndexerProgress;
import org.eclipse.ptp.internal.rdt.core.index.RemoteIndexerTask;
import org.eclipse.ptp.internal.rdt.core.miners.CDTMiner;
import org.eclipse.ptp.internal.rdt.core.model.Scope;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
import org.eclipse.ptp.internal.rdt.core.navigation.OpenDeclarationResult;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchMatch;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchQuery;
@@ -1215,4 +1215,107 @@ public class RemoteToolsCIndexSubsystem implements ICIndexSubsystem {
public EventType getReIndexEventType() {
return IRemoteFastIndexerUpdateEvent.EventType.EVENT_REINDEX;
}
+
+ /**
+ * @since 3.0
+ */
+ public String computeHighlightPositions(ITranslationUnit targetUnit) {
+ // If something goes wrong, return an empty string.
+
+ checkAllProjects(new NullProgressMonitor());
+ DataStore dataStore = getDataStore(null);
+ if (dataStore == null) {
+ return ""; //$NON-NLS-1$
+ }
+ DataElement queryCmd = dataStore.localDescriptorQuery(dataStore.getDescriptorRoot(), CDTMiner.C_SEMANTIC_HIGHTLIGHTING_COMPUTE_POSITIONS);
+ if (queryCmd == null) {
+ return ""; //$NON-NLS-1$
+ }
+ NullProgressMonitor monitor = new NullProgressMonitor();
+ StatusMonitor smonitor = StatusMonitor.getStatusMonitorFor(fProvider.getConnection(), dataStore);
+ ArrayList<Object> args = new ArrayList<Object>();
+ Scope scope = new Scope(targetUnit.getCProject().getProject());
+ DataElement dataElement = dataStore.createObject(null, CDTMiner.T_SCOPE_SCOPENAME_DESCRIPTOR, scope.getName());
+
+ args.add(dataElement);
+ args.add(createSerializableElement(dataStore, targetUnit));
+
+ // execute the command
+ DataElement status = dataStore.command(queryCmd, args, dataStore.getDescriptorRoot());
+
+ try {
+ smonitor.waitForUpdate(status, monitor);
+ }
+ catch (Exception e) {
+ RDTLog.logError(e);
+ }
+
+ DataElement element = status.get(0);
+ String data = element.getName();
+ try {
+ Object result = Serializer.deserialize(data);
+ if (result == null || !(result instanceof String)) {
+ return ""; //$NON-NLS-1$;
+ }
+ return (String) result;
+ } catch (IOException e) {
+ RDTLog.logError(e);
+ } catch (ClassNotFoundException e) {
+ RDTLog.logError(e);
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * @since 3.0
+ */
+ public FoldingRegionsResult computeFoldingRegions(ITranslationUnit targetUnit, int docLength, boolean fPreprocessorBranchFoldingEnabled, boolean fStatementsFoldingEnabled) {
+ checkAllProjects(new NullProgressMonitor());
+ DataStore dataStore = getDataStore(null);
+ if (dataStore == null) {
+ return null;
+ }
+ DataElement queryCmd = dataStore.localDescriptorQuery(dataStore.getDescriptorRoot(), CDTMiner.C_CODE_FOLDING_COMPUTE_REGIONS);
+ if (queryCmd == null) {
+ return null;
+ }
+ NullProgressMonitor monitor = new NullProgressMonitor();
+ StatusMonitor smonitor = StatusMonitor.getStatusMonitorFor(fProvider.getConnection(), dataStore);
+ ArrayList<Object> args = new ArrayList<Object>();
+ Scope scope = new Scope(targetUnit.getCProject().getProject());
+ DataElement dataElement = dataStore.createObject(null, CDTMiner.T_SCOPE_SCOPENAME_DESCRIPTOR, scope.getName());
+
+ args.add(dataElement);
+ args.add(createSerializableElement(dataStore, targetUnit));
+ args.add(dataStore.createObject(null, CDTMiner.T_INDEX_INT_DESCRIPTOR, Integer.toString(docLength)));
+ args.add(dataStore.createObject(null, CDTMiner.T_INDEX_BOOLEAN_DESCRIPTOR, Boolean.toString(fPreprocessorBranchFoldingEnabled)));
+ args.add(dataStore.createObject(null, CDTMiner.T_INDEX_BOOLEAN_DESCRIPTOR, Boolean.toString(fStatementsFoldingEnabled)));
+
+ // execute the command
+ DataElement status = dataStore.command(queryCmd, args, dataStore.getDescriptorRoot());
+
+ try {
+ smonitor.waitForUpdate(status, monitor);
+ }
+ catch (Exception e) {
+ RDTLog.logError(e);
+ }
+
+ DataElement element = status.get(0);
+
+ String data = element.getName();
+ try {
+ Object result = Serializer.deserialize(data);
+ if (result == null || !(result instanceof FoldingRegionsResult)) {
+ return null;
+ }
+ return (FoldingRegionsResult) result;
+ } catch (IOException e) {
+ RDTLog.logError(e);
+ } catch (ClassNotFoundException e) {
+ RDTLog.logError(e);
+ }
+ return null;
+ }
+
}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteCCodeFoldingService.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteCCodeFoldingService.java
new file mode 100644
index 0000000..b74f1c7
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteCCodeFoldingService.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.ui.editor;
+
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
+
+/**
+ * Provides code folding regions from the remote host.
+ */
+public interface IRemoteCCodeFoldingService {
+ /**
+ * Add what this does
+ *
+ * @param
+ * @return
+ */
+ FoldingRegionsResult computeCodeFoldingRegions(IWorkingCopy workingCopy, int docLength, boolean fPreprocessorBranchFoldingEnabled, boolean fStatementsFoldingEnabled);
+}
+
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteSemanticHighlightingService.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteSemanticHighlightingService.java
new file mode 100644
index 0000000..96e82f3
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/IRemoteSemanticHighlightingService.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.ui.editor;
+
+import org.eclipse.cdt.core.model.IWorkingCopy;
+
+/**
+ * Provides Semantic Highlighting added and removed positions from the remote host.
+ */
+public interface IRemoteSemanticHighlightingService {
+ /**
+ * Returns a list of added and removed positions needed by the Presenter.
+ *
+ * @param working copy of the file
+ * @return A comma separated list of highlighting positions where Element x = the offset,
+ * x+1 = the length, x+2 is the Highlightings index.
+ */
+ String computeSemanticHighlightingPositions(IWorkingCopy workingCopy);
+}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCCodeFoldingService.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCCodeFoldingService.java
new file mode 100644
index 0000000..2551715
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCCodeFoldingService.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+
+
+package org.eclipse.ptp.internal.rdt.ui.editor;
+
+import java.util.Map;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.ptp.internal.rdt.core.RemoteIndexerInfoProviderFactory;
+import org.eclipse.ptp.internal.rdt.core.model.ModelAdapter;
+import org.eclipse.ptp.internal.rdt.core.model.TranslationUnit;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
+import org.eclipse.ptp.internal.rdt.core.serviceproviders.AbstractRemoteService;
+import org.eclipse.ptp.internal.rdt.core.subsystems.ICIndexSubsystem;
+import org.eclipse.ptp.rdt.core.RDTLog;
+import org.eclipse.rse.core.subsystems.IConnectorService;
+
+/**
+ * A service for computing code folding on a remote host.
+ */
+public class RemoteCCodeFoldingService extends AbstractRemoteService implements IRemoteCCodeFoldingService {
+ public RemoteCCodeFoldingService(IConnectorService connectorService) {
+ super(connectorService);
+ }
+
+ public RemoteCCodeFoldingService(ICIndexSubsystem subsystem) {
+ super(subsystem);
+ }
+
+ public FoldingRegionsResult computeCodeFoldingRegions(IWorkingCopy workingCopy, int docLength, boolean fPreprocessorBranchFoldingEnabled, boolean fStatementsFoldingEnabled) {
+ ICIndexSubsystem subsystem = getSubSystem();
+ if (subsystem == null)
+ return null;
+
+ ITranslationUnit unit = workingCopy.getTranslationUnit();
+
+ ITranslationUnit targetUnit;
+ try {
+ targetUnit = ModelAdapter.adaptElement(null, unit, 0, true);
+ } catch (CModelException e1) {
+ RDTLog.logError(e1);
+ return null;
+ } catch (Exception e) {
+ RDTLog.logError(e);
+ return null;
+ }
+
+ // TODO: This can potentially take a while. But we need
+ // to trigger scope initialization in case it hasn't
+ // been done for the project.
+ IProject project = unit.getCProject().getProject();
+ IProgressMonitor monitor = new NullProgressMonitor();
+ subsystem.checkProject(project, monitor);
+
+ if(targetUnit instanceof TranslationUnit) {
+ IScannerInfo scannerInfo = RemoteIndexerInfoProviderFactory.getScannerInfo(unit.getResource());
+ Map<String,String> langaugeProperties = null;
+ try {
+ String languageId = unit.getLanguage().getId();
+ langaugeProperties = RemoteIndexerInfoProviderFactory.getLanguageProperties(languageId, project);
+ } catch(Exception e) {
+ RDTLog.logError(e);
+ }
+ ((TranslationUnit)targetUnit).setASTContext(scannerInfo, langaugeProperties);
+ }
+
+ return subsystem.computeFoldingRegions(targetUnit, docLength, fPreprocessorBranchFoldingEnabled, fStatementsFoldingEnabled);
+ }
+
+
+}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCEditorInfoProvider.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCEditorInfoProvider.java
index 5870df1..c229121 100644
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCEditorInfoProvider.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCEditorInfoProvider.java
@@ -14,9 +14,12 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.ui.editor.CContentOutlinePage;
+import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings;
import org.eclipse.cdt.internal.ui.text.CTextTools;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.actions.CdtActionConstants;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.core.resources.IProject;
@@ -25,8 +28,10 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.help.IContextProvider;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.ptp.internal.rdt.editor.RemoteCEditor;
import org.eclipse.ptp.internal.rdt.ui.RDTHelpContextIds;
import org.eclipse.ptp.internal.rdt.ui.actions.OpenViewActionGroup;
@@ -58,6 +63,13 @@ public class RemoteCEditorInfoProvider implements IRemoteCEditorInfoProvider {
private RemoteCEditor editor;
private IEditorInput input;
+
+ /**
+ * Remote Semantic highlighting manager
+ */
+ private RemoteSemanticHighlightingManager fRemoteSemanticManager;
+
+ private RemoteCFoldingStructureProvider fRemoteFoldingProvider;
/* (non-Javadoc)
* @see org.eclipse.ptp.rdt.editor.info.IRemoteCEditorInfoProvider#initializeEditor(org.eclipse.ptp.internal.rdt.editor.RemoteCEditor)
@@ -216,8 +228,7 @@ public class RemoteCEditorInfoProvider implements IRemoteCEditorInfoProvider {
* @see org.eclipse.ptp.rdt.editor.info.IRemoteCEditorInfoProvider#dispose()
*/
public void dispose() {
- // nothing to do
-
+ uninstallRemoteCodeFolding();
}
/* (non-Javadoc)
@@ -411,8 +422,50 @@ public class RemoteCEditorInfoProvider implements IRemoteCEditorInfoProvider {
return isLocalServiceProvider();
}
- public Boolean isSemanticHighlightingEnabled() {
- return isRemote() ? new Boolean(false) : null;
+ /**
+ * Install Semantic Highlighting.
+ */
+ public void installSemanticHighlighting(ISourceViewer sourceViewer, IPreferenceStore prefStore) {
+ if (!isLocalServiceProvider() && fRemoteSemanticManager == null && isSemanticHighlightingEnabled(prefStore)) {
+ fRemoteSemanticManager= new RemoteSemanticHighlightingManager();
+ fRemoteSemanticManager.install(editor, (CSourceViewer) sourceViewer, CUIPlugin.getDefault().getTextTools().getColorManager(), prefStore);
+ } else if (isLocalServiceProvider()) { //airplane mode
+ //reset so when workspace is online, semantic highlighting gets triggered
+ uninstallSemanticHighlighting();
+ }
+ }
+
+ public void refreshRemoteSemanticManager() {
+ if (fRemoteSemanticManager != null)
+ fRemoteSemanticManager.refresh();
+ }
+
+ public boolean isSemanticHighlightingEnabled(IPreferenceStore prefStore) {
+ return SemanticHighlightings.isEnabled(prefStore) && !(editor.isEnableScalablilityMode() && prefStore.getBoolean(PreferenceConstants.SCALABILITY_SEMANTIC_HIGHLIGHT));
+ }
+
+ public void installRemoteCodeFolding(ISourceViewer sourceViewer){
+ String id= CUIPlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
+
+ // If the folding provider is the default one and we are not
+ // in off-line mode, then uninstall local folding and install remote folding:
+ if (id.compareTo("org.eclipse.cdt.ui.text.defaultFoldingProvider") == 0 && !isLocalServiceProvider()) { //$NON-NLS-1$
+ editor.uninstallProjectionModelUpdater();
+ fRemoteFoldingProvider = new RemoteCFoldingStructureProvider();
+ ProjectionViewer projectionViewer = (ProjectionViewer) sourceViewer;
+ fRemoteFoldingProvider.install(editor, projectionViewer);
+ }
+ }
+
+ public void uninstallRemoteCodeFolding() {
+ if (fRemoteFoldingProvider != null)
+ fRemoteFoldingProvider.uninstall();
}
+ public void uninstallSemanticHighlighting() {
+ if (fRemoteSemanticManager != null) {
+ fRemoteSemanticManager.uninstall();
+ fRemoteSemanticManager= null;
+ }
+ }
}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCFoldingStructureProvider.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCFoldingStructureProvider.java
new file mode 100644
index 0000000..5feda50
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCFoldingStructureProvider.java
@@ -0,0 +1,1528 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.ui.editor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.projection.IProjectionListener;
+import org.eclipse.jface.text.source.projection.IProjectionPosition;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.Branch;
+import org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.StatementRegion;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
+import org.eclipse.ptp.internal.rdt.editor.RemoteCEditor;
+import org.eclipse.ptp.rdt.core.services.IRDTServiceConstants;
+import org.eclipse.ptp.rdt.ui.serviceproviders.IIndexServiceProvider2;
+import org.eclipse.ptp.services.core.IService;
+import org.eclipse.ptp.services.core.IServiceConfiguration;
+import org.eclipse.ptp.services.core.IServiceModelManager;
+import org.eclipse.ptp.services.core.IServiceProvider;
+import org.eclipse.ptp.services.core.ServiceModelManager;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
+import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
+import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
+import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
+import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
+import org.eclipse.cdt.core.dom.ast.IASTForStatement;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
+import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElseStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfndefStatement;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
+import org.eclipse.cdt.core.dom.ast.IASTProblem;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.IParent;
+import org.eclipse.cdt.core.model.ISourceRange;
+import org.eclipse.cdt.core.model.ISourceReference;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.core.parser.IProblem;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.IWorkingCopyManager;
+import org.eclipse.cdt.ui.PreferenceConstants;
+import org.eclipse.cdt.ui.text.ICPartitions;
+import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider;
+
+import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+import org.eclipse.cdt.internal.core.model.ASTCache;
+
+import org.eclipse.cdt.internal.ui.editor.ASTProvider;
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.internal.ui.editor.ASTProvider.WAIT_FLAG;
+import org.eclipse.cdt.internal.ui.text.DocumentCharacterIterator;
+import org.eclipse.cdt.internal.ui.text.ICReconcilingListener;
+
+/**
+ * Remote implementation of a {@link ICFoldingStructureProvider}.
+ * <p>
+ * Derived from DefaultCFoldingStructureProvider.
+ * </p>
+ */
+public class RemoteCFoldingStructureProvider implements ICFoldingStructureProvider {
+
+ /**
+ * Listen to cursor position changes.
+ */
+ private final class SelectionListener implements ISelectionChangedListener {
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection s= event.getSelection();
+ if (s instanceof ITextSelection) {
+ ITextSelection selection= (ITextSelection)event.getSelection();
+ fCursorPosition= selection.getOffset();
+ }
+ }
+ }
+
+ /**
+ * Update folding positions triggered by reconciler.
+ */
+ protected class FoldingStructureReconciler implements ICReconcilingListener {
+ private volatile boolean fReconciling;
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#aboutToBeReconciled()
+ */
+ public void aboutToBeReconciled() {
+
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.ICReconcilingListener#reconciled(IASTTranslationUnit, boolean, IProgressMonitor)
+ */
+ public void reconciled(IASTTranslationUnit ast, boolean force, IProgressMonitor progressMonitor) {
+ if (fInput == null || progressMonitor.isCanceled()) {
+ return;
+ }
+ synchronized (this) {
+ if (fReconciling) {
+ return;
+ }
+ fReconciling= true;
+ }
+ try {
+ final boolean initialReconcile= fInitialReconcilePending;
+ fInitialReconcilePending= false;
+ FoldingStructureComputationContext ctx= createContext(initialReconcile);
+ if (ctx != null) {
+ update(ctx);
+ }
+ } finally {
+ fReconciling= false;
+ }
+ }
+ }
+
+
+ /**
+ * A context that contains the information needed to compute the folding structure of an
+ * {@link ITranslationUnit}. Computed folding regions are collected via
+ * {@linkplain #addProjectionRange(RemoteCFoldingStructureProvider.CProjectionAnnotation, Position) addProjectionRange}.
+ */
+ public final class FoldingStructureComputationContext {
+ private final ProjectionAnnotationModel fModel;
+ private final IDocument fDocument;
+ private final boolean fAllowCollapsing;
+
+ private ISourceReference fFirstType;
+ private boolean fHasHeaderComment;
+ private LinkedHashMap<CProjectionAnnotation,Position> fMap= new LinkedHashMap<CProjectionAnnotation,Position>();
+ private IASTTranslationUnit fAST;
+
+
+
+ FoldingStructureComputationContext(IDocument document, ProjectionAnnotationModel model, boolean allowCollapsing) {
+ Assert.isNotNull(document);
+ Assert.isNotNull(model);
+ fDocument= document;
+ fModel= model;
+ fAllowCollapsing= allowCollapsing;
+ }
+
+ void setFirstType(ISourceReference reference) {
+ if (hasFirstType())
+ throw new IllegalStateException();
+ fFirstType= reference;
+ }
+
+ boolean hasFirstType() {
+ return fFirstType != null;
+ }
+
+ ISourceReference getFirstType() {
+ return fFirstType;
+ }
+
+ boolean hasHeaderComment() {
+ return fHasHeaderComment;
+ }
+
+ void setHasHeaderComment() {
+ fHasHeaderComment= true;
+ }
+
+ /**
+ * Returns <code>true</code> if newly created folding regions may be collapsed,
+ * <code>false</code> if not. This is usually <code>false</code> when updating the
+ * folding structure while typing; it may be <code>true</code> when computing or restoring
+ * the initial folding structure.
+ *
+ * @return <code>true</code> if newly created folding regions may be collapsed,
+ * <code>false</code> if not
+ */
+ public boolean allowCollapsing() {
+ return fAllowCollapsing;
+ }
+
+ /**
+ * Returns the document which contains the code being folded.
+ *
+ * @return the document which contains the code being folded
+ */
+ IDocument getDocument() {
+ return fDocument;
+ }
+
+ ProjectionAnnotationModel getModel() {
+ return fModel;
+ }
+
+ /**
+ * Adds a projection (folding) region to this context. The created annotation / position
+ * pair will be added to the {@link ProjectionAnnotationModel} of the
+ * {@link ProjectionViewer} of the editor.
+ *
+ * @param annotation the annotation to add
+ * @param position the corresponding position
+ */
+ public void addProjectionRange(CProjectionAnnotation annotation, Position position) {
+ fMap.put(annotation, position);
+ }
+
+ /**
+ * Returns <code>true</code> if header comments should be collapsed.
+ *
+ * @return <code>true</code> if header comments should be collapsed
+ */
+ public boolean collapseHeaderComments() {
+ return fAllowCollapsing && fCollapseHeaderComments;
+ }
+
+ /**
+ * Returns <code>true</code> if comments should be collapsed.
+ *
+ * @return <code>true</code> if comments should be collapsed
+ */
+ public boolean collapseComments() {
+ return fAllowCollapsing && fCollapseComments;
+ }
+
+ /**
+ * Returns <code>true</code> if functions should be collapsed.
+ *
+ * @return <code>true</code> if functions should be collapsed
+ */
+ public boolean collapseFunctions() {
+ return fAllowCollapsing && fCollapseFunctions;
+ }
+
+ /**
+ * Returns <code>true</code> if macros should be collapsed.
+ *
+ * @return <code>true</code> if macros should be collapsed
+ */
+ public boolean collapseMacros() {
+ return fAllowCollapsing && fCollapseMacros;
+ }
+
+ /**
+ * Returns <code>true</code> if methods should be collapsed.
+ *
+ * @return <code>true</code> if methods should be collapsed
+ */
+ public boolean collapseMethods() {
+ return fAllowCollapsing && fCollapseMethods;
+ }
+
+ /**
+ * Returns <code>true</code> if structures should be collapsed.
+ *
+ * @return <code>true</code> if structures should be collapsed
+ */
+ public boolean collapseStructures() {
+ return fAllowCollapsing && fCollapseStructures;
+ }
+
+ /**
+ * Returns <code>true</code> if inactive code should be collapsed.
+ *
+ * @return <code>true</code> if inactive code should be collapsed
+ */
+ public boolean collapseInactiveCode() {
+ return fAllowCollapsing && fCollapseInactiveCode;
+ }
+
+ /**
+ * @return the current AST or <code>null</code>
+ */
+ public IASTTranslationUnit getAST() {
+ return fAST;
+ }
+ }
+
+
+ private static class CProjectionAnnotation extends ProjectionAnnotation {
+
+ public final static int CMODEL= 0;
+ public final static int COMMENT= 1;
+ public final static int BRANCH= 2;
+ public final static int STATEMENT= 3;
+
+ private Object fKey;
+ private int fCategory;
+
+ public CProjectionAnnotation(boolean isCollapsed, Object key, boolean isComment) {
+ this(isCollapsed, key, isComment ? COMMENT : 0);
+ }
+
+ public CProjectionAnnotation(boolean isCollapsed, Object key, int category) {
+ super(isCollapsed);
+ fKey= key;
+ fCategory= category;
+ }
+
+ public Object getElement() {
+ return fKey;
+ }
+
+ public void setElement(Object element) {
+ fKey= element;
+ }
+
+ public int getCategory() {
+ return fCategory;
+ }
+ /*
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "CProjectionAnnotation:\n" + //$NON-NLS-1$
+ "\tkey: \t"+ fKey + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
+ "\tcollapsed: \t" + isCollapsed() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
+ "\tcategory: \t" + getCategory() + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+
+ private static final class Tuple {
+ CProjectionAnnotation annotation;
+ Position position;
+ Tuple(CProjectionAnnotation annotation, Position position) {
+ this.annotation= annotation;
+ this.position= position;
+ }
+ }
+
+ private static final class Counter {
+ int fCount;
+ }
+
+ /**
+ * Projection position that will return two foldable regions: one folding away
+ * the region from after the '/*' to the beginning of the content, the other
+ * from after the first content line until after the comment.
+ */
+ private static final class CommentPosition extends Position implements IProjectionPosition {
+ CommentPosition(int offset, int length) {
+ super(offset, length);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument)
+ */
+ public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException {
+ DocumentCharacterIterator sequence= new DocumentCharacterIterator(document, offset, offset + length);
+ int prefixEnd= 0;
+ int contentStart= findFirstContent(sequence, prefixEnd);
+
+ int firstLine= document.getLineOfOffset(offset + prefixEnd);
+ int captionLine= document.getLineOfOffset(offset + contentStart);
+ int lastLine= document.getLineOfOffset(offset + length);
+
+ Assert.isTrue(firstLine <= captionLine, "first folded line is greater than the caption line"); //$NON-NLS-1$
+ Assert.isTrue(captionLine <= lastLine, "caption line is greater than the last folded line"); //$NON-NLS-1$
+
+ IRegion preRegion;
+ if (firstLine < captionLine) {
+ int preOffset= document.getLineOffset(firstLine);
+ IRegion preEndLineInfo= document.getLineInformation(captionLine);
+ int preEnd= preEndLineInfo.getOffset();
+ preRegion= new Region(preOffset, preEnd - preOffset);
+ } else {
+ preRegion= null;
+ }
+
+ if (captionLine < lastLine) {
+ int postOffset= document.getLineOffset(captionLine + 1);
+ IRegion postRegion= new Region(postOffset, offset + length - postOffset);
+
+ if (preRegion == null)
+ return new IRegion[] { postRegion };
+
+ return new IRegion[] { preRegion, postRegion };
+ }
+
+ if (preRegion != null)
+ return new IRegion[] { preRegion };
+
+ return null;
+ }
+
+ /**
+ * Finds the offset of the first identifier part within <code>content</code>.
+ * Returns 0 if none is found.
+ *
+ * @param content the content to search
+ * @return the first index of a unicode identifier part, or zero if none can
+ * be found
+ */
+ private int findFirstContent(final CharSequence content, int prefixEnd) {
+ int lenght= content.length();
+ for (int i= prefixEnd; i < lenght; i++) {
+ if (Character.isUnicodeIdentifierPart(content.charAt(i)))
+ return i;
+ }
+ return 0;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument)
+ */
+ public int computeCaptionOffset(IDocument document) {
+ DocumentCharacterIterator sequence= new DocumentCharacterIterator(document, offset, offset + length);
+ return findFirstContent(sequence, 0);
+ }
+ }
+
+ /**
+ * Projection position that will return two foldable regions: one folding away
+ * the lines before the one containing the simple name of the C element, one
+ * folding away any lines after the caption.
+ */
+ private static final class CElementPosition extends Position implements IProjectionPosition {
+
+ private ICElement fElement;
+
+ public CElementPosition(int offset, int length, ICElement element) {
+ super(offset, length);
+ Assert.isNotNull(element);
+ fElement= element;
+ }
+
+ public void setElement(ICElement member) {
+ Assert.isNotNull(member);
+ fElement= member;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument)
+ */
+ public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException {
+ int captionOffset= offset;
+ try {
+ /* The member's name range may not be correct. However,
+ * reconciling would trigger another element delta which would
+ * lead to reentrant situations. Therefore, we optimistically
+ * assume that the name range is correct, but double check the
+ * received lines below. */
+ if (fElement instanceof ISourceReference) {
+ ISourceRange sourceRange= ((ISourceReference) fElement).getSourceRange();
+ if (sourceRange != null) {
+ // Use end of name range for the caption offset
+ // in case a qualified name is split on multiple lines (bug 248613).
+ captionOffset= sourceRange.getIdStartPos() + sourceRange.getIdLength() - 1;
+ }
+ }
+ } catch (CModelException e) {
+ // ignore and use default
+ }
+
+ int firstLine= document.getLineOfOffset(offset);
+ int captionLine= document.getLineOfOffset(captionOffset);
+ int lastLine= document.getLineOfOffset(offset + length);
+
+ /* see comment above - adjust the caption line to be inside the
+ * entire folded region, and rely on later element deltas to correct
+ * the name range. */
+ if (captionLine < firstLine)
+ captionLine= firstLine;
+ if (captionLine > lastLine)
+ captionLine= lastLine;
+
+ IRegion preRegion;
+ if (firstLine < captionLine) {
+ int preOffset= document.getLineOffset(firstLine);
+ IRegion preEndLineInfo= document.getLineInformation(captionLine);
+ int preEnd= preEndLineInfo.getOffset();
+ preRegion= new Region(preOffset, preEnd - preOffset);
+ } else {
+ preRegion= null;
+ }
+
+ if (captionLine < lastLine) {
+ int postOffset= document.getLineOffset(captionLine + 1);
+ IRegion postRegion= new Region(postOffset, offset + length - postOffset);
+
+ if (preRegion == null)
+ return new IRegion[] { postRegion };
+
+ return new IRegion[] { preRegion, postRegion };
+ }
+
+ if (preRegion != null)
+ return new IRegion[] { preRegion };
+
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument)
+ */
+ public int computeCaptionOffset(IDocument document) throws BadLocationException {
+ int captionOffset= offset;
+ try {
+ // need a reconcile here?
+ if (fElement instanceof ISourceReference) {
+ ISourceRange sourceRange= ((ISourceReference) fElement).getSourceRange();
+ if (sourceRange != null) {
+ captionOffset= sourceRange.getIdStartPos() + sourceRange.getIdLength() - 1;
+ if (captionOffset < offset) {
+ captionOffset= offset;
+ }
+ }
+ }
+ } catch (CModelException e) {
+ // ignore and use default
+ }
+
+ return captionOffset - offset;
+ }
+
+ }
+
+ /**
+ * Internal projection listener.
+ */
+ private final class ProjectionListener implements IProjectionListener {
+ private ProjectionViewer fViewer;
+
+ /**
+ * Registers the listener with the viewer.
+ *
+ * @param viewer the viewer to register a listener with
+ */
+ public ProjectionListener(ProjectionViewer viewer) {
+ Assert.isLegal(viewer != null);
+ fViewer= viewer;
+ fViewer.addProjectionListener(this);
+ }
+
+ /**
+ * Disposes of this listener and removes the projection listener from the viewer.
+ */
+ public void dispose() {
+ if (fViewer != null) {
+ fViewer.removeProjectionListener(this);
+ fViewer= null;
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled()
+ */
+ public void projectionEnabled() {
+ handleProjectionEnabled();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled()
+ */
+ public void projectionDisabled() {
+ handleProjectionDisabled();
+ }
+ }
+
+ /**
+ * Implementation of <code>IRegion</code> that can be reused
+ * by setting the offset and the length.
+ */
+ private static class ModifiableRegion extends Position implements IRegion {
+ ModifiableRegion() {
+ super();
+ }
+ ModifiableRegion(int offset, int length) {
+ super(offset, length);
+ }
+ }
+
+ /**
+ * Representation of a preprocessor code branch.
+ */
+ private static class Branch extends ModifiableRegion {
+
+ private final boolean fTaken;
+ public final String fCondition;
+ public boolean fInclusive;
+
+ Branch(int offset, boolean taken, String key) {
+ this(offset, 0, taken, key);
+ }
+
+ Branch(int offset, int length, boolean taken, String key) {
+ super(offset, length);
+ fTaken= taken;
+ fCondition= key;
+ }
+
+ public void setEndOffset(int endOffset) {
+ setLength(endOffset - getOffset());
+ }
+
+ public boolean taken() {
+ return fTaken;
+ }
+
+ public void setInclusive(boolean inclusive) {
+ fInclusive= inclusive;
+ }
+
+ Branch(org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.Branch inBranch) {
+ this(inBranch.getOffset(), inBranch.getLength(), inBranch.taken(), inBranch.fCondition);
+ setInclusive(inBranch.fInclusive);
+ }
+ }
+
+ private final static boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.cdt.ui/debug/folding")); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private ITextEditor fEditor;
+ private ProjectionListener fProjectionListener;
+ protected ICElement fInput;
+
+ private boolean fCollapseHeaderComments= true;
+ private boolean fCollapseComments= false;
+ private boolean fCollapseMacros= false;
+ private boolean fCollapseFunctions= true;
+ private boolean fCollapseStructures= true;
+ private boolean fCollapseMethods= false;
+ private boolean fCollapseInactiveCode= true;
+
+ private int fMinCommentLines= 1;
+ private boolean fPreprocessorBranchFoldingEnabled= true;
+ private boolean fStatementsFoldingEnabled= false;
+ private boolean fCommentFoldingEnabled= true;
+
+ private ICReconcilingListener fReconilingListener;
+ private volatile boolean fInitialReconcilePending= true;
+
+ private int fCursorPosition;
+
+ private SelectionListener fSelectionListener;
+
+
+ /**
+ * Creates a new folding provider. It must be
+ * {@link #install(ITextEditor, ProjectionViewer) installed} on an editor/viewer pair before it
+ * can be used, and {@link #uninstall() uninstalled} when not used any longer.
+ * <p>
+ * The projection state may be reset by calling {@link #initialize()}.
+ * </p>
+ */
+ public RemoteCFoldingStructureProvider() {
+ }
+
+ /*
+ * @see org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider#install(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.projection.ProjectionViewer)
+ */
+ public void install(ITextEditor editor, ProjectionViewer viewer) {
+ Assert.isLegal(editor != null);
+ Assert.isLegal(viewer != null);
+
+ internalUninstall();
+
+ if (editor instanceof CEditor) {
+ fEditor= editor;
+ fProjectionListener= new ProjectionListener(viewer);
+ }
+ }
+
+ /*
+ * @see org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider#uninstall()
+ */
+ public void uninstall() {
+ internalUninstall();
+ }
+
+ /**
+ * Internal implementation of {@link #uninstall()}.
+ */
+ private void internalUninstall() {
+ if (isInstalled()) {
+ handleProjectionDisabled();
+ fProjectionListener.dispose();
+ fProjectionListener= null;
+ fEditor= null;
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the provider is installed, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the provider is installed, <code>false</code> otherwise
+ */
+ protected final boolean isInstalled() {
+ return fEditor != null;
+ }
+
+ /**
+ * Called whenever projection is enabled, for example when the viewer issues a
+ * {@link IProjectionListener#projectionEnabled() projectionEnabled} message. When the provider
+ * is already enabled when this method is called, it is first
+ * {@link #handleProjectionDisabled() disabled}.
+ * <p>
+ * Subclasses may extend.
+ * </p>
+ */
+ protected void handleProjectionEnabled() {
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.handleProjectionEnabled()"); //$NON-NLS-1$
+ // projectionEnabled messages are not always paired with projectionDisabled
+ // i.e. multiple enabled messages may be sent out.
+ // we have to make sure that we disable first when getting an enable
+ // message.
+ handleProjectionDisabled();
+
+ if (fEditor instanceof CEditor) {
+ initialize();
+ fReconilingListener= new FoldingStructureReconciler();
+ ((CEditor)fEditor).addReconcileListener(fReconilingListener);
+ fSelectionListener= new SelectionListener();
+ fEditor.getSelectionProvider().addSelectionChangedListener(fSelectionListener);
+ }
+ }
+
+ /**
+ * Called whenever projection is disabled, for example when the provider is
+ * {@link #uninstall() uninstalled}, when the viewer issues a
+ * {@link IProjectionListener#projectionDisabled() projectionDisabled} message and before
+ * {@link #handleProjectionEnabled() enabling} the provider. Implementations must be prepared to
+ * handle multiple calls to this method even if the provider is already disabled.
+ * <p>
+ * Subclasses may extend.
+ * </p>
+ */
+ protected void handleProjectionDisabled() {
+ if (fReconilingListener != null) {
+ ((CEditor)fEditor).removeReconcileListener(fReconilingListener);
+ fReconilingListener= null;
+ }
+ if (fSelectionListener != null) {
+ fEditor.getSelectionProvider().removeSelectionChangedListener(fSelectionListener);
+ fSelectionListener= null;
+ }
+ }
+
+ /*
+ * @see org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider#initialize()
+ */
+ public final void initialize() {
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.initialize()"); //$NON-NLS-1$
+ fInitialReconcilePending= true;
+ fCursorPosition= -1;
+ update(createInitialContext());
+ }
+
+ private FoldingStructureComputationContext createInitialContext() {
+ initializePreferences();
+ fInput= getInputElement();
+ if (fInput == null)
+ return null;
+
+ return createContext(true);
+ }
+
+ private FoldingStructureComputationContext createContext(boolean allowCollapse) {
+ if (!isInstalled())
+ return null;
+ ProjectionAnnotationModel model= getModel();
+ if (model == null)
+ return null;
+ IDocument doc= getDocument();
+ if (doc == null)
+ return null;
+
+ return new FoldingStructureComputationContext(doc, model, allowCollapse);
+ }
+
+ private ICElement getInputElement() {
+ if (fEditor instanceof RemoteCEditor) {
+ return ((RemoteCEditor)fEditor).getInputCElement();
+ }
+ return null;
+ }
+
+ private void initializePreferences() {
+ IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
+ fCollapseFunctions= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_FUNCTIONS);
+ fCollapseStructures= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_STRUCTURES);
+ fCollapseMacros= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_MACROS);
+ fCollapseMethods= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_METHODS);
+ fCollapseHeaderComments= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_HEADERS);
+ fCollapseComments= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_COMMENTS);
+ fCollapseInactiveCode= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE);
+ fPreprocessorBranchFoldingEnabled= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_PREPROCESSOR_BRANCHES_ENABLED);
+ fStatementsFoldingEnabled= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_STATEMENTS);
+ fCommentFoldingEnabled = true;
+ }
+
+ private void update(FoldingStructureComputationContext ctx) {
+
+ if (ctx == null || !isConsistent(fInput))
+ return;
+
+ if (!fInitialReconcilePending && fSelectionListener != null) {
+ fEditor.getSelectionProvider().removeSelectionChangedListener(fSelectionListener);
+ fSelectionListener= null;
+ }
+
+ Map<CProjectionAnnotation,Position> additions= new HashMap<CProjectionAnnotation,Position>();
+ List<CProjectionAnnotation> deletions= new ArrayList<CProjectionAnnotation>();
+ List<CProjectionAnnotation> updates= new ArrayList<CProjectionAnnotation>();
+
+ computeFoldingStructure(ctx);
+ Map<CProjectionAnnotation,Position> updated= ctx.fMap;
+ Map<Object, List<Tuple>> previous= computeCurrentStructure(ctx);
+
+ Iterator<CProjectionAnnotation> e= updated.keySet().iterator();
+ while (e.hasNext()) {
+ CProjectionAnnotation newAnnotation= e.next();
+ Object key= newAnnotation.getElement();
+ Position newPosition= updated.get(newAnnotation);
+
+ List<Tuple> annotations= previous.get(key);
+ if (annotations == null) {
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.update() new annotation " + newAnnotation); //$NON-NLS-1$
+
+ additions.put(newAnnotation, newPosition);
+
+ } else {
+ Iterator<Tuple> x= annotations.iterator();
+ boolean matched= false;
+ while (x.hasNext()) {
+ Tuple tuple= x.next();
+ CProjectionAnnotation existingAnnotation= tuple.annotation;
+ Position existingPosition= tuple.position;
+ if (newAnnotation.getCategory() == existingAnnotation.getCategory()) {
+ final boolean collapseChanged = ctx.allowCollapsing() && existingAnnotation.isCollapsed() != newAnnotation.isCollapsed();
+ if (existingPosition != null && (collapseChanged || !newPosition.equals(existingPosition))) {
+ existingPosition.setOffset(newPosition.getOffset());
+ existingPosition.setLength(newPosition.getLength());
+ if (collapseChanged) {
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.update() change annotation " + newAnnotation); //$NON-NLS-1$
+ if (newAnnotation.isCollapsed())
+ existingAnnotation.markCollapsed();
+ else
+ existingAnnotation.markExpanded();
+ }
+ updates.add(existingAnnotation);
+ }
+ matched= true;
+ x.remove();
+ break;
+ }
+ }
+ if (!matched) {
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.update() new annotation " + newAnnotation); //$NON-NLS-1$
+
+ additions.put(newAnnotation, newPosition);
+ }
+ if (annotations.isEmpty())
+ previous.remove(key);
+ }
+ }
+
+ Iterator<List<Tuple>> e2= previous.values().iterator();
+ while (e2.hasNext()) {
+ List<Tuple> list= e2.next();
+ int size= list.size();
+ for (int i= 0; i < size; i++) {
+ CProjectionAnnotation annotation= list.get(i).annotation;
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.update() deleted annotation " + annotation); //$NON-NLS-1$
+ deletions.add(annotation);
+ }
+ }
+
+ match(deletions, additions, updates, ctx);
+
+ Annotation[] removals= new Annotation[deletions.size()];
+ deletions.toArray(removals);
+ Annotation[] changes= new Annotation[updates.size()];
+ updates.toArray(changes);
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.update() "+removals.length+" deleted, "+additions.size()+" added, "+changes.length+" changed"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ ctx.getModel().modifyAnnotations(removals, additions, changes);
+ }
+
+ /**
+ * Matches deleted annotations to changed or added ones. A deleted
+ * annotation/position tuple that has a matching addition / change
+ * is updated and marked as changed. The matching tuple is not added
+ * (for additions) or marked as deletion instead (for changes). The
+ * result is that more annotations are changed and fewer get
+ * deleted/re-added.
+ */
+ private void match(List<CProjectionAnnotation> deletions, Map<CProjectionAnnotation,Position> additions,
+ List<CProjectionAnnotation> changes, FoldingStructureComputationContext ctx) {
+ if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty()))
+ return;
+
+ List<CProjectionAnnotation> newDeletions= new ArrayList<CProjectionAnnotation>();
+ List<CProjectionAnnotation> newChanges= new ArrayList<CProjectionAnnotation>();
+
+ Iterator<CProjectionAnnotation> deletionIterator= deletions.iterator();
+ while (deletionIterator.hasNext()) {
+ CProjectionAnnotation deleted= deletionIterator.next();
+ Position deletedPosition= ctx.getModel().getPosition(deleted);
+ if (deletedPosition == null || deletedPosition.length < 5)
+ continue;
+
+ Tuple deletedTuple= new Tuple(deleted, deletedPosition);
+
+ Tuple match= findMatch(deletedTuple, changes, null, ctx);
+ boolean addToDeletions= true;
+ if (match == null) {
+ match= findMatch(deletedTuple, additions.keySet(), additions, ctx);
+ addToDeletions= false;
+ }
+
+ if (match != null) {
+ Object element= match.annotation.getElement();
+ deleted.setElement(element);
+ deletedPosition.setLength(match.position.getLength());
+ if (deletedPosition instanceof CElementPosition && element instanceof ICElement) {
+ CElementPosition cep= (CElementPosition) deletedPosition;
+ cep.setElement((ICElement) element);
+ }
+
+ deletionIterator.remove();
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.update() changed annotation " + deleted); //$NON-NLS-1$
+ newChanges.add(deleted);
+
+ if (addToDeletions) {
+ if (DEBUG) System.out.println("RemoteCFoldingStructureProvider.update() deleted annotation " + match.annotation); //$NON-NLS-1$
+ newDeletions.add(match.annotation);
+ }
+ }
+ }
+
+ deletions.addAll(newDeletions);
+ changes.addAll(newChanges);
+ }
+
+ /**
+ * Finds a match for <code>tuple</code> in a collection of
+ * annotations. The positions for the
+ * <code>CProjectionAnnotation</code> instances in
+ * <code>annotations</code> can be found in the passed
+ * <code>positionMap</code> or in the model if
+ * <code>positionMap</code> is <code>null</code>.
+ * <p>
+ * A tuple is said to match another if their annotations have the
+ * same category and their position offsets are equal.
+ * </p>
+ * <p>
+ * If a match is found, the annotation gets removed from
+ * <code>annotations</code>.
+ * </p>
+ *
+ * @param tuple the tuple for which we want to find a match
+ * @param annotations collection of
+ * <code>CProjectionAnnotation</code>
+ * @param positionMap a <code>Map&lt;Annotation, Position&gt;</code>
+ * or <code>null</code>
+ * @return a matching tuple or <code>null</code> for no match
+ */
+ private Tuple findMatch(Tuple tuple, Collection<CProjectionAnnotation> annotations, Map<CProjectionAnnotation,Position> positionMap, FoldingStructureComputationContext ctx) {
+ Iterator<CProjectionAnnotation> it= annotations.iterator();
+ while (it.hasNext()) {
+ CProjectionAnnotation annotation= it.next();
+ if (tuple.annotation.getCategory() == annotation.getCategory()) {
+ Position position= positionMap == null ? ctx.getModel().getPosition(annotation) : positionMap.get(annotation);
+ if (position == null)
+ continue;
+
+ if (tuple.position.getOffset() == position.getOffset()) {
+ it.remove();
+ return new Tuple(annotation, position);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private Map<Object, List<Tuple>> computeCurrentStructure(FoldingStructureComputationContext ctx) {
+ boolean includeBranches= fPreprocessorBranchFoldingEnabled;
+ boolean includeStmts= fStatementsFoldingEnabled;
+ boolean includeCModel= true;
+ Map<Object, List<Tuple>> map= new HashMap<Object, List<Tuple>>();
+ ProjectionAnnotationModel model= ctx.getModel();
+ Iterator<?> e= model.getAnnotationIterator();
+ while (e.hasNext()) {
+ Object annotation= e.next();
+ if (annotation instanceof CProjectionAnnotation) {
+ CProjectionAnnotation cAnnotation= (CProjectionAnnotation) annotation;
+ final boolean include;
+ switch (cAnnotation.getCategory()) {
+ case CProjectionAnnotation.BRANCH:
+ include= includeBranches;
+ break;
+ case CProjectionAnnotation.STATEMENT:
+ include= includeStmts;
+ break;
+ case CProjectionAnnotation.CMODEL:
+ include= includeCModel;
+ break;
+ default:
+ include= true;
+ break;
+ }
+ Position position= model.getPosition(cAnnotation);
+ assert position != null;
+ if (include || position.length < 5) {
+ List<Tuple> list= map.get(cAnnotation.getElement());
+ if (list == null) {
+ list= new ArrayList<Tuple>(2);
+ map.put(cAnnotation.getElement(), list);
+ }
+ list.add(new Tuple(cAnnotation, position));
+ }
+ }
+ }
+
+ Comparator<Tuple> comparator= new Comparator<Tuple>() {
+ public int compare(Tuple t1, Tuple t2) {
+ return t1.position.getOffset() - t2.position.getOffset();
+ }
+ };
+ for(List<Tuple> list : map.values()) {
+ Collections.sort(list, comparator);
+ }
+ return map;
+ }
+
+ private IRemoteCCodeFoldingService getCodeFoldingService(IProject project) {
+ IServiceModelManager smm = ServiceModelManager.getInstance();
+ IServiceConfiguration serviceConfig = smm.getActiveConfiguration(project);
+ IService indexingService = smm.getService(IRDTServiceConstants.SERVICE_C_INDEX);
+ IServiceProvider serviceProvider = serviceConfig.getServiceProvider(indexingService);
+ if (!(serviceProvider instanceof IIndexServiceProvider2)) {
+ return null;
+ }
+ IRemoteCCodeFoldingService service = ((IIndexServiceProvider2) serviceProvider).getRemoteCodeFoldingService();
+ return service;
+ }
+
+ private void computeFoldingStructure(final FoldingStructureComputationContext ctx) {
+ final Stack<StatementRegion> iral = new Stack<StatementRegion>();
+ List<Branch> branches = new ArrayList<Branch>();
+
+ if (fCommentFoldingEnabled) {
+ // compute comment positions from partitioning
+ try {
+ IDocument doc = ctx.getDocument();
+ ITypedRegion[] partitions = TextUtilities.computePartitioning(doc, ICPartitions.C_PARTITIONING, 0, doc.getLength(), false);
+ computeFoldingStructure(partitions, ctx);
+ } catch (BadLocationException e) {
+ // ignore
+ }
+ }
+ final boolean needAST= fPreprocessorBranchFoldingEnabled || fStatementsFoldingEnabled;
+ if (needAST) {
+ IProject project = ((RemoteCEditor) fEditor).getInputCElement().getCProject().getProject();
+ IWorkingCopyManager fManager= CUIPlugin.getDefault().getWorkingCopyManager();
+ IWorkingCopy workingCopy= fManager.getWorkingCopy(fEditor.getEditorInput());
+ IRemoteCCodeFoldingService cfs = getCodeFoldingService(project);
+ FoldingRegionsResult rr = cfs.computeCodeFoldingRegions(workingCopy, getDocument().getLength(), fPreprocessorBranchFoldingEnabled, fStatementsFoldingEnabled);
+
+ if (fStatementsFoldingEnabled && rr != null && rr.iral != null) {
+ Stack<StatementRegion> sr = new Stack<StatementRegion>();
+ while (!rr.iral.empty()) {
+ sr.push(new StatementRegion(rr.iral.pop()));
+ }
+ computeStatementFoldingStructure(sr, ctx);
+ }
+
+ if (fPreprocessorBranchFoldingEnabled && rr != null && rr.branches != null) {
+ List<Branch> br = new ArrayList<Branch>();
+ for (org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.Branch branch : rr.branches) {
+ br.add(new Branch(branch));
+ }
+ computePreprocessorFoldingStructure(br, ctx);
+ }
+
+ }
+
+ fInitialReconcilePending= false;
+ IParent parent= (IParent) fInput;
+ try {
+ computeFoldingStructure(parent.getChildren(), ctx);
+ } catch (CModelException x) {
+ }
+
+ }
+
+ static boolean isConsistent(ICElement element) {
+ if (element instanceof ITranslationUnit) {
+ try {
+ return ((ITranslationUnit)element).isConsistent();
+ } catch (CModelException exc) {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * A modifiable region with extra information about the region it holds.
+ * It tells us whether or not to include the last line of the region
+ */
+ private static class StatementRegion extends ModifiableRegion {
+ public final String function;
+ public int level;
+ public boolean inclusive;
+ public StatementRegion(String function, int level) {
+ this.function= function;
+ this.level= level;
+ }
+
+ StatementRegion(org.eclipse.ptp.internal.rdt.core.miners.RemoteFoldingRegionsHandler.StatementRegion sr) {
+ this.function= sr.function;
+ this.level= sr.level;
+ this.inclusive = sr.inclusive;
+ this.length = sr.getLength();
+ this.offset = sr.getOffset();
+ }
+ }
+
+ /**
+ * Computes folding structure of statements for the given AST.
+ *
+ * @param ast
+ * @param ctx
+ */
+ private void computeStatementFoldingStructure(Stack<StatementRegion> iral, FoldingStructureComputationContext ctx) {
+ while (!iral.empty()) {
+ StatementRegion mr = iral.pop();
+ IRegion aligned = alignRegion(mr, ctx,mr.inclusive);
+ if (aligned != null) {
+ Position alignedPos= new Position(aligned.getOffset(), aligned.getLength());
+ ctx.addProjectionRange(new CProjectionAnnotation(
+ false, mr.function + mr.level + computeKey(mr, ctx), CProjectionAnnotation.STATEMENT), alignedPos);
+ }
+ }
+ }
+
+ /**
+ * Computes folding structure for preprocessor branches for the given AST.
+ *
+ * @param ast
+ * @param ctx
+ */
+ private void computePreprocessorFoldingStructure(List<Branch> branches, FoldingStructureComputationContext ctx) {
+ Map<String, Counter> keys= new HashMap<String, Counter>(branches.size());
+ for (Branch branch : branches) {
+ IRegion aligned = alignRegion(branch, ctx, branch.fInclusive);
+ if (aligned != null) {
+ Position alignedPos= new Position(aligned.getOffset(), aligned.getLength());
+ final boolean collapse= !branch.taken() && ctx.collapseInactiveCode() && !alignedPos.includes(fCursorPosition);
+ // compute a stable key
+ String key = branch.fCondition;
+ Counter counter= keys.get(key);
+ if (counter == null) {
+ keys.put(key, new Counter());
+ } else {
+ key= Integer.toString(counter.fCount++) + key;
+ }
+ ctx.addProjectionRange(new CProjectionAnnotation(collapse, key, CProjectionAnnotation.BRANCH), alignedPos);
+ }
+ }
+ }
+
+ /**
+ * Compute a key for recognizing an annotation based on the given position.
+ *
+ * @param pos
+ * @param ctx
+ * @return a key to recognize an annotation position
+ */
+ private Object computeKey(Position pos, FoldingStructureComputationContext ctx) {
+ try {
+ final IDocument document= ctx.getDocument();
+ IRegion line= document.getLineInformationOfOffset(pos.offset);
+ return document.get(pos.offset, Math.min(32, line.getOffset() + line.getLength() - pos.offset));
+ } catch (BadLocationException exc) {
+ return exc;
+ }
+ }
+
+ /**
+ * Compute folding structure based on partioning information.
+ *
+ * @param partitions array of document partitions
+ * @param ctx the folding structure context
+ * @throws BadLocationException
+ */
+ private void computeFoldingStructure(ITypedRegion[] partitions, FoldingStructureComputationContext ctx) throws BadLocationException {
+ boolean collapse = ctx.collapseComments();
+ IDocument doc= ctx.getDocument();
+ int startLine = -1;
+ int endLine = -1;
+ List<Tuple> comments= new ArrayList<Tuple>();
+ ModifiableRegion commentRange = new ModifiableRegion();
+ for (ITypedRegion partition : partitions) {
+ boolean singleLine= false;
+ if (ICPartitions.C_MULTI_LINE_COMMENT.equals(partition.getType())
+ || ICPartitions.C_MULTI_LINE_DOC_COMMENT.equals(partition.getType())) {
+ Position position= createCommentPosition(alignRegion(partition, ctx, true));
+ if (position != null) {
+ if (startLine >= 0 && endLine - startLine >= fMinCommentLines) {
+ Position projection = createCommentPosition(alignRegion(commentRange, ctx, true));
+ if (projection != null) {
+ comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(projection.offset, Math.min(16, projection.length)), true), projection));
+ }
+ startLine= -1;
+ }
+ comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(position.offset, Math.min(16, position.length)), true), position));
+ } else {
+ singleLine= true;
+ }
+ } else {
+ singleLine= ICPartitions.C_SINGLE_LINE_COMMENT.equals(partition.getType());
+ }
+ if (singleLine) {
+ // if comment starts at column 0 and spans only one line
+ // and is adjacent to a previous line comment, add it
+ // to the commentRange
+ int lineNr = doc.getLineOfOffset(partition.getOffset());
+ IRegion lineRegion = doc.getLineInformation(lineNr);
+ boolean isLineStart = partition.getOffset() == lineRegion.getOffset();
+ if (!isLineStart) {
+ continue;
+ }
+ if (!singleLine) {
+ singleLine = lineRegion.getOffset() + lineRegion.getLength() >= partition.getOffset() + partition.getLength();
+ if (!singleLine) {
+ continue;
+ }
+ }
+ if (startLine < 0 || lineNr - endLine > 1) {
+ if (startLine >= 0 && endLine - startLine >= fMinCommentLines) {
+ Position projection = createCommentPosition(alignRegion(commentRange, ctx, true));
+ if (projection != null) {
+ comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(projection.offset, Math.min(16, projection.length)), true), projection));
+ }
+ }
+ startLine = lineNr;
+ endLine = lineNr;
+ commentRange.offset = lineRegion.getOffset();
+ commentRange.length = lineRegion.getLength();
+ } else {
+ endLine = lineNr;
+ int delta = lineRegion.getOffset() + lineRegion.getLength() - commentRange.offset - commentRange.length;
+ commentRange.length += delta;
+ }
+ }
+ }
+ if (startLine >= 0 && endLine - startLine >= fMinCommentLines) {
+ Position projection = createCommentPosition(alignRegion(commentRange, ctx, true));
+ if (projection != null) {
+ comments.add(new Tuple(new CProjectionAnnotation(collapse, doc.get(projection.offset, Math.min(16, projection.length)), true), projection));
+ }
+ }
+ if (!comments.isEmpty()) {
+ // first comment starting before line 10 is considered the header comment
+ Iterator<Tuple> iter = comments.iterator();
+ Tuple tuple = iter.next();
+ int lineNr = doc.getLineOfOffset(tuple.position.getOffset());
+ if (lineNr < 10) {
+ if (ctx.collapseHeaderComments()) {
+ tuple.annotation.markCollapsed();
+ } else {
+ tuple.annotation.markExpanded();
+ }
+ }
+ ctx.addProjectionRange(tuple.annotation, tuple.position);
+ while (iter.hasNext()) {
+ tuple = iter.next();
+ ctx.addProjectionRange(tuple.annotation, tuple.position);
+ }
+ }
+ }
+
+ private void computeFoldingStructure(ICElement[] elements, FoldingStructureComputationContext ctx) throws CModelException {
+ for (ICElement element : elements) {
+ computeFoldingStructure(element, ctx);
+
+ if (element instanceof IParent) {
+ IParent parent= (IParent) element;
+ computeFoldingStructure(parent.getChildren(), ctx);
+ }
+ }
+ }
+
+ /**
+ * Computes the folding structure for a given {@link ICElement C element}. Computed
+ * projection annotations are
+ * {@link RemoteCFoldingStructureProvider.FoldingStructureComputationContext#addProjectionRange(RemoteCFoldingStructureProvider.CProjectionAnnotation, Position) added}
+ * to the computation context.
+ * <p>
+ * Subclasses may extend or replace. The default implementation creates projection annotations
+ * for the following elements:
+ * <ul>
+ * <li>structs, unions, classes</li>
+ * <li>functions</li>
+ * <li>methods</li>
+ * <li>multiline macro definitions</li>
+ * </ul>
+ * </p>
+ *
+ * @param element the C element to compute the folding structure for
+ * @param ctx the computation context
+ */
+ protected void computeFoldingStructure(ICElement element, FoldingStructureComputationContext ctx) {
+
+ boolean collapse= false;
+ switch (element.getElementType()) {
+
+ case ICElement.C_STRUCT:
+ case ICElement.C_CLASS:
+ case ICElement.C_UNION:
+ case ICElement.C_ENUMERATION:
+ case ICElement.C_TEMPLATE_STRUCT:
+ case ICElement.C_TEMPLATE_CLASS:
+ case ICElement.C_TEMPLATE_UNION:
+ collapse= ctx.collapseStructures();
+ break;
+ case ICElement.C_MACRO:
+ collapse= ctx.collapseMacros();
+ break;
+ case ICElement.C_FUNCTION:
+ case ICElement.C_TEMPLATE_FUNCTION:
+ collapse= ctx.collapseFunctions();
+ break;
+ case ICElement.C_METHOD:
+ case ICElement.C_TEMPLATE_METHOD:
+ collapse= ctx.collapseMethods();
+ break;
+ case ICElement.C_NAMESPACE:
+ break;
+ default:
+ return;
+ }
+
+ IRegion[] regions= computeProjectionRanges((ISourceReference) element, ctx);
+ if (regions.length > 0) {
+ IRegion normalized= alignRegion(regions[regions.length - 1], ctx, true);
+ if (normalized != null) {
+ Position position= createElementPosition(normalized, element);
+ if (position != null) {
+ collapse= collapse && !position.includes(fCursorPosition);
+ ctx.addProjectionRange(new CProjectionAnnotation(collapse, element, false), position);
+ }
+ }
+ }
+ }
+
+ /**
+ * Computes the projection ranges for a given <code>ISourceReference</code>. More than one
+ * range or none at all may be returned. If there are no foldable regions, an empty array is
+ * returned.
+ * <p>
+ * The last region in the returned array (if not empty) describes the region for the C
+ * element that implements the source reference. Any preceding regions describe comments
+ * of that element.
+ * </p>
+ *
+ * @param reference a C element that is a source reference
+ * @param ctx the folding context
+ * @return the regions to be folded
+ */
+ protected final IRegion[] computeProjectionRanges(ISourceReference reference, FoldingStructureComputationContext ctx) {
+ try {
+ ISourceRange range= reference.getSourceRange();
+ return new IRegion[] {
+ new Region(range.getStartPos(), range.getLength())
+ };
+ } catch (CModelException e) {
+ }
+
+ return new IRegion[0];
+ }
+
+ /**
+ * Creates a comment folding position from an
+ * {@link #alignRegion(IRegion, RemoteCFoldingStructureProvider.FoldingStructureComputationContext, boolean) aligned}
+ * region.
+ *
+ * @param aligned an aligned region
+ * @return a folding position corresponding to <code>aligned</code>
+ */
+ protected final Position createCommentPosition(IRegion aligned) {
+ if (aligned == null) {
+ return null;
+ }
+ return new CommentPosition(aligned.getOffset(), aligned.getLength());
+ }
+
+ /**
+ * Creates a folding position that remembers its element from an
+ * {@link #alignRegion(IRegion, RemoteCFoldingStructureProvider.FoldingStructureComputationContext, boolean) aligned}
+ * region.
+ *
+ * @param aligned an aligned region
+ * @param element the element to remember
+ * @return a folding position corresponding to <code>aligned</code>
+ */
+ protected final Position createElementPosition(IRegion aligned, ICElement element) {
+ return new CElementPosition(aligned.getOffset(), aligned.getLength(), element);
+ }
+
+ /**
+ * Aligns <code>region</code> to start and end at a line offset. The region's start is
+ * decreased to the next line offset, and the end offset increased to the next line start or the
+ * end of the document. <code>null</code> is returned if <code>region</code> is
+ * <code>null</code> itself or does not comprise at least one line delimiter, as a single line
+ * cannot be folded.
+ *
+ * @param region the region to align, may be <code>null</code>
+ * @param ctx the folding context
+ * @return a region equal or greater than <code>region</code> that is aligned with line
+ * offsets, <code>null</code> if the region is too small to be foldable (e.g. covers
+ * only one line)
+ */
+ protected final IRegion alignRegion(IRegion region, FoldingStructureComputationContext ctx) {
+ return alignRegion(region, ctx, true);
+ }
+
+ /**
+ * Aligns <code>region</code> to start and end at a line offset. The region's start is
+ * decreased to the next line offset, and the end offset increased to the next line start or the
+ * end of the document. <code>null</code> is returned if <code>region</code> is
+ * <code>null</code> itself or does not comprise at least one line delimiter, as a single line
+ * cannot be folded.
+ *
+ * @param region the region to align, may be <code>null</code>
+ * @param ctx the folding context
+ * @param inclusive include line of end offset
+ * @return a region equal or greater than <code>region</code> that is aligned with line
+ * offsets, <code>null</code> if the region is too small to be foldable (e.g. covers
+ * only one line)
+ */
+ protected final IRegion alignRegion(IRegion region, FoldingStructureComputationContext ctx, boolean inclusive) {
+ if (region == null)
+ return null;
+
+ IDocument document= ctx.getDocument();
+
+ try {
+
+ int start= document.getLineOfOffset(region.getOffset());
+ int end= document.getLineOfOffset(region.getOffset() + region.getLength());
+ if (start >= end)
+ return null;
+
+ int offset= document.getLineOffset(start);
+ int endOffset;
+ if (inclusive) {
+ if (document.getNumberOfLines() > end + 1)
+ endOffset= document.getLineOffset(end + 1);
+ else
+ endOffset= document.getLineOffset(end) + document.getLineLength(end);
+ } else {
+ endOffset= document.getLineOffset(end);
+ }
+ return new Region(offset, endOffset - offset);
+
+ } catch (BadLocationException x) {
+ // concurrent modification
+ return null;
+ }
+ }
+
+ private ProjectionAnnotationModel getModel() {
+ return (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
+ }
+
+ private IDocument getDocument() {
+ IDocumentProvider provider= fEditor.getDocumentProvider();
+ return provider.getDocument(fEditor.getEditorInput());
+ }
+
+}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCReconcilingStrategy.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCReconcilingStrategy.java
index 033c8f5..3874bee 100644
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCReconcilingStrategy.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteCReconcilingStrategy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2012 IBM Corporation 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
@@ -22,7 +22,9 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.IRegion;
+import org.eclipse.ptp.internal.rdt.core.model.RemoteModelWorkingCopy;
import org.eclipse.ptp.internal.rdt.core.model.RemoteReconcileWorkingCopyOperation;
+import org.eclipse.ptp.rdt.ui.UIPlugin;
import org.eclipse.ui.texteditor.ITextEditor;
public class RemoteCReconcilingStrategy extends CReconcilingStrategy {
@@ -64,6 +66,7 @@ public class RemoteCReconcilingStrategy extends CReconcilingStrategy {
private void reconcile(final boolean initialReconcile) {
boolean computeAST= fEditor instanceof ICReconcilingListener;
+ RemoteModelWorkingCopy rmWorkingCopy = null;
IWorkingCopy workingCopy = fManager.getWorkingCopy(fEditor.getEditorInput());
if (workingCopy == null) {
return;
@@ -76,13 +79,23 @@ public class RemoteCReconcilingStrategy extends CReconcilingStrategy {
RemoteReconcileWorkingCopyOperation op = new RemoteReconcileWorkingCopyOperation(workingCopy, computeAST, true);
op.runOperation(fProgressMonitor);
- ((ICReconcilingListener)fEditor).reconciled(null, true, fProgressMonitor);
+ rmWorkingCopy = op.fRmWorkingCopy;
}
} catch (OperationCanceledException oce) {
// document was modified while parsing
} catch (CModelException e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$
- CUIPlugin.log(status);
- }
+ UIPlugin.log(status);
+ } finally {
+ try {
+ synchronized (rmWorkingCopy) {
+ ((ICReconcilingListener)fEditor).reconciled(null, true, fProgressMonitor);
+ }
+ } catch(Exception e) {
+ IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$
+ UIPlugin.log(status);
+ }
+ }
+
}
}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingManager.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingManager.java
new file mode 100644
index 0000000..6bac026
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingManager.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems) - Adapted for CDT
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.ui.editor;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ptp.internal.rdt.editor.RemoteCEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.cdt.ui.text.ICPartitions;
+import org.eclipse.cdt.ui.text.IColorManager;
+import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlighting;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingPresenter;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings;
+import org.eclipse.cdt.internal.ui.text.CPresentationReconciler;
+import org.eclipse.cdt.internal.ui.text.CSourceViewerScalableConfiguration;
+
+/**
+ * Semantic highlighting manager.
+ * Cloned from JDT.
+ *
+ * @since 4.0
+ */
+public class RemoteSemanticHighlightingManager extends SemanticHighlightingManager {
+
+ /** Remote Semantic highlighting reconciler */
+ private RemoteSemanticHighlightingReconciler fRemoteReconciler;
+ /** The editor */
+ private RemoteCEditor remoteCEditor;
+
+ /**
+ * Install the semantic highlighting on the given editor infrastructure
+ *
+ * @param editor The remote C editor
+ * @param sourceViewer The source viewer
+ * @param colorManager The color manager
+ * @param preferenceStore The preference store
+ */
+ public void install(RemoteCEditor editor, CSourceViewer sourceViewer, IColorManager colorManager, IPreferenceStore preferenceStore) {
+ remoteCEditor= editor;
+ fSourceViewer= sourceViewer;
+ fColorManager= colorManager;
+ fPreferenceStore= preferenceStore;
+ if (remoteCEditor != null) {
+ fConfiguration= new CSourceViewerScalableConfiguration(colorManager, preferenceStore, editor, ICPartitions.C_PARTITIONING);
+ fPresentationReconciler= (CPresentationReconciler) fConfiguration.getPresentationReconciler(sourceViewer);
+ } else {
+ fConfiguration= null;
+ fPresentationReconciler= null;
+ }
+
+ fPreferenceStore.addPropertyChangeListener(this);
+
+ if (isEnabled())
+ enable();
+ }
+
+ /**
+ * Install the semantic highlighting on the given source viewer infrastructure. No reconciliation will be performed.
+ *
+ * @param sourceViewer the source viewer
+ * @param colorManager the color manager
+ * @param preferenceStore the preference store
+ * @param hardcodedRanges the hard-coded ranges to be highlighted
+ */
+ public void install(CSourceViewer sourceViewer, IColorManager colorManager, IPreferenceStore preferenceStore, HighlightedRange[][] hardcodedRanges) {
+ fHardcodedRanges= hardcodedRanges;
+ install(null, sourceViewer, colorManager, preferenceStore);
+ }
+
+ /**
+ * Enable semantic highlighting.
+ */
+ protected void enable() {
+ initializeHighlightings();
+
+ fPresenter= new SemanticHighlightingPresenter();
+ fPresenter.install(fSourceViewer, fPresentationReconciler);
+
+ if (remoteCEditor != null) {
+ fRemoteReconciler= new RemoteSemanticHighlightingReconciler();
+ fRemoteReconciler.install(remoteCEditor, fSourceViewer, fPresenter, fSemanticHighlightings, fHighlightings);
+ } else {
+ fPresenter.updatePresentation(null, createHardcodedPositions(), new HighlightedPosition[0]);
+ }
+ }
+
+ /**
+ * Uninstall the semantic highlighting
+ */
+ public void uninstall() {
+ disable();
+
+ if (fPreferenceStore != null) {
+ fPreferenceStore.removePropertyChangeListener(this);
+ fPreferenceStore= null;
+ }
+
+ remoteCEditor= null;
+ fSourceViewer= null;
+ fColorManager= null;
+ fConfiguration= null;
+ fPresentationReconciler= null;
+ fHardcodedRanges= null;
+ }
+
+ /**
+ * Disable semantic highlighting.
+ */
+ protected void disable() {
+ if (fRemoteReconciler != null) {
+ fRemoteReconciler.uninstall();
+ fRemoteReconciler= null;
+ }
+
+ if (fPresenter != null) {
+ fPresenter.uninstall();
+ fPresenter= null;
+ }
+
+ if (fSemanticHighlightings != null)
+ disposeHighlightings();
+ }
+
+
+ /*
+ * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ handlePropertyChangeEvent(event);
+ }
+
+ /**
+ * Handle the given property change event
+ *
+ * @param event The event
+ */
+ protected boolean handlePropertyChangeEvent(PropertyChangeEvent event) {
+ if (fPreferenceStore == null)
+ return false; // Uninstalled during event notification
+
+ if (fConfiguration != null)
+ fConfiguration.handlePropertyChangeEvent(event);
+
+ if (SemanticHighlightings.affectsEnablement(fPreferenceStore, event)) {
+ if (isEnabled())
+ enable();
+ else
+ disable();
+ }
+
+ if (!isEnabled())
+ return false;
+
+ boolean refreshNeeded= false;
+
+ for (int i= 0, n= fSemanticHighlightings.length; i < n; i++) {
+ SemanticHighlighting semanticHighlighting= fSemanticHighlightings[i];
+
+ String colorKey= SemanticHighlightings.getColorPreferenceKey(semanticHighlighting);
+ if (colorKey.equals(event.getProperty())) {
+ adaptToTextForegroundChange(fHighlightings[i], event);
+ fPresenter.highlightingStyleChanged(fHighlightings[i]);
+ refreshNeeded= true;
+ continue;
+ }
+
+ String boldKey= SemanticHighlightings.getBoldPreferenceKey(semanticHighlighting);
+ if (boldKey.equals(event.getProperty())) {
+ adaptToTextStyleChange(fHighlightings[i], event, SWT.BOLD);
+ fPresenter.highlightingStyleChanged(fHighlightings[i]);
+ refreshNeeded= true;
+ continue;
+ }
+
+ String italicKey= SemanticHighlightings.getItalicPreferenceKey(semanticHighlighting);
+ if (italicKey.equals(event.getProperty())) {
+ adaptToTextStyleChange(fHighlightings[i], event, SWT.ITALIC);
+ fPresenter.highlightingStyleChanged(fHighlightings[i]);
+ refreshNeeded= true;
+ continue;
+ }
+
+ String strikethroughKey= SemanticHighlightings.getStrikethroughPreferenceKey(semanticHighlighting);
+ if (strikethroughKey.equals(event.getProperty())) {
+ adaptToTextStyleChange(fHighlightings[i], event, TextAttribute.STRIKETHROUGH);
+ fPresenter.highlightingStyleChanged(fHighlightings[i]);
+ refreshNeeded= true;
+ continue;
+ }
+
+ String underlineKey= SemanticHighlightings.getUnderlinePreferenceKey(semanticHighlighting);
+ if (underlineKey.equals(event.getProperty())) {
+ adaptToTextStyleChange(fHighlightings[i], event, TextAttribute.UNDERLINE);
+ fPresenter.highlightingStyleChanged(fHighlightings[i]);
+ refreshNeeded= true;
+ continue;
+ }
+
+ String enabledKey= SemanticHighlightings.getEnabledPreferenceKey(semanticHighlighting);
+ if (enabledKey.equals(event.getProperty())) {
+ adaptToEnablementChange(fHighlightings[i], event);
+ fPresenter.highlightingStyleChanged(fHighlightings[i]);
+ refreshNeeded= true;
+ continue;
+ }
+ }
+
+ if (refreshNeeded && fRemoteReconciler != null)
+ fRemoteReconciler.refresh();
+
+ return refreshNeeded;
+ }
+
+ /**
+ * Force refresh of highlighting.
+ */
+ public void refresh() {
+ if (fRemoteReconciler != null) {
+ fRemoteReconciler.refresh();
+ }
+ }
+} \ No newline at end of file
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingReconciler.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingReconciler.java
new file mode 100644
index 0000000..a1a50b8
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingReconciler.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ptp.internal.rdt.ui.editor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.internal.core.model.ASTCache;
+import org.eclipse.cdt.internal.ui.editor.ASTProvider;
+import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlighting;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingPresenter;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingReconciler;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightedPosition;
+import org.eclipse.ptp.internal.rdt.editor.RemoteCEditor;
+import org.eclipse.ptp.internal.rdt.ui.editor.RemoteSemanticHighlightingManager;
+import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightingStyle;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.IWorkingCopyManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ptp.rdt.core.services.IRDTServiceConstants;
+import org.eclipse.ptp.rdt.ui.serviceproviders.IIndexServiceProvider2;
+import org.eclipse.ptp.services.core.IService;
+import org.eclipse.ptp.services.core.IServiceConfiguration;
+import org.eclipse.ptp.services.core.IServiceModelManager;
+import org.eclipse.ptp.services.core.IServiceProvider;
+import org.eclipse.ptp.services.core.ServiceModelManager;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPartSite;
+
+
+/**
+ * Remote Semantic highlighting reconciler
+ */
+
+public class RemoteSemanticHighlightingReconciler extends SemanticHighlightingReconciler {
+
+ /** Reconcile operation lock. */
+ private final Object fReconcileLock= new Object();
+
+ private boolean fIsReconciling= false;
+
+ /** Highlightings */
+ protected RemoteSemanticHighlightingManager.HighlightingStyle[] fHighlightings;
+
+ /** Highlightings - cache for background thread, only valid during {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)} */
+ protected RemoteSemanticHighlightingManager.HighlightingStyle[] fJobHighlightings;
+
+ /** The Remote C editor this semantic highlighting reconciler is installed on */
+ private RemoteCEditor fRemoteEditor;
+
+ /** Background job */
+ private Job fJob;
+ /** Background job lock */
+ private final Object fJobLock= new Object();
+
+
+ /**
+ * @param positions are separated by commas. Element x = the offset,
+ * x+1 = the length, x+2 is the Highlightings index.
+ */
+ private void parsePositions(String positions) {
+ String [] positionList = positions.split(","); //$NON-NLS-1$
+
+ for(int i=0; i < positionList.length; i+=3) {
+ int lgtIndex = Integer.parseInt(positionList[i+2]);
+ if (fJobHighlightings[lgtIndex].isEnabled()){
+ int offset = Integer.parseInt(positionList[i]);
+ int length = Integer.parseInt(positionList[i+1]);
+ addPosition(offset, length, fJobHighlightings[lgtIndex]);
+ }
+ }
+ sortPositions();
+ }
+
+ /**
+ * Add a position with the given range and highlighting iff it does not exist already.
+ *
+ * @param offset The range offset
+ * @param length The range length
+ * @param highlighting The highlighting
+ */
+ private void addPosition(int offset, int length, HighlightingStyle highlighting) {
+ boolean isExisting= false;
+ // TODO: use binary search
+ for (int i= 0, n= fRemovedPositions.size(); i < n; i++) {
+ HighlightedPosition position= fRemovedPositions.get(i);
+ if (position == null)
+ continue;
+ if (position.isEqual(offset, length, highlighting)) {
+ isExisting= true;
+ fRemovedPositions.set(i, null);
+ fNOfRemovedPositions--;
+ break;
+ }
+ }
+
+ if (!isExisting) {
+ HighlightedPosition position= fJobPresenter.createHighlightedPosition(offset, length, highlighting);
+ fAddedPositions.add(position);
+ }
+ }
+
+ private IRemoteSemanticHighlightingService getSemanticHighlightingService(IProject project) {
+ IServiceModelManager smm = ServiceModelManager.getInstance();
+ IServiceConfiguration serviceConfig = smm.getActiveConfiguration(project);
+ IService indexingService = smm.getService(IRDTServiceConstants.SERVICE_C_INDEX);
+ IServiceProvider serviceProvider = serviceConfig.getServiceProvider(indexingService);
+ if (!(serviceProvider instanceof IIndexServiceProvider2)) {
+ return null;
+ }
+ IRemoteSemanticHighlightingService service = ((IIndexServiceProvider2) serviceProvider).getRemoteSemanticHighlightingService();
+ return service;
+ }
+
+
+ public void reconciled(IASTTranslationUnit ast, boolean force, IProgressMonitor progressMonitor) {
+ // ensure at most one thread can be reconciling at any time
+ synchronized (fReconcileLock) {
+ if (fIsReconciling)
+ return;
+ fIsReconciling= true;
+ }
+
+ TextPresentation textPresentation= null;
+ boolean updatePresentation = false;
+
+ fJobPresenter= fPresenter;
+ fJobSemanticHighlightings= fSemanticHighlightings;
+ fJobHighlightings= fHighlightings;
+
+ try {
+ if (fJobPresenter == null || fJobSemanticHighlightings == null || fJobHighlightings == null)
+ return;
+
+ IWorkingCopyManager fManager= CUIPlugin.getDefault().getWorkingCopyManager();
+ IWorkingCopy workingCopy= fManager.getWorkingCopy(fRemoteEditor.getEditorInput());
+
+ if (workingCopy == null) {
+ return;
+ }
+
+ fJobPresenter.setCanceled(progressMonitor != null && progressMonitor.isCanceled());
+
+ startReconcilingPositions();
+
+ if (!fJobPresenter.isCanceled()) {
+ IProject project = ((RemoteCEditor) fRemoteEditor).getInputCElement().getCProject().getProject();
+ IRemoteSemanticHighlightingService rsgs = getSemanticHighlightingService(project);
+
+ /*
+ * Send the working copy to the server. It will return the found positions in a comma
+ * separated list.
+ */
+ String foundPositions = rsgs.computeSemanticHighlightingPositions(workingCopy);
+ if (foundPositions != null && foundPositions.compareTo("") != 0) { //$NON-NLS-1$
+ parsePositions(foundPositions);
+ updatePresentation = true;
+ }
+ }
+
+ if (!fJobPresenter.isCanceled() && updatePresentation) {
+ //Update the presentation just as is done with the local C Editor
+ textPresentation= fJobPresenter.createPresentation(fAddedPositions, fRemovedPositions);
+ updatePresentation(textPresentation, fAddedPositions, fRemovedPositions);
+ }
+ stopReconcilingPositions();
+
+ } finally {
+ fJobPresenter= null;
+ fJobSemanticHighlightings= null;
+ fJobHighlightings= null;
+ synchronized (fReconcileLock) {
+ fIsReconciling= false;
+ }
+ }
+ }
+
+ private void sortPositions() {
+ List<HighlightedPosition> oldPositions= fRemovedPositions;
+ List<HighlightedPosition> newPositions= new ArrayList<HighlightedPosition>(fNOfRemovedPositions);
+ for (int i= 0, n= oldPositions.size(); i < n; i ++) {
+ HighlightedPosition current= oldPositions.get(i);
+ if (current != null)
+ newPositions.add(current);
+ }
+ fRemovedPositions= newPositions;
+ // positions need to be sorted by ascending offset
+ Collections.sort(fAddedPositions, new Comparator<Position>() {
+ public int compare(final Position p1, final Position p2) {
+ return p1.getOffset() - p2.getOffset();
+ }});
+ }
+
+
+ /**
+ * Update the presentation.
+ *
+ * @param textPresentation the text presentation
+ * @param addedPositions the added positions
+ * @param removedPositions the removed positions
+ */
+ protected void updatePresentation(TextPresentation textPresentation, List<HighlightedPosition> addedPositions, List<HighlightedPosition> removedPositions) {
+ Runnable runnable= fJobPresenter.createUpdateRunnable(textPresentation, addedPositions, removedPositions);
+ if (runnable == null)
+ return;
+
+ RemoteCEditor editor= fRemoteEditor;
+
+ if (editor == null)
+ return;
+
+ IWorkbenchPartSite site= editor.getSite();
+ if (site == null)
+ return;
+
+ Shell shell= site.getShell();
+ if (shell == null || shell.isDisposed())
+ return;
+
+ Display display= shell.getDisplay();
+ if (display == null || display.isDisposed())
+ return;
+
+ display.asyncExec(runnable);
+ }
+
+ /**
+ * Install this reconciler on the given editor, presenter and highlightings.
+ * @param editor the editor
+ * @param sourceViewer the source viewer
+ * @param fPresenter2 the semantic highlighting presenter
+ * @param semanticHighlightings the semantic highlightings
+ * @param highlightings the highlightings
+ */
+ public void install(RemoteCEditor editor, ISourceViewer sourceViewer, SemanticHighlightingPresenter fPresenter2, SemanticHighlighting[] semanticHighlightings, RemoteSemanticHighlightingManager.HighlightingStyle[] highlightings) {
+ fPresenter= fPresenter2;
+ fSemanticHighlightings= semanticHighlightings;
+ fHighlightings= highlightings;
+
+ fRemoteEditor= editor;
+
+ if (fRemoteEditor != null) {
+ fRemoteEditor.addReconcileListener(this);
+ }
+ }
+
+ /**
+ * Uninstall this reconciler from the editor
+ */
+ public void uninstall() {
+ if (fPresenter != null)
+ fPresenter.setCanceled(true);
+
+ if (fRemoteEditor != null) {
+ fRemoteEditor.removeReconcileListener(this);
+ fRemoteEditor= null;
+ }
+
+ fSemanticHighlightings= null;
+ fHighlightings= null;
+ fPresenter= null;
+ }
+
+ /**
+ * Refreshes the highlighting.
+ */
+ public void refresh() {
+ reconciled(null, true, new NullProgressMonitor());
+ }
+
+}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingService.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingService.java
new file mode 100644
index 0000000..89ce164
--- /dev/null
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/editor/RemoteSemanticHighlightingService.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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:
+ * IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ptp.internal.rdt.ui.editor;
+
+import java.util.Map;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.ptp.internal.rdt.core.RemoteIndexerInfoProviderFactory;
+import org.eclipse.ptp.internal.rdt.core.model.ModelAdapter;
+import org.eclipse.ptp.internal.rdt.core.model.TranslationUnit;
+import org.eclipse.ptp.internal.rdt.core.serviceproviders.AbstractRemoteService;
+import org.eclipse.ptp.internal.rdt.core.subsystems.ICIndexSubsystem;
+import org.eclipse.ptp.rdt.core.RDTLog;
+import org.eclipse.rse.core.subsystems.IConnectorService;
+
+/**
+ * A service for computing semantic highlighting on a remote host.
+ */
+public class RemoteSemanticHighlightingService extends AbstractRemoteService implements IRemoteSemanticHighlightingService {
+
+ public RemoteSemanticHighlightingService(IConnectorService connectorService) {
+ super(connectorService);
+ }
+
+ public RemoteSemanticHighlightingService(ICIndexSubsystem subsystem) {
+ super(subsystem);
+ }
+
+ public String computeSemanticHighlightingPositions(IWorkingCopy workingCopy) {
+ ICIndexSubsystem subsystem = getSubSystem();
+ if(subsystem == null) {
+ return null;
+ }
+ ITranslationUnit unit = workingCopy.getTranslationUnit();
+
+ ITranslationUnit targetUnit;
+ try {
+ targetUnit = ModelAdapter.adaptElement(null, unit, 0, true);
+ } catch (CModelException e1) {
+ RDTLog.logError(e1);
+ return null;
+ } catch (Exception e) {
+ RDTLog.logError(e);
+ return null;
+ }
+
+ // TODO: This can potentially take a while. But we need
+ // to trigger scope initialization in case it hasn't
+ // been done for the project.
+ IProject project = unit.getCProject().getProject();
+ IProgressMonitor monitor = new NullProgressMonitor();
+ subsystem.checkProject(project, monitor);
+
+ if(targetUnit instanceof TranslationUnit) {
+ IScannerInfo scannerInfo = RemoteIndexerInfoProviderFactory.getScannerInfo(unit.getResource());
+ Map<String,String> langaugeProperties = null;
+ try {
+ String languageId = unit.getLanguage().getId();
+ langaugeProperties = RemoteIndexerInfoProviderFactory.getLanguageProperties(languageId, project);
+ } catch(Exception e) {
+ RDTLog.logError(e);
+ }
+ ((TranslationUnit)targetUnit).setASTContext(scannerInfo, langaugeProperties);
+ }
+
+ return subsystem.computeHighlightPositions(targetUnit);
+ }
+} \ No newline at end of file
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/IIndexServiceProvider2.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/IIndexServiceProvider2.java
index 4e56ee6..638e8ab 100755
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/IIndexServiceProvider2.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/IIndexServiceProvider2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation 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
@@ -11,6 +11,8 @@
package org.eclipse.ptp.rdt.ui.serviceproviders;
import org.eclipse.ptp.internal.rdt.ui.contentassist.IContentAssistService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteSemanticHighlightingService;
import org.eclipse.ptp.internal.rdt.ui.navigation.INavigationService;
import org.eclipse.ptp.internal.rdt.ui.search.ISearchService;
import org.eclipse.ptp.rdt.core.serviceproviders.IIndexServiceProvider;
@@ -32,4 +34,14 @@ public interface IIndexServiceProvider2 extends IIndexServiceProvider {
* @since 4.1
*/
public INavigationService getNavigationService();
+
+ /**
+ * @since 4.1
+ */
+ public IRemoteSemanticHighlightingService getRemoteSemanticHighlightingService();
+
+ /**
+ * @since 4.1
+ */
+ public IRemoteCCodeFoldingService getRemoteCodeFoldingService();
}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/LocalCIndexServiceProvider.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/LocalCIndexServiceProvider.java
index 4b3dabd..b4705c9 100644
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/LocalCIndexServiceProvider.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/LocalCIndexServiceProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 IBM Corporation and others.
+ * Copyright (c) 2011, 2012 IBM Corporation 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,6 +14,10 @@ package org.eclipse.ptp.rdt.ui.serviceproviders;
import org.eclipse.ptp.internal.rdt.core.serviceproviders.AbstractLocalCIndexServiceProvider;
import org.eclipse.ptp.internal.rdt.ui.contentassist.IContentAssistService;
import org.eclipse.ptp.internal.rdt.ui.contentassist.LocalContentAssistService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteSemanticHighlightingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.RemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.RemoteSemanticHighlightingService;
import org.eclipse.ptp.internal.rdt.ui.navigation.INavigationService;
import org.eclipse.ptp.internal.rdt.ui.navigation.LocalNavigationService;
import org.eclipse.ptp.internal.rdt.ui.search.ISearchService;
@@ -30,6 +34,8 @@ public class LocalCIndexServiceProvider extends AbstractLocalCIndexServiceProvid
private ISearchService fSearchService;
private IContentAssistService fContentAssistService;
private INavigationService fNavigationService;
+ private IRemoteSemanticHighlightingService fRemoteSemanticHighlightingService;
+ private IRemoteCCodeFoldingService fRemoteCCodeFoldingService;
public boolean isRemote() {
return false;
@@ -53,4 +59,23 @@ public class LocalCIndexServiceProvider extends AbstractLocalCIndexServiceProvid
return fContentAssistService;
}
+ public IRemoteSemanticHighlightingService getRemoteSemanticHighlightingService() {
+ if(!isConfigured())
+ return null;
+
+ if(fRemoteSemanticHighlightingService== null)
+ fRemoteSemanticHighlightingService = new RemoteSemanticHighlightingService(fConnectorService);
+
+ return fRemoteSemanticHighlightingService;
+ }
+
+ public IRemoteCCodeFoldingService getRemoteCodeFoldingService() {
+ if(!isConfigured())
+ return null;
+
+ if(fRemoteCCodeFoldingService== null)
+ fRemoteCCodeFoldingService = new RemoteCCodeFoldingService(fConnectorService);
+
+ return fRemoteCCodeFoldingService;
+ }
}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/NullCIndexServiceProvider.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/NullCIndexServiceProvider.java
index df523cf..eff416f 100644
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/NullCIndexServiceProvider.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/NullCIndexServiceProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation 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
@@ -37,11 +37,14 @@ import org.eclipse.ptp.internal.rdt.core.index.IIndexLifecycleService;
import org.eclipse.ptp.internal.rdt.core.index.RemoteIndexerTask;
import org.eclipse.ptp.internal.rdt.core.index.IRemoteFastIndexerUpdateEvent.EventType;
import org.eclipse.ptp.internal.rdt.core.model.Scope;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
import org.eclipse.ptp.internal.rdt.core.navigation.OpenDeclarationResult;
import org.eclipse.ptp.internal.rdt.core.serviceproviders.AbstractRemoteCIndexServiceProvider;
import org.eclipse.ptp.internal.rdt.core.typehierarchy.ITypeHierarchyService;
import org.eclipse.ptp.internal.rdt.core.typehierarchy.THGraph;
import org.eclipse.ptp.internal.rdt.ui.contentassist.IContentAssistService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteSemanticHighlightingService;
import org.eclipse.ptp.internal.rdt.ui.navigation.INavigationService;
import org.eclipse.ptp.internal.rdt.ui.search.ISearchService;
import org.eclipse.ptp.rdt.ui.messages.Messages;
@@ -315,4 +318,20 @@ public class NullCIndexServiceProvider extends
return Messages.getString("NullServiceProvider.config"); //$NON-NLS-1$
}
+ public IRemoteSemanticHighlightingService getRemoteSemanticHighlightingService() {
+ return new IRemoteSemanticHighlightingService() {
+ public String computeSemanticHighlightingPositions(
+ IWorkingCopy workingCopy) {
+ return null;
+ }
+ };
+ }
+
+ public IRemoteCCodeFoldingService getRemoteCodeFoldingService() {
+ return new IRemoteCCodeFoldingService() {
+ public FoldingRegionsResult computeCodeFoldingRegions(IWorkingCopy workingCopy, int docLength, boolean fPreprocessorBranchFoldingEnabled, boolean fStatementsFoldingEnabled) {
+ return null;
+ }
+ };
+ }
}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/RSECIndexServiceProvider.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/RSECIndexServiceProvider.java
index 3600774..7ff4ca5 100755
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/RSECIndexServiceProvider.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/serviceproviders/RSECIndexServiceProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation 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
@@ -13,6 +13,10 @@ package org.eclipse.ptp.rdt.ui.serviceproviders;
import org.eclipse.ptp.internal.rdt.core.serviceproviders.AbstractRemoteCIndexServiceProvider;
import org.eclipse.ptp.internal.rdt.ui.contentassist.IContentAssistService;
import org.eclipse.ptp.internal.rdt.ui.contentassist.RemoteContentAssistService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.IRemoteSemanticHighlightingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.RemoteCCodeFoldingService;
+import org.eclipse.ptp.internal.rdt.ui.editor.RemoteSemanticHighlightingService;
import org.eclipse.ptp.internal.rdt.ui.navigation.INavigationService;
import org.eclipse.ptp.internal.rdt.ui.navigation.RemoteNavigationService;
import org.eclipse.ptp.internal.rdt.ui.search.ISearchService;
@@ -42,6 +46,8 @@ public class RSECIndexServiceProvider extends AbstractRemoteCIndexServiceProvide
private RemoteSearchService fSearchService;
private IContentAssistService fContentAssistService;
private INavigationService fNavigationService;
+ private IRemoteSemanticHighlightingService fRemoteSemanticHighlightingService;
+ private IRemoteCCodeFoldingService fRemoteCCodeFoldingService;
/**
* @since 4.1
@@ -135,4 +141,24 @@ public class RSECIndexServiceProvider extends AbstractRemoteCIndexServiceProvide
public String toString() {
return "RSECIndexServiceProvider(" + getHostName() + "," + getIndexLocation() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
+
+ public synchronized IRemoteSemanticHighlightingService getRemoteSemanticHighlightingService() {
+ if(!isConfigured())
+ return null;
+
+ if(fRemoteSemanticHighlightingService== null)
+ fRemoteSemanticHighlightingService = new RemoteSemanticHighlightingService(fConnectorService);
+
+ return fRemoteSemanticHighlightingService;
+ }
+
+ public IRemoteCCodeFoldingService getRemoteCodeFoldingService() {
+ if(!isConfigured())
+ return null;
+
+ if(fRemoteCCodeFoldingService== null)
+ fRemoteCCodeFoldingService = new RemoteCCodeFoldingService(fConnectorService);
+
+ return fRemoteCCodeFoldingService;
+ }
}
diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/subsystems/RSECIndexSubsystem.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/subsystems/RSECIndexSubsystem.java
index 56ece19..63a00eb 100755
--- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/subsystems/RSECIndexSubsystem.java
+++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/subsystems/RSECIndexSubsystem.java
@@ -64,6 +64,7 @@ import org.eclipse.ptp.internal.rdt.core.index.RemoteIndexerTask;
import org.eclipse.ptp.internal.rdt.core.index.IRemoteFastIndexerUpdateEvent.EventType;
import org.eclipse.ptp.internal.rdt.core.miners.CDTMiner;
import org.eclipse.ptp.internal.rdt.core.model.Scope;
+import org.eclipse.ptp.internal.rdt.core.navigation.FoldingRegionsResult;
import org.eclipse.ptp.internal.rdt.core.navigation.OpenDeclarationResult;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchMatch;
import org.eclipse.ptp.internal.rdt.core.search.RemoteSearchQuery;
@@ -844,6 +845,106 @@ public class RSECIndexSubsystem extends SubSystem implements ICIndexSubsystem {
}
return (RemoteSearchQuery) result;
}
+
+ /**
+ * @since 4.1
+ */
+ @SuppressWarnings("unchecked")
+ public String computeHighlightPositions(ITranslationUnit targetUnit) {
+ // If something goes wrong, return an empty string.
+
+ checkAllProjects(new NullProgressMonitor());
+ DataStore dataStore = getDataStore(null);
+ if (dataStore == null) {
+ return ""; //$NON-NLS-1$
+ }
+ DataElement queryCmd = dataStore.localDescriptorQuery(dataStore.getDescriptorRoot(), CDTMiner.C_SEMANTIC_HIGHTLIGHTING_COMPUTE_POSITIONS);
+ if (queryCmd == null) {
+ return ""; //$NON-NLS-1$
+ }
+ NullProgressMonitor monitor = new NullProgressMonitor();
+ StatusMonitor smonitor = StatusMonitorFactory.getInstance().getStatusMonitorFor(getConnectorService(), dataStore);
+ ArrayList<Object> args = new ArrayList<Object>();
+ Scope scope = new Scope(targetUnit.getCProject().getProject());
+ DataElement dataElement = dataStore.createObject(null, CDTMiner.T_SCOPE_SCOPENAME_DESCRIPTOR, scope.getName());
+
+ args.add(dataElement);
+ args.add(createSerializableElement(dataStore, targetUnit));
+
+ // execute the command
+ DataElement status = dataStore.command(queryCmd, args, dataStore.getDescriptorRoot());
+
+ try {
+ smonitor.waitForUpdate(status, monitor);
+ }
+ catch (Exception e) {
+ RDTLog.logError(e);
+ }
+
+ DataElement element = status.get(0);
+ String data = element.getName();
+ try {
+ Object result = Serializer.deserialize(data);
+ if (result == null || !(result instanceof String)) {
+ return ""; //$NON-NLS-1$;
+ }
+ return (String) result;
+ } catch (IOException e) {
+ RDTLog.logError(e);
+ } catch (ClassNotFoundException e) {
+ RDTLog.logError(e);
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ public FoldingRegionsResult computeFoldingRegions(ITranslationUnit targetUnit, int docLength, boolean fPreprocessorBranchFoldingEnabled, boolean fStatementsFoldingEnabled) {
+ checkAllProjects(new NullProgressMonitor());
+ DataStore dataStore = getDataStore(null);
+ if (dataStore == null) {
+ return null;
+ }
+ DataElement queryCmd = dataStore.localDescriptorQuery(dataStore.getDescriptorRoot(), CDTMiner.C_CODE_FOLDING_COMPUTE_REGIONS);
+ if (queryCmd == null) {
+ return null;
+ }
+ NullProgressMonitor monitor = new NullProgressMonitor();
+ StatusMonitor smonitor = StatusMonitorFactory.getInstance().getStatusMonitorFor(getConnectorService(), dataStore);
+ ArrayList<Object> args = new ArrayList<Object>();
+ Scope scope = new Scope(targetUnit.getCProject().getProject());
+ DataElement dataElement = dataStore.createObject(null, CDTMiner.T_SCOPE_SCOPENAME_DESCRIPTOR, scope.getName());
+
+ args.add(dataElement);
+ args.add(createSerializableElement(dataStore, targetUnit));
+ args.add(dataStore.createObject(null, CDTMiner.T_INDEX_INT_DESCRIPTOR, Integer.toString(docLength)));
+ args.add(dataStore.createObject(null, CDTMiner.T_INDEX_BOOLEAN_DESCRIPTOR, Boolean.toString(fPreprocessorBranchFoldingEnabled)));
+ args.add(dataStore.createObject(null, CDTMiner.T_INDEX_BOOLEAN_DESCRIPTOR, Boolean.toString(fStatementsFoldingEnabled)));
+
+ // execute the command
+ DataElement status = dataStore.command(queryCmd, args, dataStore.getDescriptorRoot());
+
+ try {
+ smonitor.waitForUpdate(status, monitor);
+ }
+ catch (Exception e) {
+ RDTLog.logError(e);
+ }
+
+ DataElement element = status.get(0);
+
+ String data = element.getName();
+ try {
+ Object result = Serializer.deserialize(data);
+ if (result == null || !(result instanceof FoldingRegionsResult)) {
+ return null;
+ }
+ return (FoldingRegionsResult) result;
+ } catch (IOException e) {
+ RDTLog.logError(e);
+ } catch (ClassNotFoundException e) {
+ RDTLog.logError(e);
+ }
+ return null;
+ }
@SuppressWarnings("unchecked")
public List<Proposal> computeCompletionProposals(Scope scope, RemoteContentAssistInvocationContext context, ITranslationUnit unit) {