Fix for Bug 529123 - [9][content assist] support MODULE_DECLARATION in
CompletionProposal.getDeclarationSignature

Change-Id: I5f181fa6eed957a8d8fbf6b09896588966d5a534
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
index fb1c08f..2f4ebde 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016, 2017 IBM Corporation and others.
+ * Copyright (c) 2016, 2018 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
@@ -315,7 +315,7 @@
 		ICompilationUnit unit = getCompilationUnit(filePath);
 		unit.codeComplete(cursorLocation, requestor);
 
-		String expected = "[PROPOSAL]{org.eclipse.foo, org.eclipse.foo, null, null, 49}";
+		String expected = "[MODULE_REF]{org.eclipse.foo, org.eclipse.foo, null, null, 49}";
 		assertResults(expected,	requestor.getResults());
 	} finally {
 		deleteProject(project1);
@@ -349,7 +349,7 @@
 		ICompilationUnit unit = getCompilationUnit(filePath);
 		unit.codeComplete(cursorLocation, requestor);
 
-		String expected = "[PROPOSAL]{j.s.r, j.s.r, null, null, 49}";
+		String expected = "[MODULE_REF]{j.s.r, j.s.r, null, null, 49}";
 		assertResults(expected,	requestor.getResults());
 	} finally {
 		deleteProject(project1);
@@ -391,7 +391,7 @@
 		ICompilationUnit unit = getCompilationUnit(filePath);
 		unit.codeComplete(cursorLocation, requestor);
 
-		String expected = "[PROPOSAL]{com.greetings, com.greetings, null, null, 49}";
+		String expected = "[MODULE_REF]{com.greetings, com.greetings, null, null, 49}";
 		assertResults(expected,	requestor.getResults());
 	} finally {
 		deleteProject(project1);
@@ -1016,14 +1016,120 @@
 		ICompilationUnit unit = getCompilationUnit("/Completion9_1/src/module-info.java");
 		unit.codeComplete(cursorLocation, requestor);
 
-		String expected = "[PROPOSAL]{test.second, test.second, null, null, 49}\n" +
-				"[PROPOSAL]{test.some.core.api, test.some.core.api, null, null, 49}\n" +
-				"[PROPOSAL]{test.third.from.manifest, test.third.from.manifest, null, null, 49}";
+		String expected = "[MODULE_REF]{test.second, test.second, null, null, 49}\n" +
+				"[MODULE_REF]{test.some.core.api, test.some.core.api, null, null, 49}\n" +
+				"[MODULE_REF]{test.third.from.manifest, test.third.from.manifest, null, null, 49}";
 		assertResults(expected,	requestor.getResults());
 
 	} finally {
 		deleteProject(project1);
 	}
 }
