/******************************************************************************* * Copyright (c) 2005, 2016 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.text.tests; import java.util.Arrays; import java.util.Comparator; import org.eclipse.jdt.testplugin.JavaProjectHelper; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.ui.tests.core.ProjectTestSetup; import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder; import org.eclipse.jdt.internal.core.manipulation.search.IOccurrencesFinder.OccurrenceLocation; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Tests for the BreakContinueTargerFinder class. * * @since 3.2 */ public class BreakContinueTargetFinderTest extends TestCase{ private static final Class<BreakContinueTargetFinderTest> THIS= BreakContinueTargetFinderTest.class; public static Test suite() { return new ProjectTestSetup(new TestSuite(THIS)); } public static Test setUpTest(Test test) { return new ProjectTestSetup(test); } private ASTParser fParser; private BreakContinueTargetFinder fFinder; private IJavaProject fJProject1; private IPackageFragmentRoot fSourceFolder; /* * @see junit.framework.TestCase#setUp() */ @Override protected void setUp() throws Exception { fParser = ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL); fFinder= new BreakContinueTargetFinder(); fJProject1= ProjectTestSetup.getProject(); fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); } @Override protected void tearDown() throws Exception { JavaProjectHelper.clear(fJProject1, ProjectTestSetup.getDefaultClasspath()); } private OccurrenceLocation[] getHighlights(StringBuffer source, int offset, int length) throws Exception { CompilationUnit root = createCompilationUnit(source); String errorString = fFinder.initialize(root, offset, length); assertNull(errorString, errorString); return fFinder.getOccurrences(); } private CompilationUnit createCompilationUnit(StringBuffer source) throws JavaModelException { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); ICompilationUnit cu= pack1.createCompilationUnit("E.java", source.toString(), false, null); fParser.setSource(cu); return (CompilationUnit) fParser.createAST(null); } private void checkSelection(StringBuffer s, int offset, int length, OccurrenceLocation[] expected) throws Exception { OccurrenceLocation[] selectedNodes= getHighlights(s, offset, length); assertEquals("number of selections", expected.length, selectedNodes.length); sortByStartIndex(selectedNodes); sortByStartIndex(expected); for (int i= 0; i < selectedNodes.length; i++) { assertEquals(expected[i].getOffset(), selectedNodes[i].getOffset()); assertEquals(expected[i].getLength(), selectedNodes[i].getLength()); } } private void sortByStartIndex(OccurrenceLocation[] OccurrenceLocations) { Arrays.sort(OccurrenceLocations, new Comparator<OccurrenceLocation>() { @Override public int compare(OccurrenceLocation node0, OccurrenceLocation node1) { return node0.getOffset() - node1.getOffset(); } }); } //pattern must be found - otherwise it's assumed to be an error private OccurrenceLocation find(StringBuffer s, String pattern, int ithOccurrence) { if (ithOccurrence < 1) throw new IllegalStateException("ithOccurrence = " + ithOccurrence); return find(s, pattern, ithOccurrence, 0); } private OccurrenceLocation find(StringBuffer s, String pattern, int ithOccurrence, int startIdx) { if (startIdx < 0 || startIdx > s.length()) throw new IllegalStateException("startIdx = " + startIdx); int idx = s.indexOf(pattern, startIdx); if (idx == -1) throw new IllegalStateException("not found \"" + pattern + "\" in \"" + s.substring(startIdx)); if (ithOccurrence == 1) return new OccurrenceLocation(idx, pattern.length(), 0, ""); return find(s, pattern, ithOccurrence-1, idx+1); } public void testBreakFor() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" for (int i = 0; i < xs.length; i++) {\n"); s.append(" break;"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("break");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "for", 1), find(s, "}", 1) }; checkSelection(s, offset, length, ranges); } public void testBreakForeach() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" for (int i : xs){\n"); s.append(" break;"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("break");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "for", 1), find(s, "}", 1) }; checkSelection(s, offset, length, ranges); } public void testBreakWhile() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(boolean b){\n"); s.append(" while (b) {\n"); s.append(" System.err.println(b);\n"); s.append(" break;\n"); s.append(" }\n"); s.append(" }\n"); s.append("}"); int offset= 1 + s.indexOf("break");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "while", 1), find(s, "}", 1) }; checkSelection(s, offset, length, ranges); } public void testBreakDo() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(boolean b){\n"); s.append(" do {\n"); s.append(" System.err.println(b);\n"); s.append(" break;\n"); s.append(" } while(b);\n"); s.append(" }\n"); s.append("}"); int offset= 1 + s.indexOf("break");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "do", 1), find(s, ";", 3) }; checkSelection(s, offset, length, ranges); } public void testBreakSwitch() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int i){\n"); s.append(" switch (i){\n"); s.append(" case 1: System.err.println(i); break;\n"); s.append(" default:System.out.println(i);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("break");//middle of word int length= 2; OccurrenceLocation[] ranges= { find(s, "switch", 1), find(s, "}", 1) }; checkSelection(s, offset, length, ranges); } public void testLabeledBreakFor() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" bar: for (int i = 0; i < xs.length; i++) {\n"); s.append(" do{\n"); s.append(" break bar;"); s.append(" }while (xs != null);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("break");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "bar", 1), find(s, "}", 2) }; checkSelection(s, offset, length, ranges); } public void testLabeledBreakFor1() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" bar: for (int i = 0; i < xs.length; i++) {\n"); s.append(" baz: do{\n"); s.append(" break bar;"); s.append(" }while (xs != null);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 5 + s.indexOf("break");//after word int length= 0; OccurrenceLocation[] ranges= { find(s, "bar", 1), find(s, "}", 2) }; checkSelection(s, offset, length, ranges); } public void testBreakFor2() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" bar: for (int i = 0; i < xs.length; i++) {\n"); s.append(" baz: do{\n"); s.append(" break;"); s.append(" }while (xs != null);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= s.indexOf("break") + 2; // inside 'break' int length= 0; OccurrenceLocation[] ranges= { find(s, "baz", 1), find(s, ";", 4) }; checkSelection(s, offset, length, ranges); } public void testLabeledBreakIf() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" public static void main(String[] args) {\n"); s.append(" stay: if (true) {\n"); s.append(" for (int i= 0; i < 5; i++) {\n"); s.append(" System.out.println(i);\n"); s.append(" if (i == 3)\n"); s.append(" break stay;\n"); s.append(" }\n"); s.append(" System.out.println(\"after loop\");\n"); s.append(" return;\n"); s.append(" }\n"); s.append(" System.out.println(\"Stayed!\");\n"); s.append(" }\n"); s.append("}\n"); int offset= s.indexOf("break");//before word int length= 0; OccurrenceLocation[] ranges= { find(s, "stay", 1), find(s, "}", 2) }; checkSelection(s, offset, length, ranges); } public void testContinueFor() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" for (int i = 0; i < xs.length; i++) {\n"); s.append(" continue;"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("continue");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "for", 1) }; checkSelection(s, offset, length, ranges); } public void testContinueForeach() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" for (int i : xs){\n"); s.append(" continue;"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("continue");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "for", 1) }; checkSelection(s, offset, length, ranges); } public void testContinueWhile() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(boolean b){\n"); s.append(" while (b) {\n"); s.append(" System.err.println(b);\n"); s.append(" continue;\n"); s.append(" }\n"); s.append(" }\n"); s.append("}"); int offset= 1 + s.indexOf("continue");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "while", 1) }; checkSelection(s, offset, length, ranges); } public void testContinueDo() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(boolean b){\n"); s.append(" do {\n"); s.append(" System.err.println(b);\n"); s.append(" continue;\n"); s.append(" } while(b);\n"); s.append(" }\n"); s.append("}"); int offset= 1 + s.indexOf("continue");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "do", 1) }; checkSelection(s, offset, length, ranges); } //continue skips over switches public void testContinueSwitch() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int i){\n"); s.append(" do{\n"); s.append(" switch (i){\n"); s.append(" case 1: System.err.println(i); continue;\n"); s.append(" default:System.out.println(i);\n"); s.append(" }\n"); s.append(" }while(i != 9);\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("continue");//middle of word int length= 2; OccurrenceLocation[] ranges= { find(s, "do", 1) }; checkSelection(s, offset, length, ranges); } public void testLabeledContinueFor() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" bar: for (int i = 0; i < xs.length; i++) {\n"); s.append(" do{\n"); s.append(" continue bar;"); s.append(" }while (xs != null);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("continue");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "bar", 1) }; checkSelection(s, offset, length, ranges); } public void testLabeledContinueFor1() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" bar: for (int i = 0; i < xs.length; i++) {\n"); s.append(" baz: do{\n"); s.append(" continue bar;"); s.append(" }while (xs != null);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= 1 + s.indexOf("continue");//middle of word int length= 0; OccurrenceLocation[] ranges= { find(s, "bar", 1) }; checkSelection(s, offset, length, ranges); } public void testLabeledContinueFor2() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" bar: for (int i = 0; i < xs.length; i++) {\n"); s.append(" baz: do{\n"); s.append(" continue bar;"); s.append(" }while (xs != null);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= s.indexOf("continue bar;") + 1+ "continue ".length();//middle of label reference int length= 0; OccurrenceLocation[] ranges= { find(s, "bar", 1) }; checkSelection(s, offset, length, ranges); } public void testContinueFor2() throws Exception { StringBuffer s= new StringBuffer(); s.append("class A{\n"); s.append(" void foo(int[] xs){\n"); s.append(" bar: for (int i = 0; i < xs.length; i++) {\n"); s.append(" baz: do{\n"); s.append(" continue;"); s.append(" }while (xs != null);\n"); s.append(" }\n"); s.append(" }\n"); s.append("}\n"); int offset= s.indexOf("continue;") + 2; // inside 'continue' int length= 0; OccurrenceLocation[] ranges= { find(s, "baz", 1) }; checkSelection(s, offset, length, ranges); } }