Bug 541714: [R-Editor] Adapt to revised ltk InfoHover

Change-Id: I858b6ece41503b931bcc8eedbb724a018141b451
diff --git a/r/org.eclipse.statet.r.debug.ui/src/org/eclipse/statet/internal/r/debug/ui/actions/RDebugHover.java b/r/org.eclipse.statet.r.debug.ui/src/org/eclipse/statet/internal/r/debug/ui/actions/RDebugHover.java
index a352293..60d532b 100644
--- a/r/org.eclipse.statet.r.debug.ui/src/org/eclipse/statet/internal/r/debug/ui/actions/RDebugHover.java
+++ b/r/org.eclipse.statet.r.debug.ui/src/org/eclipse/statet/internal/r/debug/ui/actions/RDebugHover.java
@@ -17,12 +17,14 @@
 import org.eclipse.jface.text.IInformationControlCreator;
 import org.eclipse.ui.IWorkbenchPart;
 
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
 import org.eclipse.statet.jcommons.status.ProgressMonitor;
 import org.eclipse.statet.jcommons.status.StatusException;
 
 import org.eclipse.statet.internal.r.debug.ui.RDebugUIUtils;
 import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
-import org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover;
+import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover;
 import org.eclipse.statet.nico.core.runtime.ToolProcess;
 import org.eclipse.statet.nico.core.runtime.ToolStatus;
 import org.eclipse.statet.nico.ui.NicoUITools;
@@ -35,12 +37,13 @@
 import org.eclipse.statet.rj.ts.core.RTool;
 
 