+public void testBug529123_001() throws Exception {
+	IJavaProject project1 = createJavaProject("Completion9_1", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "9");
+	try {
+		project1.open(null);
+		String filePath = "/Completion9_1/src/module-info.java";
+		String fileContent =  "module Com";
+		createFile(filePath, fileContent);
+		String completeBehind = "Com";
+		int cursorLocation = fileContent.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+
+		ICompilationUnit unit = getCompilationUnit(filePath);
+		unit.codeComplete(cursorLocation, requestor);
+
+		String expected = "Completion9_1[MODULE_DECLARATION]{Completion9_1, Completion9_1, null, Completion9_1, 31}";
+		assertResults(expected,	requestor.getResults());
+	} finally {
+		deleteProject(project1);
+	}
+}
+public void testBug529123_002() throws Exception {
+	String pName = "Completion9-1"; // with a -, 
+	IJavaProject project1 = createJavaProject(pName, new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "9");
+	try {
+		project1.open(null);
+		String filePath = "/" + pName +"/src/module-info.java";
+		String fileContent =  "module Com";
+		createFile(filePath, fileContent);
+		String completeBehind = "Com";
+		int cursorLocation = fileContent.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+
+		ICompilationUnit unit = getCompilationUnit(filePath);
+		unit.codeComplete(cursorLocation, requestor);
+
+		String expected = "";
+		assertResults(expected,	requestor.getResults());
+	} finally {
+		deleteProject(project1);
+	}
+}
+public void testBug529123_003() throws Exception {
+	String pName = "529123"; // a number - invalid module name but a valid project name
+	IJavaProject project1 = createJavaProject(pName, new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "9");
+	try {
+		project1.open(null);
+		String filePath = "/" + pName +"/src/module-info.java";
+		String fileContent =  "module Com";
+		createFile(filePath, fileContent);
+		String completeBehind = "Com";
+		int cursorLocation = fileContent.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+
+		ICompilationUnit unit = getCompilationUnit(filePath);
+		unit.codeComplete(cursorLocation, requestor);
+
+		String expected = "";
+		assertResults(expected,	requestor.getResults());
+	} finally {
+		deleteProject(project1);
+	}
+}
+public void testBug529123_004() throws Exception {
+	String pName = "module.name.test"; // with dots
+	IJavaProject project1 = createJavaProject(pName, new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "9");
+	try {
+		project1.open(null);
+		String filePath = "/" + pName +"/src/module-info.java";
+		String fileContent =  "module Com";
+		createFile(filePath, fileContent);
+		String completeBehind = "Com";
+		int cursorLocation = fileContent.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+
+		ICompilationUnit unit = getCompilationUnit(filePath);
+		unit.codeComplete(cursorLocation, requestor);
+
+		String expected = "";
+		assertResults(expected,	requestor.getResults());
+	} finally {
+		deleteProject(project1);
+	}
+}
+public void testBug529123_005() throws Exception {
+	IJavaProject project1 = createJavaProject("Completion9_1", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "9");
+	try {
+		project1.open(null);
+		String filePath = "/Completion9_1/src/module-info.java";
+		String fileContent =  "module Com";
+		createFile(filePath, fileContent);
+		String completeBehind = "Com";
+		int cursorLocation = fileContent.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+
+		ICompilationUnit unit = getCompilationUnit(filePath);
+		unit.codeComplete(cursorLocation, requestor);
+
+		String expected = "Completion9_1[MODULE_DECLARATION]{Completion9_1, Completion9_1, null, Completion9_1, 31}";
+		String[] actual = requestor.getStringsResult();
+		assertTrue("Null result", actual != null);
+		assertTrue("Incorrect number of elements", actual.length == 1);
+		assertResults(expected,	requestor.getResults());
+	} finally {
+		deleteProject(project1);
+	}
+}
 
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
index 6ba2dd8..4ca2966 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2015 IBM Corporation and others.
+ * Copyright (c) 2004, 2018 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
@@ -354,6 +354,12 @@
 					buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
 				}
 				break;
+			case CompletionProposal.MODULE_DECLARATION :
+				buffer.append("MODULE_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.MODULE_REF :
+				buffer.append("MODULE_REF"); //$NON-NLS-1$
+				break;
 			case CompletionProposal.PACKAGE_REF :
 				buffer.append("PACKAGE_REF"); //$NON-NLS-1$
 				break;
@@ -590,6 +596,7 @@
 			case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION :
 				return new String(proposal.getName());
 			case CompletionProposal.PACKAGE_REF:
+			case CompletionProposal.MODULE_DECLARATION:
 				return new String(proposal.getDeclarationSignature());
 		}
 		return "";
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index 34fa590..836d38d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 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
@@ -2058,7 +2058,7 @@
 						buildContext(parsedUnit.moduleDeclaration, null, parsedUnit, null, null);
 						//this.requestor.setIgnored(CompletionProposal.MODULE_DECLARATION, false); //TODO: Hack until ui fixes this issue.
 						if(!this.requestor.isIgnored(CompletionProposal.MODULE_DECLARATION)) {
-							findModuleName(parsedUnit);
+							proposeModuleName(parsedUnit);
 						}
 						debugPrintf(); 
 						return;
@@ -10689,20 +10689,22 @@
 		}
 	}
 
