| /******************************************************************************* |
| * Copyright (c) 2000, 2007 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.wst.jsdt.core.tests.compiler.parser; |
| |
| import java.util.Locale; |
| |
| import org.eclipse.wst.jsdt.core.compiler.CharOperation; |
| import org.eclipse.wst.jsdt.internal.codeassist.select.SelectionParser; |
| import org.eclipse.wst.jsdt.internal.codeassist.select.SelectionScanner; |
| import org.eclipse.wst.jsdt.internal.compiler.CompilationResult; |
| import org.eclipse.wst.jsdt.internal.compiler.DefaultErrorHandlingPolicies; |
| import org.eclipse.wst.jsdt.internal.compiler.ast.AbstractMethodDeclaration; |
| import org.eclipse.wst.jsdt.internal.compiler.ast.ASTNode; |
| import org.eclipse.wst.jsdt.internal.compiler.ast.CompilationUnitDeclaration; |
| import org.eclipse.wst.jsdt.internal.compiler.ast.FieldDeclaration; |
| import org.eclipse.wst.jsdt.internal.compiler.ast.Initializer; |
| import org.eclipse.wst.jsdt.internal.compiler.ast.TypeDeclaration; |
| import org.eclipse.wst.jsdt.internal.compiler.batch.CompilationUnit; |
| import org.eclipse.wst.jsdt.internal.compiler.env.ICompilationUnit; |
| import org.eclipse.wst.jsdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.wst.jsdt.internal.compiler.problem.DefaultProblemFactory; |
| import org.eclipse.wst.jsdt.internal.compiler.problem.ProblemReporter; |
| |
| public class SelectionTest2 extends AbstractSelectionTest { |
| |
| public SelectionTest2(String testName) { |
| super(testName); |
| } |
| boolean thereWasAnNPE = false; |
| private class SpecialSelectionParser extends SelectionParser { |
| public SpecialSelectionParser(ProblemReporter problemReporter) { |
| super(problemReporter); |
| } |
| public void doNPEInParser(){ |
| this.stack = null; |
| } |
| } |
| |
| SpecialSelectionParser createParser(){ |
| CompilerOptions options = new CompilerOptions(getCompilerOptions()); |
| SpecialSelectionParser parser = |
| new SpecialSelectionParser( |
| new ProblemReporter( |
| DefaultErrorHandlingPolicies.proceedWithAllProblems(), |
| options, |
| new DefaultProblemFactory(Locale.getDefault()))); |
| return parser; |
| } |
| void checkMethodParse( |
| SelectionParser parser, |
| char[] source, |
| int selectionStart, |
| int selectionEnd, |
| String expectedSelection, |
| String expectedUnitToString, |
| String expectedSelectionIdentifier, |
| String expectedSelectedSource, |
| |
| String testName) { |
| |
| ICompilationUnit sourceUnit = new CompilationUnit(source, testName, null); |
| CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, 0); |
| |
| CompilationUnitDeclaration unit = parser.dietParse(sourceUnit, compilationResult, selectionStart, selectionEnd); |
| |
| ASTNode foundMethod = null; |
| if (unit.types != null) { |
| for (int i = 0; i < unit.types.length; i++) { |
| TypeDeclaration type = unit.types[i]; |
| ASTNode method = findMethod(type, selectionStart); |
| if (method != null) { |
| foundMethod = method; |
| break; |
| } |
| } |
| } |
| assertTrue("no method found at cursor location", foundMethod != null); |
| if (foundMethod instanceof AbstractMethodDeclaration) { |
| parser.parseBlockStatements((AbstractMethodDeclaration)foundMethod, unit); |
| } else { |
| TypeDeclaration type = (TypeDeclaration)foundMethod; |
| if (type.fields != null) { |
| for (int i = 0; i < type.fields.length; i++) { |
| FieldDeclaration field = type.fields[i]; |
| if (field instanceof Initializer && field.sourceStart <= selectionStart && selectionStart <= field.sourceEnd) { |
| parser.parseBlockStatements((Initializer)field, type, unit); |
| break; |
| } |
| } |
| } |
| } |
| |
| String computedUnitToString = unit.toString(); |
| //System.out.println(computedUnitToString); |
| //System.out.println(Util.displayString(computedUnitToString)); |
| //System.out.println(expectedUnitToString); |
| |
| String computedCompletion = parser.assistNode == null |
| ? NONE |
| : parser.assistNode.toString(); |
| assertEquals( |
| "invalid selection node-" + testName, |
| expectedSelection, |
| computedCompletion); |
| |
| assertEquals( |
| "invalid selection location-"+testName, |
| expectedUnitToString, |
| computedUnitToString); |
| |
| if (expectedSelectionIdentifier != null){ |
| char[] chars = ((SelectionScanner)parser.scanner).selectionIdentifier; |
| String computedSelectionIdentifier = chars == null ? NONE : new String(chars); |
| assertEquals( |
| "invalid selection identifier-" + testName, |
| expectedSelectionIdentifier, |
| computedSelectionIdentifier); |
| } |
| if (expectedSelectedSource != null){ |
| char[] chars = null; |
| if (parser.assistNode != null){ |
| chars = CharOperation.subarray( |
| parser.scanner.source, |
| parser.assistNode.sourceStart, |
| parser.assistNode.sourceEnd + 1); |
| } else { |
| if (parser.assistIdentifier() != null){ |
| if (((SelectionScanner)parser.scanner).selectionEnd |
| >= ((SelectionScanner)parser.scanner).selectionStart){ |
| chars = CharOperation.subarray( |
| parser.scanner.source, |
| ((SelectionScanner)parser.scanner).selectionStart, |
| ((SelectionScanner)parser.scanner).selectionEnd + 1); |
| } |
| } |
| } |
| String computedReplacedSource = chars == null ? NONE : new String(chars); |
| assertEquals( |
| "invalid replaced source-" + testName, |
| expectedSelectedSource, |
| computedReplacedSource); |
| } |
| } |
| /* |
| * http://dev.eclipse.org/bugs/show_bug.cgi?id=30946 |
| */ |
| public void testBug30946() { |
| final SpecialSelectionParser parser = createParser(); |
| Thread query = new Thread( |
| new Runnable(){ |
| public void run(){ |
| String str = |
| "public class A {\n" + |
| " void foo() {\n" + |
| " if (true) {\n" + |
| " if()\n" + |
| " switch (1) {\n" + |
| " case A.B:\n" + |
| " C d= (C) s;\n" + |
| " here\n" + |
| " }\n" + |
| " }\n" + |
| " }\n" + |
| "}n"; |
| |
| String selection = "here"; |
| |
| String expectedCompletionNodeToString = "<SelectOnName:here>"; |
| |
| String completionIdentifier = "here"; |
| String expectedUnitDisplayString = |
| "public class A {\n" + |
| " public A() {\n" + |
| " }\n" + |
| " void foo() {\n" + |
| " {\n" + |
| " {\n" + |
| " C d;\n" + |
| " <SelectOnName:here>;\n" + |
| " }\n" + |
| " }\n" + |
| " }\n" + |
| "}\n"; |
| String expectedReplacedSource = "here"; |
| String testName = "<inifinite loop test>"; |
| |
| int selectionStart = str.lastIndexOf(selection); |
| int selectionEnd = str.lastIndexOf(selection) + selection.length() - 1; |
| |
| try { |
| SelectionTest2.this.checkMethodParse( |
| parser, |
| str.toCharArray(), |
| selectionStart, |
| selectionEnd, |
| expectedCompletionNodeToString, |
| expectedUnitDisplayString, |
| completionIdentifier, |
| expectedReplacedSource, |
| testName); |
| } catch (NullPointerException e) { |
| SelectionTest2.this.thereWasAnNPE = true; |
| } |
| } |
| }); |
| |
| query.start(); |
| try { |
| Thread.sleep(500); |
| } catch (InterruptedException e) { |
| } |
| // force parser to stop |
| parser.doNPEInParser(); |
| try { |
| Thread.sleep(500); |
| } catch (InterruptedException e) { |
| } |
| assertTrue("there is an infinite loop", !thereWasAnNPE); |
| |
| } |
| } |