-public class RDebugHover implements IInfoHover {
+@NonNullByDefault
+public class RDebugHover implements InfoHover {
 	
 	
 	private final int mode;
 	
-	private IInformationControlCreator controlCreator;
+	private @Nullable IInformationControlCreator controlCreator;
 	
 	
 	public RDebugHover() {
@@ -49,7 +52,10 @@
 	
 	
 	@Override
-	public Object getHoverInfo(final AssistInvocationContext context) {
+	public @Nullable Object getHoverInfo(final AssistInvocationContext context,
+			final ProgressMonitor m) {
+		m.beginSubTask("Looking up element info from R console...");
+		
 		final IWorkbenchPart part= context.getEditor().getWorkbenchPart();
 		final ToolProcess tool= NicoUITools.getTool(part);
 		if (!(tool instanceof RTool) || !(context instanceof RAssistInvocationContext)) {
@@ -78,7 +84,7 @@
 	}
 	
 	@Override
-	public IInformationControlCreator getHoverControlCreator() {
+	public @Nullable IInformationControlCreator getHoverControlCreator() {
 		if (this.controlCreator == null) {
 			this.controlCreator= new RElementInfoHoverCreator(this.mode);
 		}
diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/REditorInformationProvider.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/REditorInformationProvider.java
index a3babea..bae234f 100644
--- a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/REditorInformationProvider.java
+++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/REditorInformationProvider.java
@@ -14,8 +14,8 @@
 
 package org.eclipse.statet.internal.r.ui.editors;
 
-import static org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover.MODE_FOCUS;
-import static org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover.MODE_TOOLTIP;
+import static org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover.MODE_FOCUS;
+import static org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover.MODE_TOOLTIP;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jface.text.IDocument;
@@ -24,38 +24,44 @@
 import org.eclipse.jface.text.ITypedRegion;
 import org.eclipse.jface.text.Region;
 
+import org.eclipse.statet.jcommons.collections.ImCollections;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
 import org.eclipse.statet.internal.r.ui.rhelp.RHelpHover;
 import org.eclipse.statet.ltk.ui.sourceediting.EditorInformationProvider;
 import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
-import org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover;
 import org.eclipse.statet.r.core.source.IRDocumentConstants;
 import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
 import org.eclipse.statet.r.ui.editors.IRSourceEditor;
 import org.eclipse.statet.r.ui.sourceediting.RAssistInvocationContext;
 
 
+@NonNullByDefault
 public class REditorInformationProvider extends EditorInformationProvider {
 	
 	
-	private RHeuristicTokenScanner scanner;
+	private @Nullable RHeuristicTokenScanner scanner;
 	
 	
 	public REditorInformationProvider(final IRSourceEditor editor) {
-		super(editor, new IInfoHover[] { new RHelpHover(MODE_TOOLTIP | MODE_FOCUS) });
+		super(editor, ImCollections.newList(new RHelpHover(MODE_TOOLTIP | MODE_FOCUS)));
 	}
 	
 	
 	@Override
 	public IRegion getSubject(final ITextViewer textViewer, final int offset) {
-		if (this.scanner == null) {
-			this.scanner= RHeuristicTokenScanner.create(getEditor().getDocumentContentInfo());
+		RHeuristicTokenScanner scanner= this.scanner;
+		if (scanner == null) {
+			scanner= RHeuristicTokenScanner.create(getEditor().getDocumentContentInfo());
+			this.scanner= scanner;
 		}
 		try {
 			final IDocument document= getEditor().getViewer().getDocument();
-			this.scanner.configure(document);
-			final IRegion word= this.scanner.findRWord(offset, false, true);
+			scanner.configure(document);
+			final IRegion word= scanner.findRWord(offset, false, true);
 			if (word != null) {
-				final ITypedRegion partition= this.scanner.getPartition(word.getOffset());
+				final ITypedRegion partition= scanner.getPartition(word.getOffset());
 				if (IRDocumentConstants.R_DEFAULT_CONTENT_CONSTRAINT.matches(partition.getType())
 						|| partition.getType() == IRDocumentConstants.R_STRING_CONTENT_TYPE
 						|| partition.getType() == IRDocumentConstants.R_QUOTED_SYMBOL_CONTENT_TYPE) {
@@ -69,7 +75,7 @@
 	}
 	
 	@Override
-	protected AssistInvocationContext createContext(final IRegion region,
+	protected @Nullable AssistInvocationContext createContext(final IRegion region,
 			final String contentType, final IProgressMonitor monitor) {
 		final RAssistInvocationContext context= new RAssistInvocationContext(
 				(IRSourceEditor) getEditor(), region, contentType, this.scanner, monitor );
diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RElementCompletionProposal.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RElementCompletionProposal.java
index ed40b57..3cf34c1 100644
--- a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RElementCompletionProposal.java
+++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RElementCompletionProposal.java
@@ -39,7 +39,7 @@
 import org.eclipse.statet.ltk.ui.IElementLabelProvider;
 import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
 import org.eclipse.statet.ltk.ui.sourceediting.assist.ElementNameCompletionProposal;
-import org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover;
+import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover;
 import org.eclipse.statet.nico.ui.console.InputSourceViewer;
 import org.eclipse.statet.r.core.IRCoreAccess;
 import org.eclipse.statet.r.core.RCodeStyleSettings;
@@ -467,7 +467,7 @@
 		}
 		
 		if (this.informationControlCreator == null) {
-			this.informationControlCreator= new RHelpInfoHoverCreator(IInfoHover.MODE_PROPOSAL_INFO);
+			this.informationControlCreator= new RHelpInfoHoverCreator(InfoHover.MODE_PROPOSAL_INFO);
 		}
 		return this.informationControlCreator;
 	}
diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpHover.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpHover.java
index b133ab4..4547e6b 100644
--- a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpHover.java
+++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpHover.java
@@ -19,12 +19,16 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.text.IInformationControlCreator;
 
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+import org.eclipse.statet.jcommons.status.ProgressMonitor;
+import org.eclipse.statet.jcommons.status.StatusException;
 import org.eclipse.statet.jcommons.text.core.TextRegion;
 
 import org.eclipse.statet.ltk.ast.core.util.AstSelection;
 import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
 import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
-import org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover;
+import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover;
 import org.eclipse.statet.r.core.IRCoreAccess;
 import org.eclipse.statet.r.core.RCore;
 import org.eclipse.statet.r.core.model.IRFrame;
@@ -42,7 +46,8 @@
 import org.eclipse.statet.r.core.rsource.ast.RAstNode;
 
 
-public class RHelpHover implements IInfoHover {
+@NonNullByDefault
+public class RHelpHover implements InfoHover {
 	
 	
 	private final int mode;
@@ -58,7 +63,8 @@
 	
 	
 	@Override
-	public Object getHoverInfo(final AssistInvocationContext context) {
+	public @Nullable Object getHoverInfo(final AssistInvocationContext context,
+			final ProgressMonitor m) throws StatusException {
 		final AstSelection selection= context.getAstSelection();
 		if (!(selection.getCovering() instanceof RAstNode)) {
 			return null;
@@ -159,7 +165,7 @@
 		return null;
 	}
 	
-	private IRHelpPage searchFrames(final List<IRHelpPage> helpPages, final List<IRFrame> frames) {
+	private @Nullable IRHelpPage searchFrames(final List<IRHelpPage> helpPages, final List<IRFrame> frames) {
 		if (frames == null) {
 			return null;
 		}
@@ -181,13 +187,14 @@
 		return new RHelpInfoHoverCreator(this.mode);
 	}
 	
-	static RElementName searchName(RAstNode rNode, final TextRegion region, final boolean checkInterrupted) {
+	static @Nullable RElementName searchName(final RAstNode node, final TextRegion region,
+			final boolean checkInterrupted) {
 		RElementAccess access= null;
-		while (rNode != null && access == null) {
+		for (RAstNode node0= node; node0 != null && access == null; node0= node0.getRParent() ) {
 			if (checkInterrupted && Thread.currentThread().isInterrupted()) {
 				return null;
 			}
-			final List<Object> attachments= rNode.getAttachments();
+			final List<Object> attachments= node.getAttachments();
 			for (final Object attachment : attachments) {
 				if (attachment instanceof RElementAccess) {
 					access= (RElementAccess) attachment;
@@ -201,18 +208,17 @@
 					}
 				}
 			}
-			rNode= rNode.getRParent();
 		}
 		return null;
 	}
 	
-	static RElementName searchNameOfFunction(RAstNode rNode, final TextRegion region) {
-		while (rNode != null) {
-			if (rNode.getNodeType() == NodeType.F_CALL) {
-				final FCall fcall= (FCall) rNode;
+	static @Nullable RElementName searchNameOfFunction(final RAstNode node, final TextRegion region) {
+		for (RAstNode node0= node; node0 != null; node0= node0.getRParent() ) {
+			if (node0.getNodeType() == NodeType.F_CALL) {
+				final FCall fcall= (FCall) node0;
 				if (fcall.getArgsOpenOffset() != Integer.MIN_VALUE
 						&& fcall.getArgsOpenOffset() <= region.getStartOffset()) {
-					final List<Object> attachments= ((FCall) rNode).getAttachments();
+					final List<Object> attachments= ((FCall) node0).getAttachments();
 					for (final Object attachment : attachments) {
 						if (attachment instanceof RElementAccess) {
 							final RElementAccess access= (RElementAccess) attachment;
@@ -230,42 +236,38 @@
 				}
 				return null;
 			}
-			rNode= rNode.getRParent();
 		}
 		return null;
 	}
 	
-	static RElementName getElementAccessOfRegion(final RElementAccess access, final TextRegion region) {
+	private static @Nullable RElementName getElementAccessOfRegion(final RElementAccess access, final TextRegion region) {
 		if (access.getSegmentName() == null) {
 			return null;
 		}
 		
 		int segmentCount= 0;
-		RElementAccess current= access;
-		while (current != null) {
+		for (RElementAccess segment0= access; segment0 != null; segment0= segment0.getNextSegment()) {
 			segmentCount++;
-			final RAstNode nameNode= current.getNameNode();
+			final RAstNode nameNode= segment0.getNameNode();
 			if (nameNode != null
 					&& nameNode.getStartOffset() <= region.getStartOffset()
 					&& nameNode.getEndOffset() >= region.getEndOffset() ) {
 				if (RElementName.isRegularMainType(access.getType())) {
 					return access;
 				}
-				if (segmentCount == 1) {
-					if (RElementName.isPackageFacetScopeType(access.getType())) {
+				if (RElementName.isPackageFacetScopeType(access.getType())) {
+					if (segmentCount == 1) {
 						return access;
 					}
-				}
-				else /* (segmentCount > 1) */ {
-					if (RElementName.isPackageFacetScopeType(access.getType())
-							&& RElementName.isRegularMainType(access.getNextSegment().getType())
-							&& access.getNextSegment().getSegmentName() != null) {
-						return RElementName.normalize(access);
+					else /* (segmentCount > 1) */ {
+						if (RElementName.isRegularMainType(access.getNextSegment().getType())
+								&& access.getNextSegment().getSegmentName() != null) {
+							return RElementName.normalize(access);
+						}
 					}
 				}
 				return null;
 			}
-			current= current.getNextSegment();
 		}
 		
 		return null;
diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpInfoHoverCreator.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpInfoHoverCreator.java
index 5c38a86..cf86693 100644
--- a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpInfoHoverCreator.java
+++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/rhelp/RHelpInfoHoverCreator.java
@@ -15,7 +15,7 @@
 package org.eclipse.statet.internal.r.ui.rhelp;
 
 import static org.eclipse.debug.ui.IDebugUIConstants.PREF_DETAIL_PANE_FONT;
-import static org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover.MODE_FOCUS;
+import static org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover.MODE_FOCUS;
 
 import java.net.URI;
 
diff --git a/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/debug/ui/assist/RElementInfoControl.java b/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/debug/ui/assist/RElementInfoControl.java
index c41f919..70d52b4 100644
--- a/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/debug/ui/assist/RElementInfoControl.java
+++ b/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/debug/ui/assist/RElementInfoControl.java
@@ -15,7 +15,7 @@
 package org.eclipse.statet.internal.r.debug.ui.assist;
 
 import static org.eclipse.debug.ui.IDebugUIConstants.PREF_DETAIL_PANE_FONT;
-import static org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover.MODE_FOCUS;
+import static org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover.MODE_FOCUS;
 
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.Platform;
diff --git a/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/objectbrowser/ObjectBrowserView.java b/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/objectbrowser/ObjectBrowserView.java
index 1597364..eceaf81 100644
--- a/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/objectbrowser/ObjectBrowserView.java
+++ b/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/internal/r/objectbrowser/ObjectBrowserView.java
@@ -105,7 +105,7 @@
 import org.eclipse.statet.ltk.core.ElementName;
 import org.eclipse.statet.ltk.ui.ElementNameProvider;
 import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorCommandIds;
-import org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover;
+import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover;
 import org.eclipse.statet.ltk.ui.util.ViewerDragSupport;
 import org.eclipse.statet.nico.core.runtime.ToolProcess;
 import org.eclipse.statet.nico.ui.IToolRegistry;
@@ -315,7 +315,7 @@
 	private class HoverManager extends ColumnHoverManager {
 		
 		HoverManager() {
-			super(ObjectBrowserView.this.treeViewer, ObjectBrowserView.this.tokenOwner, new RElementInfoHoverCreator(IInfoHover.MODE_TOOLTIP));
+			super(ObjectBrowserView.this.treeViewer, ObjectBrowserView.this.tokenOwner, new RElementInfoHoverCreator(InfoHover.MODE_TOOLTIP));
 			
 			final ColumnHoverStickyManager stickyManager= new ColumnHoverStickyManager(ObjectBrowserView.this.tokenOwner, this);
 			getInternalAccessor().setInformationControlReplacer(stickyManager);
diff --git a/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/r/ui/rtool/RElementInfoHoverCreator.java b/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/r/ui/rtool/RElementInfoHoverCreator.java
index bd0f70d..f641814 100644
--- a/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/r/ui/rtool/RElementInfoHoverCreator.java
+++ b/r/org.eclipse.statet.r.ui/srcDebug/org/eclipse/statet/r/ui/rtool/RElementInfoHoverCreator.java
@@ -14,7 +14,7 @@
 
 package org.eclipse.statet.r.ui.rtool;
 
-import static org.eclipse.statet.ltk.ui.sourceediting.assist.IInfoHover.MODE_FOCUS;
+import static org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover.MODE_FOCUS;
 
 import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
 import org.eclipse.jface.text.IInformationControl;
@@ -36,7 +36,7 @@
 	
 	@Override
 	protected IInformationControl doCreateInformationControl(final Shell parent) {
-		return ((this.mode & MODE_FOCUS) != 0) ? 
+		return ((this.mode & MODE_FOCUS) != 0) ?
 				new RElementInfoControl(parent, this.mode, true) :
 				new RElementInfoControl(parent, this.mode);
 	}