blob: f4d44b1557799f8b153fed5450abfaf2f731965b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 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.jdt.core.tests.model;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import junit.framework.Test;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
public abstract class AbstractJavadocCompletionModelTest extends AbstractJavaModelCompletionTests implements JavadocTagConstants {
// Basic relevance values
/** R_DEFAULT+R_INTERESTING+R_NON_RESTRICTED<br>= 8 */
protected final static int JAVADOC_RELEVANCE = R_DEFAULT+ R_INTERESTING+ R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 9 */
protected final static int R_DRINR= R_DEFAULT+R_RESOLVED+R_INTERESTING+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 12 */
protected final static int R_DRIUNR= R_DEFAULT+R_RESOLVED+R_INTERESTING+R_UNQUALIFIED+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED<br>= 19 */
protected static final int R_DRICNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_QUALIFIED+R_NON_RESTRICTED<br>= 21 */
protected static final int R_DRICQNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_QUALIFIED+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 22 */
protected static final int R_DRICUNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_UNQUALIFIED+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED<br>= 23 */
protected static final int R_DRICENNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_QUALIFIED+R_NON_RESTRICTED<br>= 25 */
protected static final int R_DRICENQNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_QUALIFIED+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 26 */
protected static final int R_DRICENUNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_UNQUALIFIED+R_NON_RESTRICTED;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_NON_STATIC<br>= 30 */
protected static final int R_DRICNRNS = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_NON_RESTRICTED+R_NON_STATIC;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_NON_STATIC<br>= 34 */
protected static final int R_DRICENNRNS = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_NON_RESTRICTED+R_NON_STATIC;
// Exception relevance values
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_EXCEPTION<br>= 39 */
protected static final int R_DRICNRE = R_DRICNR+R_EXCEPTION;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_EXCEPTION<br>= 42 */
protected static final int R_DRICUNRE = R_DRICUNR+R_EXCEPTION;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_EXCEPTION<br>= 43 */
protected static final int R_DRICENNRE = R_DRICENNR+R_EXCEPTION;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_EXCEPTION<br>= 46 */
protected static final int R_DRICENUNRE = R_DRICENUNR+R_EXCEPTION;
// Exact Expected relevance values
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE<br>= 49 */
protected static final int R_DRICNREET = R_DRICNR+R_EXACT_EXPECTED_TYPE;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE<br>= 52 */
protected static final int R_DRICUNREET = R_DRICUNR+R_EXACT_EXPECTED_TYPE;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE+R_EXCEPTION<br>= 72 */
protected static final int R_DRICUNREETE = R_DRICUNR+R_EXACT_EXPECTED_TYPE+R_EXCEPTION;
// Exact Expected Exception relevance values
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_NON_RESTRICTED<br>+R_EXCEPTION+R_EXACT_EXPECTED_TYPE<br>= 69 */
protected static final int R_DRICNREEET = R_DRICNRE+R_EXACT_EXPECTED_TYPE;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXCEPTION<br>
* +R_EXACT_EXPECTED_TYPE<br>= 72 */
protected static final int R_DRICUNREEET = R_DRICUNRE+R_EXACT_EXPECTED_TYPE;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_EXCEPTION<br>
* +R_EXACT_EXPECTED_TYPE<br>= 73 */
protected static final int R_DRICENNREEET = R_DRICENNRE+R_EXACT_EXPECTED_TYPE;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_EXCEPTION<br>
* +R_EXACT_EXPECTED_TYPE<br>= 76 */
protected static final int R_DRICENUNREEET = R_DRICENUNRE+R_EXACT_EXPECTED_TYPE;
// Inline tag relevance values
/** R_DEFAULT+R_INTERESTING+R_NON_RESTRICTED<br>+R_INLINE_TAG<br>= 39 */
protected static final int JAVADOC_RELEVANCE_IT = JAVADOC_RELEVANCE+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br+R_INTERESTING+R_NON_RESTRICTED<br>+R_INLINE_TAG<br>= 40 */
protected static final int R_DRINRIT = R_DRINR+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_INLINE_TAG<br>= 50 */
protected static final int R_DRICNRIT = R_DRICNR+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_INLINE_TAG<br>= 53 */
protected static final int R_DRICUNRIT = R_DRICUNR+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_INLINE_TAG<br>= 54 */
protected static final int R_DRICENNRIT = R_DRICENNR+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_INLINE_TAG<br>= 57 */
protected static final int R_DRICENUNRIT = R_DRICENUNR+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_NON_STATIC+R_INLINE_TAG<br>= 61 */
protected static final int R_DRICNRNSIT = R_DRICNRNS+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_NON_RESTRICTED<br>+R_EXACT_EXPECTED_TYPE+R_INLINE_TAG<br>= 80 */
protected static final int R_DRICNREETIT = R_DRICNREET+R_INLINE_TAG;
/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE<br>
* +R_INLINE_TAG<br>= 83 */
protected static final int R_DRICUNREETIT = R_DRICUNREET+R_INLINE_TAG;
// Store all relevance values in array
private static final int[] RELEVANCES = {
JAVADOC_RELEVANCE,
R_DRIUNR,
R_DRICNR,
R_DRICQNR,
R_DRICUNR,
R_DRICENNR,
R_DRICENQNR,
R_DRICENUNR,
R_DRICNRNS,
R_DRICENNRNS,
R_DRICNRE,
R_DRICUNRE,
R_DRICENNRE,
R_DRICENUNRE,
R_DRICNREET,
R_DRICUNREET,
R_DRICNREEET,
R_DRICUNREEET,
R_DRICENNREEET,
R_DRICENUNREEET,
JAVADOC_RELEVANCE_IT,
R_DRICNRIT,
R_DRICUNRIT,
R_DRICENNRIT,
R_DRICENUNRIT,
R_DRICNRNSIT,
R_DRICNREETIT,
R_DRICUNREETIT,
};
private static final String[] RELEVANCES_NAMES = {
"JAVADOC_RELEVANCE",
"R_DRIUNR",
"R_DRICNR",
"R_DRICQNR",
"R_DRICUNR",
"R_DRICENNR",
"R_DRICENQNR",
"R_DRICENUNR",
"R_DRICNRNS",
"R_DRICENNRNS",
"R_DRICNRE",
"R_DRICUNRE",
"R_DRICENNRE",
"R_DRICENUNRE",
"R_DRICNREET",
"R_DRICUNREET",
"R_DRICNREEET",
"R_DRICUNREEET",
"R_DRICENNREEET",
"R_DRICENUNREEET",
"JAVADOC_RELEVANCE_IT",
"R_DRICNRIT",
"R_DRICUNRIT",
"R_DRICENNRIT",
"R_DRICENUNRIT",
"R_DRICNRNSIT",
"R_DRICNREETIT",
"R_DRICUNREETIT",
};
// Write file contents
protected static final String WRITE_DIR = System.getProperty("writeDir");
protected static final File WRITE_DIR_FILE;
protected static final Set PACKAGE_FILES = new HashSet();
static {
File writeDir = null;
if (WRITE_DIR != null) {
// Create write directory if necessay
writeDir = new File(WRITE_DIR);
if (writeDir.exists()) {
// perhaps delete all files...
} else if (!writeDir.mkdirs()) {
System.err.println(WRITE_DIR+" does NOT exist and cannot be created!!!");
writeDir = null;
}
}
WRITE_DIR_FILE = writeDir;
}
CompletionTestsRequestor2 requestor;
protected int cursorLocation;
protected int completionStart;
protected String replacedText;
protected String positions;
public AbstractJavadocCompletionModelTest(String name) {
super(name);
this.tabs = 2;
this.displayName = true;
this.endChar = "";
}
public static Test suite() {
return buildModelTestSuite(AbstractJavadocCompletionModelTest.class);
}
protected void assertResults(String expected) throws JavaModelException {
int length = this.workingCopies.length;
String[] sources = new String[length*2];
for (int i=0; i<length; i++) {
sources[i*2] = this.workingCopies[i].getPath().toString();
sources[i*2+1] = this.workingCopies[i].getSource();
}
assertResults(sources, expected, this.requestor.getResultsWithoutSorting());
}
protected void assertSortedResults(String expected) throws JavaModelException {
int length = this.workingCopies.length;
String[] sources = new String[length*2];
for (int i=0; i<length; i++) {
sources[i*2] = this.workingCopies[i].getPath().toString();
sources[i*2+1] = this.workingCopies[i].getSource();
}
assertResults(sources, expected, this.requestor.getReversedResults());
}
private void assertResults(String[] sources, String expected, String actual) {
int count = this.requestor.proposalsPtr+1;
if (!expected.equals(actual)) {
System.out.println("********************************************************************************");
if (this.displayName) {
System.out.print(getName());
System.out.print(" got ");
if (count==0)
System.out.println("no result!");
else {
System.out.print(count);
System.out.print(" result");
if (count==1)
System.out.println(":");
else
System.out.println("s:");
}
}
if (!this.displayName || count>0) {
System.out.println(displayString(actual, this.tabs));
System.out.println(this.endChar);
}
System.out.println("--------------------------------------------------------------------------------");
for (int i=0, length = sources.length; i<length; i+=2) {
System.out.println(sources[i]);
System.out.println(sources[i+1]);
}
}
assertEquals(
"Completion proposals are not correct!",
expected,
actual
);
}
protected void assertNoProblem(String path) {
String problem = this.requestor.getProblem();
if (problem.length() > 0) {
System.out.println("********************************************************************************");
if (this.displayName) {
System.out.print(getName());
System.out.println(" contains an error although it should NOT:");
}
System.out.println(displayString(problem, this.tabs));
System.out.println("--------------------------------------------------------------------------------");
System.out.println(this.workingCopies[0].getPath().toString()+'\n');
try {
System.out.println(this.workingCopies[0].getSource());
} catch (JavaModelException e) {
// forget it
}
assertEquals(
path+" should have NO problem!",
"",
problem
);
}
}
protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind) throws JavaModelException {
completeInJavadoc(path, source, showPositions, completeBehind, 1 /* first index */);
}
protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, boolean last) throws JavaModelException {
completeInJavadoc(path, source, showPositions, completeBehind, last ? -1 : 1);
}
protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, int occurencePosition) throws JavaModelException {
completeInJavadoc(new String[] { path, source }, showPositions, completeBehind, occurencePosition, null);
}
protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, int occurencePosition, int[] ignoreList) throws JavaModelException {
completeInJavadoc(new String[] { path, source }, showPositions, completeBehind, occurencePosition, ignoreList);
}
protected void completeInJavadoc(String[] sources, boolean showPositions, String completeBehind) throws JavaModelException {
completeInJavadoc(sources, showPositions, completeBehind, 1, null);
}
protected void completeInJavadoc(String[] sources, boolean showPositions, String completeBehind, int occurencePosition) throws JavaModelException {
completeInJavadoc(sources, showPositions, completeBehind, occurencePosition, null);
}
protected void completeInJavadoc(String[] sources, boolean showPositions, String completeBehind, int occurencePosition, int[] ignoreList) throws JavaModelException {
assertNotNull("We should have sources!!!", sources);
assertTrue("Invalid number of sources!!!", sources.length%2==0);
// Build working copy(ies)
int length = sources.length / 2;
this.workingCopies = new ICompilationUnit[length];
for (int i=0; i<length; i++) {
this.workingCopies[i] = getWorkingCopy(sources[i*2], sources[i*2+1]);
if (WRITE_DIR != null) writeFiles(sources);
}
// Wait for indexes
waitUntilIndexesReady();
// Complete
this.requestor = new CompletionTestsRequestor2(true, false, showPositions);
if (ignoreList != null) {
for (int i = 0; i < ignoreList.length; i++) {
this.requestor.setIgnored(ignoreList[i], true);
}
}
String source = this.workingCopies[0].getSource();
this.replacedText = completeBehind;
this.completionStart = -1;
int cursorPos = this.replacedText.length();
if (occurencePosition < -10) { // case where we want to specify directly the cursor location relatively to completion start
this.completionStart = source.indexOf(this.replacedText);
cursorPos = -occurencePosition - 10;
} else if (occurencePosition < 0) {
this.completionStart = source.lastIndexOf(this.replacedText);
int max = -occurencePosition;
for (int i=1; i<max; i++) {
this.completionStart = source.lastIndexOf(this.replacedText, this.completionStart);
}
} else {
this.completionStart = source.indexOf(this.replacedText);
int shift = this.replacedText.length();
for (int i=1; i<occurencePosition && this.completionStart>0; i++) {
this.completionStart = source.indexOf(this.replacedText, this.completionStart+shift);
}
}
assertTrue("We should have found "+occurencePosition+" occurence(s) of '"+this.replacedText+"' in:\n"+source, this.completionStart>0);
this.cursorLocation = this.completionStart + cursorPos;
this.workingCopies[0].codeComplete(this.cursorLocation, this.requestor, this.wcOwner);
assertNoProblem(sources[0]);
// Store replacement info
if (occurencePosition == 0) { // special case for completion on empty token...
this.completionStart = this.cursorLocation;
}
int endPosition = this.cursorLocation;
char ch = source.charAt(endPosition);
if (Character.isJavaIdentifierPart(ch) || ch == '>' || ch == '}' || ch == '(' || ch == ')') {
do {
ch = source.charAt(++endPosition);
} while (Character.isJavaIdentifierPart(ch) || ch == '>' || ch == '}' || ch == '(' || ch == ')');
}
this.positions = "["+this.completionStart+", "+endPosition+"], ";
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#displayString(java.lang.String, int)
*/
protected String displayString(String toPrint, int indent) {
String toDisplay = super.displayString(toPrint, indent);
int openBracket = toDisplay.indexOf(", [");
if (openBracket > 0) {
StringBuffer buffer = new StringBuffer();
int closeBracket = 0;
while (openBracket > 0) {
buffer.append(toDisplay.substring(closeBracket, openBracket+2));
closeBracket = toDisplay.indexOf("], ", openBracket+3);
if (closeBracket < 0) break; // invalid
closeBracket += 3;
buffer.append("\"+this.positions+");
int i=0;
while (toDisplay.charAt(closeBracket+i) != '}') i++;
try {
int relevance = Integer.parseInt(toDisplay.substring(closeBracket, closeBracket+i));
int length = RELEVANCES.length;
boolean found = false;
for (int r=0; !found && r<length; r++) {
if (RELEVANCES[r] == relevance) {
buffer.append(RELEVANCES_NAMES[r]);
buffer.append("+\"");
found = true;
}
}
if (!found) {
buffer.append('"');
buffer.append(relevance);
}
closeBracket += i;
}
catch (NumberFormatException nfe) {
System.err.println(nfe.getMessage()+" should not occur!");
}
openBracket = toDisplay.indexOf(", [", closeBracket);
}
if (closeBracket > 0) {
buffer.append(toDisplay.substring(closeBracket, toDisplay.length()));
toDisplay = buffer.toString();
}
}
return toDisplay.replaceAll(", 8}", ", \"+JAVADOC_RELEVANCE+\"}");
}
protected void setUpProjectOptions(String compliance) throws JavaModelException {
try {
setUpProjectCompliance(COMPLETION_PROJECT, compliance);
} catch (IOException e) {
assertTrue("Unexpected IOException: "+e.getMessage(), false);
}
}
public void setUpSuite() throws Exception {
super.setUpSuite();
if (COMPLETION_PROJECT == null) {
COMPLETION_PROJECT = setUpJavaProject("Completion");
createFolder(new Path("/Completion/src/javadoc/tags"));
} else {
setUpProjectCompliance(COMPLETION_PROJECT, "1.4");
this.currentProject = COMPLETION_PROJECT;
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#tearDown()
*/
protected void tearDown() throws Exception {
this.requestor = null;
super.tearDown();
}
public void tearDownSuite() throws Exception {
deleteFolder(new Path("/Completion/src/javadoc/tags"));
super.tearDownSuite();
if (COMPLETION_SUITES == null) {
COMPLETION_PROJECT = null;
}
}
/*
* Write files for self-hosting debug.
*/
protected void writeFiles(String[] sources) {
// Get write directory path
if (WRITE_DIR_FILE == null) return;
// Get test name
String testName = getName();
int idx = testName.indexOf(" - ");
if (idx > 0) {
testName = testName.substring(idx+3);
}
// testName = "Test"+testName.substring(4);
// Write sources to dir
int length = sources.length / 2;
String[][] names = new String[length][3];
for (int i=0; i<length; i++) {
// Get pathes
IPath filePath = new Path(sources[2*i]).removeFirstSegments(2); // remove project and source folder
IPath dirPath = filePath.removeLastSegments(1);
String fileDir = dirPath.toString();
String typeName = filePath.removeFileExtension().lastSegment();
// Create package dir or delete files if already exist
File packageDir = new File(WRITE_DIR_FILE, fileDir);
if (!PACKAGE_FILES.contains(packageDir)) {
if (packageDir.exists()) {
PACKAGE_FILES.add(packageDir);
Util.delete(packageDir);
} else if (packageDir.mkdirs()) {
PACKAGE_FILES.add(packageDir);
} else {
System.err.println(packageDir+" does not exist and CANNOT be created!!!");
continue;
}
}
// Store names info
names[i][0] = typeName;
String fileName = (typeName.length() <= 3) ? typeName : typeName.substring(0, typeName.length()-3);
fileName = fileName + testName.substring(4);
names[i][1] = fileName;
names[i][2] = packageDir.getAbsolutePath()+"\\"+fileName+".java";
}
// Write modified contents
for (int i=0; i<length; i++) {
String contents = sources[2*i+1];
for (int j=0; j<length; j++) {
contents = contents.replaceAll(names[j][0], names[j][1]);
}
String fullPathName = names[i][2];
System.out.println("Write file "+fullPathName);
Util.writeToFile(contents, fullPathName);
}
}
}