From b2561fc60dbe74e8c332025b61cae104f5ccfc66 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Fri, 15 Dec 2017 12:57:37 +0200 Subject: [PATCH] Find SCL references in SCLModuleEditor with Ctrl+Shift+G refs #7683 Change-Id: I553e61518a16f2b711b82f41576e07b3f99df1ba --- .../scl/SCL/CallHierarchy.scl | 4 +- .../contexts/TranslationContext.java | 4 +- .../module/debug/SymbolReference.java | 4 +- .../org.simantics.scl.ui/META-INF/MANIFEST.MF | 3 +- bundles/org.simantics.scl.ui/plugin.xml | 22 ++ .../scl/ui/editor2/FindSCLSearchAction.java | 121 +++++++ .../scl/ui/search/SCLSearchQuery.java | 91 +++++ .../scl/ui/search/SCLSearchResult.java | 78 +++++ .../scl/ui/search/SCLSearchResultPage.java | 323 ++++++++++++++++++ .../org.simantics.scl.feature/feature.xml | 7 - .../build.properties | 1 + .../org.simantics.scl.ui.feature/feature.xml | 65 ++++ .../org.simantics.sdk.feature/feature.xml | 4 + features/pom.xml | 1 + 14 files changed, 714 insertions(+), 14 deletions(-) create mode 100644 bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/FindSCLSearchAction.java create mode 100644 bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchQuery.java create mode 100644 bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResult.java create mode 100644 bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResultPage.java create mode 100644 features/org.simantics.scl.ui.feature/build.properties create mode 100644 features/org.simantics.scl.ui.feature/feature.xml diff --git a/bundles/org.simantics.scl.compiler/scl/SCL/CallHierarchy.scl b/bundles/org.simantics.scl.compiler/scl/SCL/CallHierarchy.scl index 5ab8e8141..4e823970e 100644 --- a/bundles/org.simantics.scl.compiler/scl/SCL/CallHierarchy.scl +++ b/bundles/org.simantics.scl.compiler/scl/SCL/CallHierarchy.scl @@ -9,7 +9,7 @@ import "SCL/Reflection" data SymbolReference = @JavaType "org.simantics.scl.compiler.module.debug.SymbolReference" @FieldNames [referred, referrer, referenceLocation] - SymbolReference {referred :: Name, referrer :: String, referenceLocation :: Location} + SymbolReference {referred :: Name, referrer :: Name, referenceLocation :: Location} importJava "org.simantics.scl.compiler.module.debug.ModuleDebugInfo" where data ModuleDebugInfo @@ -23,7 +23,7 @@ importJava "org.simantics.scl.compiler.module.Module" where whoCalls :: String -> String -> [(String, String, Long)] whoCalls moduleName valueName = - [ (callerModuleName, referrer, referenceLocation) + [ (callerModuleName, nameOfName referrer, referenceLocation) | callerModuleName <- sclModuleNames , Just callerModule = moduleByName callerModuleName , Just debugInfo = debugInfo callerModule diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java index b71c0ad27..0e7df755c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java @@ -201,7 +201,7 @@ public class TranslationContext extends TypeTranslationContext implements Enviro if(deprecatedDescription != null) errorLog.logWarning(location, "Deprecated value " + value.getName().name + "." + (deprecatedDescription.isEmpty() ? "" : " " + deprecatedDescription)); if(moduleDebugInfo != null) - moduleDebugInfo.symbolReferences.add(new SymbolReference(value.getName(), definitionName, location)); + moduleDebugInfo.symbolReferences.add(new SymbolReference(value.getName(), Name.create(compilationContext.module.getName(), definitionName), location)); return new EConstant(location, value); } catch (AmbiguousNameException e) { if(SCLCompilerConfiguration.ALLOW_OVERLOADING) @@ -229,7 +229,7 @@ public class TranslationContext extends TypeTranslationContext implements Enviro EConstant expression = new EConstant(altValue); expression.location = location; if(moduleDebugInfo != null) - moduleDebugInfo.symbolReferences.add(new SymbolReference(altValue.getName(), definitionName, location)); + moduleDebugInfo.symbolReferences.add(new SymbolReference(altValue.getName(), Name.create(compilationContext.module.getName(), definitionName), location)); return expression; } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/debug/SymbolReference.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/debug/SymbolReference.java index a2bea8c59..70d57e482 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/debug/SymbolReference.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/debug/SymbolReference.java @@ -4,10 +4,10 @@ import org.simantics.scl.compiler.common.names.Name; public class SymbolReference { public final Name referred; - public final String referrer; + public final Name referrer; public final long referenceLocation; - public SymbolReference(Name referred, String referrer, long referenceLocation) { + public SymbolReference(Name referred, Name referrer, long referenceLocation) { this.referred = referred; this.referrer = referrer; this.referenceLocation = referenceLocation; diff --git a/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF index 60603619a..556475c19 100644 --- a/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF @@ -15,7 +15,8 @@ Require-Bundle: org.eclipse.ui.editors;bundle-version="3.6.0", org.simantics.scl.compiler;bundle-version="0.6.0", org.junit;bundle-version="4.12.0";resolution:=optional, com.ibm.icu, - org.slf4j.api + org.slf4j.api, + org.eclipse.search;bundle-version="3.11.100" Export-Package: org.simantics.scl.ui.console, org.simantics.scl.ui.editor, org.simantics.scl.ui.editor2, diff --git a/bundles/org.simantics.scl.ui/plugin.xml b/bundles/org.simantics.scl.ui/plugin.xml index 56473fc29..885fe77ed 100644 --- a/bundles/org.simantics.scl.ui/plugin.xml +++ b/bundles/org.simantics.scl.ui/plugin.xml @@ -112,6 +112,10 @@ id="org.simantics.scl.editor.openDeclaration" name="Open Declaration"> + + @@ -131,6 +135,10 @@ class="org.simantics.scl.ui.editor2.OpenDeclaration" commandId="org.simantics.scl.editor.openDeclaration"> + + @@ -174,6 +182,12 @@ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="F3"> + + @@ -241,5 +255,13 @@ + + + + diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/FindSCLSearchAction.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/FindSCLSearchAction.java new file mode 100644 index 000000000..15da4192b --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/FindSCLSearchAction.java @@ -0,0 +1,121 @@ +package org.simantics.scl.ui.editor2; + + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.search.ui.NewSearchUI; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PlatformUI; +import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.elaboration.modules.SCLValue; +import org.simantics.scl.compiler.errors.Locations; +import org.simantics.scl.compiler.module.InvalidModulePathException; +import org.simantics.scl.compiler.module.ModuleUtils; +import org.simantics.scl.compiler.source.ModuleSource; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment; +import org.simantics.scl.ui.search.SCLSearchQuery; + +public class FindSCLSearchAction extends AbstractHandler { + + private static boolean isIdentifierPart(char c) { + return Character.isJavaIdentifierPart(c) || c=='.'; + } + + private static String extractIdentifierAt(String text, int caretPos) { + int startPos = caretPos; + while(startPos > 0 && isIdentifierPart(text.charAt(startPos-1))) + --startPos; + int endPos = caretPos; + while(endPos < text.length() && isIdentifierPart(text.charAt(endPos))) + ++endPos; + return text.substring(startPos, endPos); + } + + private static final String SYMBOL_CHARS = "!$%&*+/<=>?@\\^|-:~."; + + private static boolean isSymbolPart(char c) { + for(int i=0;i 0 && isSymbolPart(text.charAt(startPos-1))) + --startPos; + int endPos = caretPos; + while(endPos < text.length() && isSymbolPart(text.charAt(endPos))) + ++endPos; + return text.substring(startPos, endPos); + } + + public static String extractIdentifierOrSymbolAt(String text, int caretPos) { + String result = extractIdentifierAt(text, caretPos); + if(!result.isEmpty()) + return result; + return extractSymbolAt(text, caretPos); + } + + private static String extractLineAt(String text, int caretPos) { + int startPos = caretPos; + while(startPos > 0 && !isNewline(text.charAt(startPos-1))) + --startPos; + int endPos = caretPos; + while(endPos < text.length() && !isNewline(text.charAt(endPos))) + ++endPos; + return text.substring(startPos, endPos); + } + + private static boolean isNewline(char c) { + return c=='\n' || c=='\r'; + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart editor = + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); + if(!(editor instanceof SCLModuleEditor2)) + return null; + SCLModuleEditor2 moduleEditor = (SCLModuleEditor2)editor; + StyledText styledText = (StyledText)moduleEditor.getAdapter(Control.class); + String text = styledText.getText(); + int caretOffset = styledText.getCaretOffset(); + + // Find the line where the caret is +// String lineAtCaret = extractLineAt(text, caretOffset); + // Try to find an identifier at caret + String identifierAtCaret = extractIdentifierOrSymbolAt(text, caretOffset); + if(identifierAtCaret.isEmpty()) + return null; + SCLModuleEditorInput input = (SCLModuleEditorInput)moduleEditor.getEditorInput(); + String localModuleName = input.getModuleName(); + + SCLTextEditorEnvironment editorEnvironment = moduleEditor.getSCLTextEditorEnvironment(); + editorEnvironment.updateEnvironment(moduleEditor.getDocument()); + SCLValue value = editorEnvironment.getValue(identifierAtCaret); + Name name; + if (value == null) { + name = Name.create(localModuleName, identifierAtCaret); + } else { + name = value.getName(); + } + SCLSearchQuery query = new SCLSearchQuery(name, localModuleName); + NewSearchUI.runQueryInBackground(query); + + + +// SCLTextEditorEnvironment editorEnvironment = moduleEditor.getSCLTextEditorEnvironment(); +// editorEnvironment.updateEnvironment(moduleEditor.getDocument()); +// SCLValue value = editorEnvironment.getValue(identifierAtCaret); +// //System.out.println("identifierAtCaret = " + identifierAtCaret + " [" + Locations.beginOf(value.definitionLocation) + ", " + Locations.endOf(value.definitionLocation) + "]"); +// if(value != null) +// OpenSCLDefinition.openDefinition(value); + return null; + } + +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchQuery.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchQuery.java new file mode 100644 index 000000000..9f8ef5a24 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchQuery.java @@ -0,0 +1,91 @@ +package org.simantics.scl.ui.search; + +import java.util.ArrayList; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.search.internal.ui.text.SearchResultUpdater; +import org.eclipse.search.ui.ISearchQuery; +import org.eclipse.search.ui.ISearchResult; +import org.eclipse.search.ui.text.Match; +import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.errors.Failable; +import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.module.debug.ModuleDebugInfo; +import org.simantics.scl.compiler.module.debug.SymbolReference; +import org.simantics.scl.compiler.module.repository.ModuleRepository; +import org.simantics.scl.osgi.SCLOsgi; + +import gnu.trove.procedure.TObjectProcedure; + +public class SCLSearchQuery implements ISearchQuery { + + private SCLSearchResult result; + private String moduleName; + private Name valueName; + + public SCLSearchQuery(Name valueName, String localModuleName) { + this.valueName = valueName; + this.moduleName = localModuleName; + } + + @Override + public IStatus run(IProgressMonitor monitor) throws OperationCanceledException { + SCLSearchResult current = (SCLSearchResult) getSearchResult(); + current.removeAll(); + ModuleRepository repo = SCLOsgi.MODULE_REPOSITORY; + Name localName = Name.create(moduleName, valueName.name); + repo.getSourceRepository().forAllModules(new TObjectProcedure() { + + @Override + public boolean execute(String moduleName) { + Failable failableModule = repo.getModule(moduleName); + if (failableModule.didSucceed()) { + Module module = failableModule.getResult(); + ModuleDebugInfo info = module.getModuleDebugInfo(); + if (info != null) { + ArrayList results = info.symbolReferences; + for (SymbolReference ref : results) { + if (ref.referred.equals(valueName) || ref.referred.equals(localName)) { + result.addMatch(new Match(ref, Match.UNIT_LINE, -1, 1)); + } + } + } + } + return true; + } + }); + return Status.OK_STATUS; + } + + @Override + public String getLabel() { + return "Search references for "; + } + + @Override + public boolean canRerun() { + return true; + } + + @Override + public boolean canRunInBackground() { + return true; + } + + @Override + public ISearchResult getSearchResult() { + if (result == null) { + result = new SCLSearchResult(this); + new SearchResultUpdater(result); + } + return result; + } + + public String getValueName() { + return valueName.toString(); + } + +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResult.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResult.java new file mode 100644 index 000000000..859a29d16 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResult.java @@ -0,0 +1,78 @@ +package org.simantics.scl.ui.search; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.search.ui.ISearchQuery; +import org.eclipse.search.ui.text.AbstractTextSearchResult; +import org.eclipse.search.ui.text.IEditorMatchAdapter; +import org.eclipse.search.ui.text.IFileMatchAdapter; +import org.eclipse.search.ui.text.Match; +import org.eclipse.ui.IEditorPart; + +public class SCLSearchResult extends AbstractTextSearchResult implements IEditorMatchAdapter, IFileMatchAdapter { + + private SCLSearchQuery query; + + public SCLSearchResult(SCLSearchQuery sclSearchQuery) { + this.query = sclSearchQuery; + } + + @Override + public String getLabel() { + return "SCL search result label for " + query.getValueName(); + } + + @Override + public String getTooltip() { + return getLabel(); + } + + @Override + public ImageDescriptor getImageDescriptor() { + return null; + } + + @Override + public ISearchQuery getQuery() { + return query; + } + + @Override + public Match[] computeContainedMatches(AbstractTextSearchResult result, IFile file) { + return null; + } + + @Override + public IFile getFile(Object element) { + return null; + } + + @Override + public boolean isShownInEditor(Match match, IEditorPart editor) { + Object element= match.getElement(); +// if (element instanceof IJavaElement) { +// element= ((IJavaElement) element).getOpenable(); // class file or compilation unit +// return element != null && element.equals(editor.getEditorInput().getAdapter(IJavaElement.class)); +// } else if (element instanceof IFile) { +// return element.equals(editor.getEditorInput().getAdapter(IFile.class)); +// } + return false; + } + + @Override + public Match[] computeContainedMatches(AbstractTextSearchResult result, IEditorPart editor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public IEditorMatchAdapter getEditorMatchAdapter() { + return this; + } + + @Override + public IFileMatchAdapter getFileMatchAdapter() { + return this; + } + +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResultPage.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResultPage.java new file mode 100644 index 000000000..ebc2cbf9e --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/search/SCLSearchResultPage.java @@ -0,0 +1,323 @@ +package org.simantics.scl.ui.search; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider; +import org.eclipse.jface.viewers.DecorationContext; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StyledString; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; +import org.eclipse.search.ui.text.AbstractTextSearchResult; +import org.eclipse.search.ui.text.AbstractTextSearchViewPage; +import org.eclipse.search.ui.text.Match; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.simantics.scl.compiler.module.debug.SymbolReference; +import org.simantics.scl.ui.editor2.OpenDeclaration; +import org.simantics.scl.ui.editor2.OpenSCLDefinition; + +public class SCLSearchResultPage extends AbstractTextSearchViewPage { + + private SCLSearchResultContentProvider contentProvider; + + public SCLSearchResultPage() { + setElementLimit(-1); + } + @Override + protected void elementsChanged(Object[] objects) { + if (contentProvider != null) + contentProvider.elementsChanged(objects); + } + + @Override + protected void clear() { + + } + + private static final ViewerComparator comparator = new ViewerComparator((o1, o2) -> o1.compareTo(o2)); + + @Override + protected void configureTreeViewer(TreeViewer viewer) { + viewer.setUseHashlookup(true); + contentProvider = new SCLSearchResultContentProvider(this); + viewer.setContentProvider(contentProvider); + viewer.setComparator(comparator); + viewer.setLabelProvider(contentProvider); + } + + @Override + protected void configureTableViewer(TableViewer viewer) { + viewer.setUseHashlookup(true); + contentProvider = new SCLSearchResultContentProvider(this); + viewer.setContentProvider(contentProvider); + viewer.setComparator(comparator); + viewer.setLabelProvider(contentProvider); + } + + @Override + protected void handleOpen(OpenEvent event) { + Object selection = ((StructuredSelection)event.getSelection()).getFirstElement(); + if (selection != null) { + SymbolReference reference = (SymbolReference) selection; + OpenSCLDefinition.openDefinition(reference.referrer.module, reference.referenceLocation); + } + } + + @Override + protected void showMatch(Match match, int currentOffset, int currentLength) throws PartInitException { + SymbolReference reference = (SymbolReference) match.getElement(); + OpenSCLDefinition.openDefinition(reference.referrer.module, reference.referenceLocation); + } + + public static class SCLSearchResultContentProvider extends DecoratingStyledCellLabelProvider implements ITreeContentProvider, ILabelProvider { + + private Map> fChildrenMap; + private AbstractTextSearchResult result; + private SCLSearchResultPage page; + + public SCLSearchResultContentProvider(SCLSearchResultPage sclSearchResultPage) { + super(new SCLSearchResultLabelProvider(), PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(), DecorationContext.DEFAULT_CONTEXT); + this.page = sclSearchResultPage; + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + initialize((AbstractTextSearchResult) newInput); + } + + protected void initialize(AbstractTextSearchResult result) { + this.result = result; + fChildrenMap= new HashMap<>(); + if (result != null) { + Object[] elements= result.getElements(); + for (int i= 0; i < elements.length; i++) { + if (getPage().getDisplayedMatchCount(elements[i]) > 0) { + insert(null, null, elements[i]); + } + } + } + } + + private AbstractTextSearchResult getSearchResult() { + return result; + } + + public SCLSearchResultPage getPage() { + return page; + } + + public void elementsChanged(Object[] updatedElements) { + if (getSearchResult() == null) + return; + + AbstractTreeViewer viewer= (AbstractTreeViewer) getPage().getViewer(); + + Set toRemove= new HashSet<>(); + Set toUpdate= new HashSet<>(); + Map> toAdd= new HashMap<>(); + for (int i= 0; i < updatedElements.length; i++) { + if (getPage().getDisplayedMatchCount(updatedElements[i]) > 0) + insert(toAdd, toUpdate, updatedElements[i]); + else + remove(toRemove, toUpdate, updatedElements[i]); + } + + viewer.remove(toRemove.toArray()); + for (Iterator iter= toAdd.keySet().iterator(); iter.hasNext();) { + Object parent= iter.next(); + HashSet children= (HashSet) toAdd.get(parent); + viewer.add(parent, children.toArray()); + } + for (Iterator elementsToUpdate= toUpdate.iterator(); elementsToUpdate.hasNext();) { + viewer.refresh(elementsToUpdate.next()); + } + } + + protected void insert(Map> toAdd, Set toUpdate, Object child) { + Object parent= getParent(child); + while (parent != null) { + if (insertChild(parent, child)) { + if (toAdd != null) + insertInto(parent, child, toAdd); + } else { + if (toUpdate != null) + toUpdate.add(parent); + return; + } + child= parent; + parent= getParent(child); + } + if (insertChild(getSearchResult(), child)) { + if (toAdd != null) + insertInto(getSearchResult(), child, toAdd); + } + } + + private boolean insertChild(Object parent, Object child) { + return insertInto(parent, child, fChildrenMap); + } + + private boolean insertInto(Object parent, Object child, Map> map) { + Set children= map.get(parent); + if (children == null) { + children= new HashSet<>(); + map.put(parent, children); + } + return children.add(child); + } + + protected void remove(Set toRemove, Set toUpdate, Object element) { + // precondition here: fResult.getMatchCount(child) <= 0 + + if (hasChildren(element)) { + if (toUpdate != null) + toUpdate.add(element); + } else { + if (getPage().getDisplayedMatchCount(element) == 0) { + fChildrenMap.remove(element); + Object parent= getParent(element); + if (parent != null) { + if (removeFromSiblings(element, parent)) { + remove(toRemove, toUpdate, parent); + } + } else { + if (removeFromSiblings(element, getSearchResult())) { + if (toRemove != null) + toRemove.add(element); + } + } + } else { + if (toUpdate != null) { + toUpdate.add(element); + } + } + } + } + + /** + * Tries to remove the given element from the list of stored siblings. + * + * @param element potential child + * @param parent potential parent + * @return returns true if it really was a remove (i.e. element was a child of parent). + */ + private boolean removeFromSiblings(Object element, Object parent) { + Set siblings= fChildrenMap.get(parent); + if (siblings != null) { + return siblings.remove(element); + } else { + return false; + } + } + + @Override + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + @Override + public Object getParent(Object element) { + return null; + } + + protected final Object[] EMPTY_ARR= new Object[0]; + + @Override + public Object[] getChildren(Object parentElement) { + Set children= fChildrenMap.get(parentElement); + if (children == null) + return EMPTY_ARR; + int limit= getPage().getElementLimit().intValue(); + if (limit != -1 && limit < children.size()) { + Object[] limitedArray= new Object[limit]; + Iterator iterator= children.iterator(); + for (int i= 0; i < limit; i++) { + limitedArray[i]= iterator.next(); + } + return limitedArray; + } + + return children.toArray(); + } + + @Override + public boolean hasChildren(Object element) { + Set children= fChildrenMap.get(element); + return children != null && !children.isEmpty(); + } + + @Override + public String getText(Object element) { + SymbolReference ref = (SymbolReference) element; + return ref.referrer.toString(); + } + + } + + public static class SCLSearchResultLabelProvider implements ILabelProvider, IColorProvider, IStyledLabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + + } + + @Override + public void dispose() { + + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return true; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + + } + + @Override + public StyledString getStyledText(Object element) { + SymbolReference ref = (SymbolReference) element; + return new StyledString(ref.referrer.toString()); //+ " " + ref.referred + " " + ref.referenceLocation); + } + + @Override + public Color getForeground(Object element) { + return null; + } + + @Override + public Color getBackground(Object element) { + return null; + } + + @Override + public Image getImage(Object element) { + return null; + } + + @Override + public String getText(Object element) { + return null; + } + + } +} diff --git a/features/org.simantics.scl.feature/feature.xml b/features/org.simantics.scl.feature/feature.xml index c0ee33b4e..1e0e2f98b 100644 --- a/features/org.simantics.scl.feature/feature.xml +++ b/features/org.simantics.scl.feature/feature.xml @@ -136,13 +136,6 @@ This Agreement is governed by the laws of the State of New York and the intellec version="0.0.0" unpack="false"/> - - + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + diff --git a/features/org.simantics.sdk.feature/feature.xml b/features/org.simantics.sdk.feature/feature.xml index 6de4ce19c..3c952a4d8 100644 --- a/features/org.simantics.sdk.feature/feature.xml +++ b/features/org.simantics.sdk.feature/feature.xml @@ -200,6 +200,10 @@ id="org.simantics.scl.rest.feature" version="0.0.0"/> + + org.simantics.platform.ui.feature org.simantics.rcp.feature org.simantics.scl.feature + org.simantics.scl.ui.feature org.simantics.scl.rest.feature org.simantics.sdk.feature org.simantics.selectionview.feature -- 2.47.1