1 /*******************************************************************************
2 * Copyright (c) 2000, 2009 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.compiler.parser;
15
16 import java.util.Locale;
17
18 import org.eclipse.jdt.core.compiler.CharOperation;
19 import org.eclipse.jdt.internal.codeassist.select.SelectionParser;
20 import org.eclipse.jdt.internal.codeassist.select.SelectionScanner;
21 import org.eclipse.jdt.internal.compiler.CompilationResult;
22 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
23 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
24 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
25 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
26 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
27 import org.eclipse.jdt.internal.compiler.ast.Initializer;
28 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
29 import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
30 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
31 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
32 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
33 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
34
35 public class SelectionTest2 extends AbstractSelectionTest {
36
SelectionTest2(String testName)37 public SelectionTest2(String testName) {
38 super(testName);
39 }
40 boolean thereWasAnNPE = false;
41 class SpecialSelectionParser extends SelectionParser {
SpecialSelectionParser(ProblemReporter problemReporter)42 public SpecialSelectionParser(ProblemReporter problemReporter) {
43 super(problemReporter);
44 }
doNPEInParser()45 public void doNPEInParser(){
46 this.stack = null;
47 }
48 }
49
createParser()50 SpecialSelectionParser createParser(){
51 CompilerOptions options = new CompilerOptions(getCompilerOptions());
52 SpecialSelectionParser parser =
53 new SpecialSelectionParser(
54 new ProblemReporter(
55 DefaultErrorHandlingPolicies.proceedWithAllProblems(),
56 options,
57 new DefaultProblemFactory(Locale.getDefault())));
58 return parser;
59 }
checkMethodParse( SelectionParser parser, char[] source, int selectionStart, int selectionEnd, String expectedSelection, String expectedUnitToString, String expectedSelectionIdentifier, String expectedSelectedSource, String testName)60 void checkMethodParse(
61 SelectionParser parser,
62 char[] source,
63 int selectionStart,
64 int selectionEnd,
65 String expectedSelection,
66 String expectedUnitToString,
67 String expectedSelectionIdentifier,
68 String expectedSelectedSource,
69
70 String testName) {
71
72 ICompilationUnit sourceUnit = new CompilationUnit(source, testName, null);
73 CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, 0);
74
75 CompilationUnitDeclaration unit = parser.dietParse(sourceUnit, compilationResult, selectionStart, selectionEnd);
76
77 ASTNode foundMethod = null;
78 if (unit.types != null) {
79 for (int i = 0; i < unit.types.length; i++) {
80 TypeDeclaration type = unit.types[i];
81 ASTNode method = findMethod(type, selectionStart);
82 if (method != null) {
83 foundMethod = method;
84 break;
85 }
86 }
87 }
88 assertTrue("no method found at cursor location", foundMethod != null);
89 if (foundMethod instanceof AbstractMethodDeclaration) {
90 parser.parseBlockStatements((AbstractMethodDeclaration)foundMethod, unit);
91 } else {
92 TypeDeclaration type = (TypeDeclaration)foundMethod;
93 if (type.fields != null) {
94 for (int i = 0; i < type.fields.length; i++) {
95 FieldDeclaration field = type.fields[i];
96 if (field instanceof Initializer && field.sourceStart <= selectionStart && selectionStart <= field.sourceEnd) {
97 parser.parseBlockStatements((Initializer)field, type, unit);
98 break;
99 }
100 }
101 }
102 }
103
104 String computedUnitToString = unit.toString();
105 //System.out.println(computedUnitToString);
106 //System.out.println(Util.displayString(computedUnitToString));
107 //System.out.println(expectedUnitToString);
108
109 String computedCompletion = parser.assistNode == null
110 ? NONE
111 : parser.assistNode.toString();
112 assertEquals(
113 "invalid selection node-" + testName,
114 expectedSelection,
115 computedCompletion);
116
117 assertEquals(
118 "invalid selection location-"+testName,
119 expectedUnitToString,
120 computedUnitToString);
121
122 if (expectedSelectionIdentifier != null){
123 char[] chars = ((SelectionScanner)parser.scanner).selectionIdentifier;
124 String computedSelectionIdentifier = chars == null ? NONE : new String(chars);
125 assertEquals(
126 "invalid selection identifier-" + testName,
127 expectedSelectionIdentifier,
128 computedSelectionIdentifier);
129 }
130 if (expectedSelectedSource != null){
131 char[] chars = null;
132 if (parser.assistNode != null){
133 chars = CharOperation.subarray(
134 parser.scanner.source,
135 parser.assistNode.sourceStart,
136 parser.assistNode.sourceEnd + 1);
137 } else {
138 if (parser.assistIdentifier() != null){
139 if (((SelectionScanner)parser.scanner).selectionEnd
140 >= ((SelectionScanner)parser.scanner).selectionStart){
141 chars = CharOperation.subarray(
142 parser.scanner.source,
143 ((SelectionScanner)parser.scanner).selectionStart,
144 ((SelectionScanner)parser.scanner).selectionEnd + 1);
145 }
146 }
147 }
148 String computedReplacedSource = chars == null ? NONE : new String(chars);
149 assertEquals(
150 "invalid replaced source-" + testName,
151 expectedSelectedSource,
152 computedReplacedSource);
153 }
154 }
155 /*
156 * http://dev.eclipse.org/bugs/show_bug.cgi?id=30946
157 */
testBug30946()158 public void testBug30946() {
159 final SpecialSelectionParser parser = createParser();
160 Thread query = new Thread(
161 new Runnable(){
162 @Override
163 public void run(){
164 String str =
165 "public class A {\n" +
166 " void foo() {\n" +
167 " if (true) {\n" +
168 " if()\n" +
169 " switch (1) {\n" +
170 " case A.B:\n" +
171 " C d= (C) s;\n" +
172 " here\n" +
173 " }\n" +
174 " }\n" +
175 " }\n" +
176 "}n";
177
178 String selection = "here";
179
180 String expectedCompletionNodeToString = "<SelectOnName:here>";
181
182 String completionIdentifier = "here";
183 String expectedUnitDisplayString =
184 "public class A {\n" +
185 " public A() {\n" +
186 " }\n" +
187 " void foo() {\n" +
188 " {\n" +
189 " {\n" +
190 " C d;\n" +
191 " <SelectOnName:here>;\n" +
192 " }\n" +
193 " }\n" +
194 " }\n" +
195 "}\n";
196 String expectedReplacedSource = "here";
197 String testName = "<inifinite loop test>";
198
199 int selectionStart = str.lastIndexOf(selection);
200 int selectionEnd = str.lastIndexOf(selection) + selection.length() - 1;
201
202 try {
203 SelectionTest2.this.checkMethodParse(
204 parser,
205 str.toCharArray(),
206 selectionStart,
207 selectionEnd,
208 expectedCompletionNodeToString,
209 expectedUnitDisplayString,
210 completionIdentifier,
211 expectedReplacedSource,
212 testName);
213 } catch (NullPointerException e) {
214 SelectionTest2.this.thereWasAnNPE = true;
215 }
216 }
217 });
218
219 query.start();
220 try {
221 Thread.sleep(500);
222 } catch (InterruptedException e) {
223 }
224 // force parser to stop
225 parser.doNPEInParser();
226 try {
227 Thread.sleep(500);
228 } catch (InterruptedException e) {
229 }
230 assertTrue("there is an infinite loop", !this.thereWasAnNPE);
231
232 }
233 }
234