1 /*******************************************************************************
2  * Copyright (c) 2000, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.core.tests.model;
15 
16 import java.io.File;
17 import java.io.IOException;
18 import java.util.HashSet;
19 import java.util.Set;
20 
21 import junit.framework.Test;
22 
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.Path;
25 import org.eclipse.jdt.core.ICompilationUnit;
26 import org.eclipse.jdt.core.JavaModelException;
27 import org.eclipse.jdt.core.tests.util.Util;
28 import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
29 
30 @SuppressWarnings({"rawtypes", "unchecked"})
31 public abstract class AbstractJavadocCompletionModelTest extends AbstractJavaModelCompletionTests implements JavadocTagConstants {
32 
33 	// Basic relevance values
34 	/** R_DEFAULT+R_INTERESTING+R_NON_RESTRICTED<br>= 8 */
35 	protected final static int JAVADOC_RELEVANCE = R_DEFAULT+ R_INTERESTING+ R_NON_RESTRICTED;
36 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 9 */
37 	protected final static int R_DRINR= R_DEFAULT+R_RESOLVED+R_INTERESTING+R_NON_RESTRICTED;
38 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 12 */
39 	protected final static int R_DRIUNR= R_DEFAULT+R_RESOLVED+R_INTERESTING+R_UNQUALIFIED+R_NON_RESTRICTED;
40 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED<br>= 19 */
41 	protected static final int R_DRICNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_NON_RESTRICTED;
42 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_QUALIFIED+R_NON_RESTRICTED<br>= 21 */
43 	protected static final int R_DRICQNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_QUALIFIED+R_NON_RESTRICTED;
44 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 22 */
45 	protected static final int R_DRICUNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_UNQUALIFIED+R_NON_RESTRICTED;
46 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED<br>= 23 */
47 	protected static final int R_DRICENNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_NON_RESTRICTED;
48 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_QUALIFIED+R_NON_RESTRICTED<br>= 25 */
49 	protected static final int R_DRICENQNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_QUALIFIED+R_NON_RESTRICTED;
50 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED<br>= 26 */
51 	protected static final int R_DRICENUNR = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_UNQUALIFIED+R_NON_RESTRICTED;
52 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_NON_STATIC<br>= 30 */
53 	protected static final int R_DRICNRNS = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_NON_RESTRICTED+R_NON_STATIC;
54 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_NON_STATIC<br>= 34 */
55 	protected static final int R_DRICENNRNS = R_DEFAULT+R_RESOLVED+R_INTERESTING+R_CASE+R_EXACT_NAME+R_NON_RESTRICTED+R_NON_STATIC;
56 
57 	// Exception relevance values
58 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_EXCEPTION<br>= 39 */
59 	protected static final int R_DRICNRE = R_DRICNR+R_EXCEPTION;
60 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_EXCEPTION<br>= 42 */
61 	protected static final int R_DRICUNRE = R_DRICUNR+R_EXCEPTION;
62 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_EXCEPTION<br>= 43 */
63 	protected static final int R_DRICENNRE = R_DRICENNR+R_EXCEPTION;
64 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_EXCEPTION<br>= 46 */
65 	protected static final int R_DRICENUNRE = R_DRICENUNR+R_EXCEPTION;
66 
67 	// Exact Expected relevance values
68 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE<br>= 49 */
69 	protected static final int R_DRICNREET = R_DRICNR+R_EXACT_EXPECTED_TYPE;
70 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE<br>= 52 */
71 	protected static final int R_DRICUNREET = R_DRICUNR+R_EXACT_EXPECTED_TYPE;
72 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE+R_EXCEPTION<br>= 72 */
73 	protected static final int R_DRICUNREETE = R_DRICUNR+R_EXACT_EXPECTED_TYPE+R_EXCEPTION;
74 
75 	// Exact Expected Exception relevance values
76 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_NON_RESTRICTED<br>+R_EXCEPTION+R_EXACT_EXPECTED_TYPE<br>= 69 */
77 	protected static final int R_DRICNREEET = R_DRICNRE+R_EXACT_EXPECTED_TYPE;
78 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXCEPTION<br>
79 	 * +R_EXACT_EXPECTED_TYPE<br>= 72 */
80 	protected static final int R_DRICUNREEET = R_DRICUNRE+R_EXACT_EXPECTED_TYPE;
81 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_EXCEPTION<br>
82 	 * +R_EXACT_EXPECTED_TYPE<br>= 73 */
83 	protected static final int R_DRICENNREEET = R_DRICENNRE+R_EXACT_EXPECTED_TYPE;
84 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_EXCEPTION<br>
85 	 * +R_EXACT_EXPECTED_TYPE<br>= 76 */
86 	protected static final int R_DRICENUNREEET = R_DRICENUNRE+R_EXACT_EXPECTED_TYPE;
87 
88 	// Inline tag relevance values
89 	/** R_DEFAULT+R_INTERESTING+R_NON_RESTRICTED<br>+R_INLINE_TAG<br>= 39 */
90 	protected static final int JAVADOC_RELEVANCE_IT = JAVADOC_RELEVANCE+R_INLINE_TAG;
91 	/** R_DEFAULT+R_RESOLVED<br+R_INTERESTING+R_NON_RESTRICTED<br>+R_INLINE_TAG<br>= 40 */
92 	protected static final int R_DRINRIT = R_DRINR+R_INLINE_TAG;
93 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_INLINE_TAG<br>= 50 */
94 	protected static final int R_DRICNRIT = R_DRICNR+R_INLINE_TAG;
95 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_INLINE_TAG<br>= 53 */
96 	protected static final int R_DRICUNRIT = R_DRICUNR+R_INLINE_TAG;
97 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_NON_RESTRICTED+R_INLINE_TAG<br>= 54 */
98 	protected static final int R_DRICENNRIT = R_DRICENNR+R_INLINE_TAG;
99 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_EXACT_NAME<br>+R_UNQUALIFIED+R_NON_RESTRICTED+R_INLINE_TAG<br>= 57 */
100 	protected static final int R_DRICENUNRIT = R_DRICENUNR+R_INLINE_TAG;
101 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE<br>+R_NON_RESTRICTED+R_NON_STATIC+R_INLINE_TAG<br>= 61 */
102 	protected static final int R_DRICNRNSIT = R_DRICNRNS+R_INLINE_TAG;
103 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_NON_RESTRICTED<br>+R_EXACT_EXPECTED_TYPE+R_INLINE_TAG<br>= 80 */
104 	protected static final int R_DRICNREETIT = R_DRICNREET+R_INLINE_TAG;
105 	/** R_DEFAULT+R_RESOLVED<br>+R_INTERESTING+R_CASE+R_UNQUALIFIED<br>+R_NON_RESTRICTED+R_EXACT_EXPECTED_TYPE<br>
106 	 * +R_INLINE_TAG<br>= 83 */
107 	protected static final int R_DRICUNREETIT = R_DRICUNREET+R_INLINE_TAG;
108 
109 	// Store all relevance values in array
110 	private static final int[] RELEVANCES = {
111 		JAVADOC_RELEVANCE,
112 		R_DRIUNR,
113 		R_DRICNR,
114 		R_DRICQNR,
115 		R_DRICUNR,
116 		R_DRICENNR,
117 		R_DRICENQNR,
118 		R_DRICENUNR,
119 		R_DRICNRNS,
120 		R_DRICENNRNS,
121 		R_DRICNRE,
122 		R_DRICUNRE,
123 		R_DRICENNRE,
124 		R_DRICENUNRE,
125 		R_DRICNREET,
126 		R_DRICUNREET,
127 		R_DRICNREEET,
128 		R_DRICUNREEET,
129 		R_DRICENNREEET,
130 		R_DRICENUNREEET,
131 		JAVADOC_RELEVANCE_IT,
132 		R_DRICNRIT,
133 		R_DRICUNRIT,
134 		R_DRICENNRIT,
135 		R_DRICENUNRIT,
136 		R_DRICNRNSIT,
137 		R_DRICNREETIT,
138 		R_DRICUNREETIT,
139 	};
140 	private static final String[] RELEVANCES_NAMES = {
141 		"JAVADOC_RELEVANCE",
142 		"R_DRIUNR",
143 		"R_DRICNR",
144 		"R_DRICQNR",
145 		"R_DRICUNR",
146 		"R_DRICENNR",
147 		"R_DRICENQNR",
148 		"R_DRICENUNR",
149 		"R_DRICNRNS",
150 		"R_DRICENNRNS",
151 		"R_DRICNRE",
152 		"R_DRICUNRE",
153 		"R_DRICENNRE",
154 		"R_DRICENUNRE",
155 		"R_DRICNREET",
156 		"R_DRICUNREET",
157 		"R_DRICNREEET",
158 		"R_DRICUNREEET",
159 		"R_DRICENNREEET",
160 		"R_DRICENUNREEET",
161 		"JAVADOC_RELEVANCE_IT",
162 		"R_DRICNRIT",
163 		"R_DRICUNRIT",
164 		"R_DRICENNRIT",
165 		"R_DRICENUNRIT",
166 		"R_DRICNRNSIT",
167 		"R_DRICNREETIT",
168 		"R_DRICUNREETIT",
169 	};
170 
171 	// Write file contents
172 	protected static final String WRITE_DIR = System.getProperty("writeDir");
173 	protected static final File WRITE_DIR_FILE;
174 	protected static final Set PACKAGE_FILES = new HashSet();
175 	static {
176 		File writeDir = null;
177 		if (WRITE_DIR != null) {
178 			// Create write directory if necessay
179 			writeDir = new File(WRITE_DIR);
180 			if (writeDir.exists()) {
181 				// perhaps delete all files...
182 			} else if (!writeDir.mkdirs()) {
183 				System.err.println(WRITE_DIR+" does NOT exist and cannot be created!!!");
184 				writeDir = null;
185 			}
186 
187 		}
188 		WRITE_DIR_FILE = writeDir;
189 	}
190 
191 	CompletionTestsRequestor2 requestor;
192 	protected int cursorLocation;
193 	protected int completionStart;
194 	protected String replacedText;
195 	protected String positions;
196 
AbstractJavadocCompletionModelTest(String name)197 	public AbstractJavadocCompletionModelTest(String name) {
198 		super(name);
199 		this.tabs = 2;
200 		this.displayName = true;
201 		this.endChar = "";
202 	}
203 
suite()204 	public static Test suite() {
205 		return buildModelTestSuite(AbstractJavadocCompletionModelTest.class);
206 	}
assertResults(String expected)207 	protected void assertResults(String expected) throws JavaModelException {
208 		int length = this.workingCopies.length;
209 		String[] sources = new String[length*2];
210 		for (int i=0; i<length; i++) {
211 			sources[i*2] = this.workingCopies[i].getPath().toString();
212 			sources[i*2+1] = this.workingCopies[i].getSource();
213 		}
214 		assertResults(sources, expected, this.requestor.getResultsWithoutSorting());
215 	}
assertSortedResults(String expected)216 	protected void assertSortedResults(String expected) throws JavaModelException {
217 		int length = this.workingCopies.length;
218 		String[] sources = new String[length*2];
219 		for (int i=0; i<length; i++) {
220 			sources[i*2] = this.workingCopies[i].getPath().toString();
221 			sources[i*2+1] = this.workingCopies[i].getSource();
222 		}
223 		assertResults(sources, expected, this.requestor.getReversedResults());
224 	}
assertResults(String[] sources, String expected, String actual)225 	private void assertResults(String[] sources, String expected, String actual) {
226 		int count = this.requestor.proposalsPtr+1;
227 		if (!expected.equals(actual)) {
228 			System.out.println("********************************************************************************");
229 			if (this.displayName) {
230 				System.out.print(getName());
231 				System.out.print(" got ");
232 				if (count==0)
233 					System.out.println("no result!");
234 				else {
235 					System.out.print(count);
236 					System.out.print(" result");
237 					if (count==1)
238 						System.out.println(":");
239 					else
240 						System.out.println("s:");
241 				}
242 			}
243 			if (!this.displayName || count>0) {
244 				System.out.println(displayString(actual, this.tabs));
245 				System.out.println(this.endChar);
246 			}
247 			System.out.println("--------------------------------------------------------------------------------");
248 			for (int i=0, length = sources.length; i<length; i+=2) {
249 				System.out.println(sources[i]);
250 				System.out.println(sources[i+1]);
251 			}
252 		}
253 		assertEquals(
254 			"Completion proposals are not correct!",
255 			expected,
256 			actual
257 		);
258 	}
assertNoProblem(String path)259 	protected void assertNoProblem(String path) {
260 		String problem = this.requestor.getProblem();
261 		if (problem.length() > 0) {
262 			System.out.println("********************************************************************************");
263 			if (this.displayName) {
264 				System.out.print(getName());
265 				System.out.println(" contains an error although it should NOT:");
266 			}
267 			System.out.println(displayString(problem, this.tabs));
268 			System.out.println("--------------------------------------------------------------------------------");
269 			System.out.println(this.workingCopies[0].getPath().toString()+'\n');
270 			try {
271 				System.out.println(this.workingCopies[0].getSource());
272 			} catch (JavaModelException e) {
273 				// forget it
274 			}
275 			assertEquals(
276 				path+" should have NO problem!",
277 				"",
278 				problem
279 			);
280 		}
281 	}
282 
completeInJavadoc(String path, String source, boolean showPositions, String completeBehind)283 	protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind) throws JavaModelException {
284 		completeInJavadoc(path, source, showPositions, completeBehind, 1 /* first index */);
285 	}
286 
completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, boolean last)287 	protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, boolean last) throws JavaModelException {
288 		completeInJavadoc(path, source, showPositions, completeBehind, last ? -1 : 1);
289 	}
290 
completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, int occurencePosition)291 	protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, int occurencePosition) throws JavaModelException {
292 		completeInJavadoc(new String[] { path, source }, showPositions, completeBehind, occurencePosition, null);
293 	}
294 
completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, int occurencePosition, int[] ignoreList)295 	protected void completeInJavadoc(String path, String source, boolean showPositions, String completeBehind, int occurencePosition, int[] ignoreList) throws JavaModelException {
296 		completeInJavadoc(new String[] { path, source }, showPositions, completeBehind, occurencePosition, ignoreList);
297 	}
completeInJavadoc(String[] sources, boolean showPositions, String completeBehind)298 	protected void completeInJavadoc(String[] sources, boolean showPositions, String completeBehind) throws JavaModelException {
299 		completeInJavadoc(sources, showPositions, completeBehind, 1, null);
300 	}
301 
completeInJavadoc(String[] sources, boolean showPositions, String completeBehind, int occurencePosition)302 	protected void completeInJavadoc(String[] sources, boolean showPositions, String completeBehind, int occurencePosition) throws JavaModelException {
303 		completeInJavadoc(sources, showPositions, completeBehind, occurencePosition, null);
304 	}
305 
completeInJavadoc(String[] sources, boolean showPositions, String completeBehind, int occurencePosition, int[] ignoreList)306 	protected void completeInJavadoc(String[] sources, boolean showPositions, String completeBehind, int occurencePosition, int[] ignoreList) throws JavaModelException {
307 		assertNotNull("We should have sources!!!", sources);
308 		assertTrue("Invalid number of sources!!!",  sources.length%2==0);
309 
310 		// Build working copy(ies)
311 		int length = sources.length / 2;
312 		this.workingCopies = new ICompilationUnit[length];
313 		for (int i=0; i<length; i++) {
314 			this.workingCopies[i] = getWorkingCopy(sources[i*2], sources[i*2+1]);
315 			if (WRITE_DIR != null) 	writeFiles(sources);
316 		}
317 
318 		// Wait for indexes
319 		waitUntilIndexesReady();
320 
321 		// Complete
322 		this.requestor = new CompletionTestsRequestor2(true, false, showPositions);
323 		if (ignoreList != null) {
324 			for (int i = 0; i < ignoreList.length; i++) {
325 				this.requestor.setIgnored(ignoreList[i], true);
326 			}
327 		}
328 		String source = this.workingCopies[0].getSource();
329 		this.replacedText = completeBehind;
330 		this.completionStart = -1;
331 		int cursorPos = this.replacedText.length();
332 		if (occurencePosition < -10) { // case where we want to specify directly the cursor location relatively to completion start
333 			this.completionStart = source.indexOf(this.replacedText);
334 			cursorPos = -occurencePosition - 10;
335 		} else if (occurencePosition < 0) {
336 			this.completionStart = source.lastIndexOf(this.replacedText);
337 			int max = -occurencePosition;
338 			for (int i=1; i<max; i++) {
339 				this.completionStart = source.lastIndexOf(this.replacedText, this.completionStart);
340 			}
341 		} else {
342 			this.completionStart = source.indexOf(this.replacedText);
343 			int shift = this.replacedText.length();
344 			for (int i=1; i<occurencePosition && this.completionStart>0; i++) {
345 				this.completionStart = source.indexOf(this.replacedText, this.completionStart+shift);
346 			}
347 		}
348 		assertTrue("We should have found "+occurencePosition+" occurence(s) of '"+this.replacedText+"' in:\n"+source, this.completionStart>0);
349 		this.cursorLocation =  this.completionStart + cursorPos;
350 		this.workingCopies[0].codeComplete(this.cursorLocation, this.requestor, this.wcOwner);
351 		assertNoProblem(sources[0]);
352 
353 		// Store replacement info
354 		if (occurencePosition == 0) { // special case for completion on empty token...
355 			this.completionStart = this.cursorLocation;
356 		}
357 		int endPosition = this.cursorLocation;
358 		char ch = source.charAt(endPosition);
359 		if (Character.isJavaIdentifierPart(ch) || ch == '>' || ch == '}' || ch == '(' || ch == ')') {
360 			do {
361 				ch = source.charAt(++endPosition);
362 			} while (Character.isJavaIdentifierPart(ch) || ch == '>' || ch == '}' || ch == '(' || ch == ')');
363 		}
364 		this.positions = "["+this.completionStart+", "+endPosition+"], ";
365 	}
366 
367 	/* (non-Javadoc)
368 	 * @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#displayString(java.lang.String, int)
369 	 */
370 	@Override
displayString(String toPrint, int indent)371 	protected String displayString(String toPrint, int indent) {
372 		String toDisplay = super.displayString(toPrint, indent);
373 		int openBracket = toDisplay.indexOf(", [");
374 		if (openBracket > 0) {
375 			StringBuffer buffer = new StringBuffer();
376 			int closeBracket = 0;
377 			while (openBracket > 0) {
378 				buffer.append(toDisplay.substring(closeBracket, openBracket+2));
379 				closeBracket = toDisplay.indexOf("], ", openBracket+3);
380 				if (closeBracket < 0) break; // invalid
381 				closeBracket += 3;
382 				buffer.append("\"+this.positions+");
383 				int i=0;
384 				while (toDisplay.charAt(closeBracket+i) != '}') i++;
385 				try {
386 					int relevance = Integer.parseInt(toDisplay.substring(closeBracket, closeBracket+i));
387 					int length = RELEVANCES.length;
388 					boolean found = false;
389 					for (int r=0; !found && r<length; r++) {
390 						if (RELEVANCES[r] == relevance) {
391 							buffer.append(RELEVANCES_NAMES[r]);
392 							buffer.append("+\"");
393 							found = true;
394 						}
395 					}
396 					if (!found) {
397 						buffer.append('"');
398 						buffer.append(relevance);
399 					}
400 					closeBracket += i;
401 				}
402 				catch (NumberFormatException nfe) {
403 					System.err.println(nfe.getMessage()+" should not occur!");
404 				}
405 				openBracket = toDisplay.indexOf(", [", closeBracket);
406 			}
407 			if (closeBracket > 0) {
408 				buffer.append(toDisplay.substring(closeBracket, toDisplay.length()));
409 				toDisplay = buffer.toString();
410 			}
411 		}
412 		return toDisplay.replaceAll(", 8}", ", \"+JAVADOC_RELEVANCE+\"}");
413 	}
414 
setUpProjectOptions(String compliance)415 	protected void setUpProjectOptions(String compliance) throws JavaModelException {
416 		try {
417 			setUpProjectCompliance(COMPLETION_PROJECT, compliance);
418 		} catch (IOException e) {
419 			assertTrue("Unexpected IOException: "+e.getMessage(), false);
420 		}
421 	}
422 
423 	@Override
setUpSuite()424 	public void setUpSuite() throws Exception {
425 		super.setUpSuite();
426 		if (COMPLETION_PROJECT == null)  {
427 			COMPLETION_PROJECT = setUpJavaProject("Completion");
428 			createFolder(new Path("/Completion/src/javadoc/tags"));
429 		} else {
430 			setUpProjectCompliance(COMPLETION_PROJECT, "1.4");
431 			this.currentProject = COMPLETION_PROJECT;
432 		}
433 	}
434 
435 	/* (non-Javadoc)
436 	 * @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#tearDown()
437 	 */
438 	@Override
tearDown()439 	protected void tearDown() throws Exception {
440 		this.requestor = null;
441 		super.tearDown();
442 	}
443 
444 	@Override
tearDownSuite()445 	public void tearDownSuite() throws Exception {
446 		deleteFolder(new Path("/Completion/src/javadoc/tags"));
447 		super.tearDownSuite();
448 		if (COMPLETION_SUITES == null) {
449 			COMPLETION_PROJECT = null;
450 		}
451 	}
452 
453 	/*
454 	 * Write files for self-hosting debug.
455 	 */
writeFiles(String[] sources)456 	protected void writeFiles(String[] sources) {
457 
458 		// Get write directory path
459 		if (WRITE_DIR_FILE == null) return;
460 
461 		// Get test name
462 		String testName = getName();
463 		int idx = testName.indexOf(" - ");
464 		if (idx > 0) {
465 			testName = testName.substring(idx+3);
466 		}
467 //		testName = "Test"+testName.substring(4);
468 
469 		// Write sources to dir
470 		int length = sources.length / 2;
471 		String[][] names = new String[length][3];
472 		for (int i=0; i<length; i++) {
473 
474 			// Get pathes
475 			IPath filePath = new Path(sources[2*i]).removeFirstSegments(2); // remove project and source folder
476 			IPath dirPath = filePath.removeLastSegments(1);
477 			String fileDir = dirPath.toString();
478 			String typeName = filePath.removeFileExtension().lastSegment();
479 
480 			// Create package dir or delete files if already exist
481 			File packageDir = new File(WRITE_DIR_FILE, fileDir);
482 			if (!PACKAGE_FILES.contains(packageDir)) {
483 				if (packageDir.exists()) {
484 					PACKAGE_FILES.add(packageDir);
485 					Util.delete(packageDir);
486 				} else if (packageDir.mkdirs()) {
487 					PACKAGE_FILES.add(packageDir);
488 				} else {
489 					System.err.println(packageDir+" does not exist and CANNOT be created!!!");
490 					continue;
491 				}
492 			}
493 
494 			// Store names info
495 			names[i][0] = typeName;
496 			String fileName = (typeName.length() <= 3) ? typeName : typeName.substring(0, typeName.length()-3);
497 			fileName = fileName + testName.substring(4);
498 			names[i][1] = fileName;
499 			names[i][2] = packageDir.getAbsolutePath()+"\\"+fileName+".java";
500 		}
501 
502 		// Write modified contents
503 		for (int i=0; i<length; i++) {
504 			String contents = sources[2*i+1];
505 			for (int j=0; j<length; j++) {
506 				contents = contents.replaceAll(names[j][0], names[j][1]);
507 			}
508 			String fullPathName = names[i][2];
509 			System.out.println("Write file "+fullPathName);
510 			Util.writeToFile(contents, fullPathName);
511 		}
512 	}
513 }
514