Bug 570488 - [genericeditor][DefaultContentAssistProcessor]
IllegalStateException: No match available

Change-Id: I1eb121e526db426185e9747159f3f0810c939680
Signed-off-by: Christoph Läubrich <laeubi@laeubi-soft.de>
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java
index 31be5ba..dd18cea 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java
@@ -14,10 +14,13 @@
 package org.eclipse.ui.genericeditor.tests;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -36,6 +39,11 @@
 import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.swt.widgets.Widget;
 
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.ILogListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+
 import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
 import org.eclipse.jface.text.tests.util.DisplayHelper;
@@ -67,6 +75,18 @@
 	}
 
 	@Test
+	public void testDefaultContentAssistBug570488() throws Exception {
+		ILog log= Platform.getLog(Platform.getBundle("org.eclipse.jface.text"));
+		TestLogListener listener= new TestLogListener();
+		log.addLogListener(listener);
+		createAndOpenFile("Bug570488.txt", "bar 'bar'");
+		openConentAssist();
+		DisplayHelper.driveEventQueue(Display.getCurrent());
+		assertFalse("There are errors in the log", listener.messages.stream().anyMatch(s -> s.matches(IStatus.ERROR)));
+		log.removeLogListener(listener);
+	}
+
+	@Test
 	public void testCompletionUsingViewerSelection() throws Exception {
 		final Set<Shell> beforeShells = Arrays.stream(editor.getSite().getShell().getDisplay().getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
 		editor.getDocumentProvider().getDocument(editor.getEditorInput()).set("abc");
@@ -226,4 +246,15 @@
 			completionShell.close();
 		}
 	}
+
+	private static final class TestLogListener implements ILogListener {
+
+		List<IStatus> messages= new ArrayList<>();
+
+		@Override
+		public void logging(IStatus status, String plugin) {
+			messages.add(status);
+		}
+
+	}
 }
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultContentAssistProcessor.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultContentAssistProcessor.java
index a446ba6..d80bbaf 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultContentAssistProcessor.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/DefaultContentAssistProcessor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2017 Red Hat Inc. and others.
+ * Copyright (c) 2017, 2021 Red Hat Inc. and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
  *
  * Contributors:
  * - Sopot Cela (Red Hat Inc.)
+ * Christoph Läubrich - Bug 570488 - [genericeditor][DefaultContentAssistProcessor] IllegalStateException: No match available
  *******************************************************************************/
 package org.eclipse.ui.internal.genericeditor;
 
@@ -50,13 +51,17 @@
 	@Override
 	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
 		String text = viewer.getDocument().get();
-		String[] tokens = text.split(NON_ALPHANUMERIC_REGEXP);
-
-		//remove duplicates
-		Set<String> tokenSet = new HashSet<>(Arrays.asList(tokens));
-
 		//wordStartIndex is the index of the last non-alphanumeric before 'offset' in text 'text'
 		int wordStartIndex = findStartingPoint(text, offset);
+		if (wordStartIndex < 0) {
+			// not possible
+			return null;
+		}
+		String[] tokens = text.split(NON_ALPHANUMERIC_REGEXP);
+
+		// remove duplicates
+		Set<String> tokenSet = new HashSet<>(Arrays.asList(tokens));
+
 		String prefix = text.substring(wordStartIndex, offset);
 
 		List<ICompletionProposal> proposals = new ArrayList<>();
@@ -80,8 +85,10 @@
 	private static int findStartingPoint(String text, int offset) {
 		String substring = text.substring(0, offset);
 		Matcher m = NON_ALPHANUMERIC_LAST_PATTERN.matcher(substring);
-		m.find();
-		return m.end();
+		if (m.find()) {
+			return m.end();
+		}
+		return -1;
 	}
 
 	@Override