-	private void findModuleName(CompilationUnitDeclaration parsedUnit) {
-		char[] fileName1 = parsedUnit.getFileName();
-		if (fileName1 == null || !CharOperation.endsWith(fileName1, MODULE_INFO_FILE_NAME)) return;
-		int lastFileSeparatorIndex = fileName1.length - (MODULE_INFO_FILE_NAME.length + 1);
-		if (lastFileSeparatorIndex  <= 0) return;
-		int prevFileSeparatorIndex = CharOperation.lastIndexOf(fileName1[lastFileSeparatorIndex], fileName1, 0, lastFileSeparatorIndex - 1);
-		prevFileSeparatorIndex = prevFileSeparatorIndex < 0 ? 0 : prevFileSeparatorIndex + 1;
-		char[] moduleName = CharOperation.subarray(fileName1, prevFileSeparatorIndex, lastFileSeparatorIndex);
-		if (moduleName == null || moduleName.length == 0) return;
+	private void proposeModuleName(CompilationUnitDeclaration parsedUnit) {
+		String projectName = this.javaProject.getElementName();
+		char[] moduleName = projectName.toCharArray();
+		if (moduleName.length > 0) {// do not propose invalid names
+			if (!Character.isJavaIdentifierStart(moduleName[0])) return;
+			for (char c : moduleName) {
+				if (!Character.isJavaIdentifierPart(c) && c != '.') return; 
+			}
+		}
 		this.completionToken = CharOperation.concatWith(this.moduleDeclaration.tokens, '.');
+		setSourceRange(this.moduleDeclaration.sourceStart, this.moduleDeclaration.bodyStart);
 		if (this.completionToken.length > 0 && !CharOperation.prefixEquals(this.completionToken, moduleName)) return;
 
 		InternalCompletionProposal proposal =  createProposal(CompletionProposal.MODULE_DECLARATION, this.actualCompletionPosition);
 		proposal.setName(moduleName);
+		proposal.setDeclarationSignature(moduleName);
 		proposal.setCompletion(moduleName);
 		proposal.setReplaceRange((this.startPosition < 0) ? 0 : this.startPosition - this.offset, this.endPosition - this.offset);
 		proposal.setTokenRange((this.tokenStart < 0) ? 0 : this.tokenStart - this.offset, this.tokenEnd - this.offset);
@@ -13059,6 +13061,12 @@
 			case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER :
 				buffer.append("METHOD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
 				break;
+			case CompletionProposal.MODULE_DECLARATION :
+				buffer.append("MODULE_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.MODULE_REF :
+				buffer.append("MODULE_REF"); //$NON-NLS-1$
+				break;
 			case CompletionProposal.PACKAGE_REF :
 				buffer.append("PACKAGE_REF"); //$NON-NLS-1$
 				break;
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
index 40bc7b1..8826f30 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2016 IBM Corporation and others.
+ * Copyright (c) 2004, 2018 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
@@ -1068,6 +1068,12 @@
 					buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
 				}
 				break;
+			case CompletionProposal.MODULE_DECLARATION :
+				buffer.append("MODULE_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.MODULE_REF :
+				buffer.append("MODULE_REF"); //$NON-NLS-1$
+				break;
 			case CompletionProposal.PACKAGE_REF :
 				buffer.append("PACKAGE_REF"); //$NON-NLS-1$
 				break;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
index 3dfe18f..da63c15 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2016 IBM Corporation and others.
+ * Copyright (c) 2004, 2018 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
@@ -1179,7 +1179,7 @@
 	}
 
 	/**
-	 * Returns the type signature or package name or module name (1.9) of the relevant
+	 * Returns the type signature or package name or module name (9) of the relevant
 	 * declaration in the context, or <code>null</code> if none.
 	 * <p>
 	 * This field is available for the following kinds of
@@ -1204,6 +1204,8 @@
 	 * 	<li><code>METHOD_DECLARATION</code> - type signature
 	 * of the type that declares the method that is being
 	 * implemented or overridden</li>
+	 * 	<li><code>MODULE_DECLARATION</code> - 
+	 * possible name of the module that is being declared</li>
 	 * 	<li><code>MODULE_REF</code> - 
 	 * name of the module that is referenced</li>
 	 * 	<li><code>PACKAGE_REF</code> - dot-based package
@@ -1220,7 +1222,7 @@
 	 * returned.
 	 * </p>
 	 *
-	 * @return a type signature or a package name or module name (1.9) (depending
+	 * @return a type signature or a package name or module name (9) (depending
 	 * on the kind of completion), or <code>null</code> if none
 	 * @see Signature
 	 */
@@ -1256,7 +1258,7 @@
 	}
 
 	/**
-	 * Sets the type or package or module(1.9) signature of the relevant
+	 * Sets the type or package signature or module name (9) of the relevant
 	 * declaration in the context, or <code>null</code> if none.
 	 * <p>
 	 * If not set, defaults to none.
@@ -1266,7 +1268,7 @@
 	 * its properties; this method is not intended to be used by other clients.
 	 * </p>
 	 *
-	 * @param signature the type or package  or module(1.9) signature, or
+	 * @param signature the type or package signature or module name(9) , or
 	 * <code>null</code> if none
 	 */
 	public void setDeclarationSignature(char[] signature) {