1 11 package org.eclipse.jdt.internal.ui.javaeditor.selectionactions; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.List ; 16 17 import org.eclipse.core.runtime.Assert; 18 19 import org.eclipse.jface.action.Action; 20 import org.eclipse.jface.text.ITextSelection; 21 22 import org.eclipse.ui.IEditorInput; 23 import org.eclipse.ui.PlatformUI; 24 import org.eclipse.ui.texteditor.IUpdate; 25 26 import org.eclipse.jdt.core.IInitializer; 27 import org.eclipse.jdt.core.IJavaElement; 28 import org.eclipse.jdt.core.IMember; 29 import org.eclipse.jdt.core.ISourceRange; 30 import org.eclipse.jdt.core.ISourceReference; 31 import org.eclipse.jdt.core.IType; 32 import org.eclipse.jdt.core.JavaModelException; 33 import org.eclipse.jdt.core.ToolFactory; 34 import org.eclipse.jdt.core.compiler.IScanner; 35 import org.eclipse.jdt.core.compiler.ITerminalSymbols; 36 import org.eclipse.jdt.core.compiler.InvalidInputException; 37 38 import org.eclipse.jdt.internal.corext.SourceRange; 39 40 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; 41 import org.eclipse.jdt.internal.ui.JavaPlugin; 42 import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput; 43 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; 44 45 public class GoToNextPreviousMemberAction extends Action implements IUpdate { 46 47 public static final String NEXT_MEMBER= "GoToNextMember"; public static final String PREVIOUS_MEMBER= "GoToPreviousMember"; private JavaEditor fEditor; 50 private boolean fIsGotoNext; 51 52 public static GoToNextPreviousMemberAction newGoToNextMemberAction(JavaEditor editor) { 53 String text= SelectionActionMessages.GotoNextMember_label; 54 return new GoToNextPreviousMemberAction(editor, text, true); 55 } 56 57 public static GoToNextPreviousMemberAction newGoToPreviousMemberAction(JavaEditor editor) { 58 String text= SelectionActionMessages.GotoPreviousMember_label; 59 return new GoToNextPreviousMemberAction(editor, text, false); 60 } 61 62 private GoToNextPreviousMemberAction(JavaEditor editor, String text, boolean isGotoNext) { 63 super(text); 64 Assert.isNotNull(editor); 65 fEditor= editor; 66 fIsGotoNext= isGotoNext; 67 update(); 68 if (isGotoNext) 69 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GOTO_NEXT_MEMBER_ACTION); 70 else 71 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GOTO_PREVIOUS_MEMBER_ACTION); 72 } 73 74 77 public GoToNextPreviousMemberAction(boolean isSelectNext) { 78 super(""); fIsGotoNext= isSelectNext; 80 } 81 82 public void update() { 83 boolean enabled= false; 84 ISourceReference ref= getSourceReference(); 85 if (ref != null) { 86 ISourceRange range; 87 try { 88 range= ref.getSourceRange(); 89 enabled= range != null && range.getLength() > 0; 90 } catch (JavaModelException e) { 91 } 93 } 94 setEnabled(enabled); 95 } 96 97 100 public final void run() { 101 ITextSelection selection= getTextSelection(); 102 ISourceRange newRange= getNewSelectionRange(createSourceRange(selection), null); 103 if (selection.getOffset() == newRange.getOffset() && selection.getLength() == newRange.getLength()) 105 return; 106 fEditor.selectAndReveal(newRange.getOffset(), newRange.getLength()); 107 } 108 109 private IType[] getTypes() throws JavaModelException { 110 IEditorInput input= fEditor.getEditorInput(); 111 if (input instanceof IClassFileEditorInput) { 112 return new IType[] { ((IClassFileEditorInput)input).getClassFile().getType() }; 113 } else { 114 return JavaPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(input).getAllTypes(); 115 } 116 } 117 118 private ISourceReference getSourceReference() { 119 IEditorInput input= fEditor.getEditorInput(); 120 if (input instanceof IClassFileEditorInput) { 121 return ((IClassFileEditorInput)input).getClassFile(); 122 } else { 123 return JavaPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(input); 124 } 125 } 126 127 private ITextSelection getTextSelection() { 128 return (ITextSelection)fEditor.getSelectionProvider().getSelection(); 129 } 130 131 public ISourceRange getNewSelectionRange(ISourceRange oldSourceRange, IType[] types) { 132 try{ 133 if (types == null) 134 types= getTypes(); 135 Integer [] offsetArray= createOffsetArray(types); 136 if (offsetArray.length == 0) 137 return oldSourceRange; 138 Arrays.sort(offsetArray); 139 Integer oldOffset= new Integer (oldSourceRange.getOffset()); 140 int index= Arrays.binarySearch(offsetArray, oldOffset); 141 142 if (fIsGotoNext) 143 return createNewSourceRange(getNextOffset(index, offsetArray, oldOffset)); 144 else 145 return createNewSourceRange(getPreviousOffset(index, offsetArray, oldOffset)); 146 147 } catch (JavaModelException e){ 148 JavaPlugin.log(e); return oldSourceRange; 150 } 151 } 152 153 private static Integer getPreviousOffset(int index, Integer [] offsetArray, Integer oldOffset) { 154 if (index == -1) 155 return oldOffset; 156 if (index == 0) 157 return offsetArray[0]; 158 if (index > 0) 159 return offsetArray[index - 1]; 160 Assert.isTrue(index < -1); 161 int absIndex= Math.abs(index); 162 return offsetArray[absIndex - 2]; 163 } 164 165 private static Integer getNextOffset(int index, Integer [] offsetArray, Integer oldOffset) { 166 if (index == -1) 167 return offsetArray[0]; 168 169 if (index == 0){ 170 if (offsetArray.length != 1) 171 return offsetArray[1]; 172 else 173 return offsetArray[0]; 174 } 175 if (index > 0){ 176 if (index == offsetArray.length - 1) 177 return oldOffset; 178 return offsetArray[index + 1]; 179 } 180 Assert.isTrue(index < -1); 181 int absIndex= Math.abs(index); 182 if (absIndex > offsetArray.length) 183 return oldOffset; 184 else 185 return offsetArray[absIndex - 1]; 186 } 187 188 private static ISourceRange createNewSourceRange(Integer offset){ 189 return new SourceRange(offset.intValue(), 0); 190 } 191 192 private static Integer [] createOffsetArray(IType[] types) throws JavaModelException { 193 List result= new ArrayList (); 194 for (int i= 0; i < types.length; i++) { 195 IType iType= types[i]; 196 addOffset(result, iType.getNameRange().getOffset()); 197 addOffset(result, iType.getSourceRange().getOffset() + iType.getSourceRange().getLength()); 198 addMemberOffsetList(result, iType.getMethods()); 199 addMemberOffsetList(result, iType.getFields()); 200 addMemberOffsetList(result, iType.getInitializers()); 201 } 202 return (Integer []) result.toArray(new Integer [result.size()]); 203 } 204 205 private static void addMemberOffsetList(List result, IMember[] members) throws JavaModelException { 206 for (int i= 0; i < members.length; i++) { 207 addOffset(result, getOffset(members[i])); 208 } 209 } 210 211 private static int getOffset(IMember iMember) throws JavaModelException { 212 if (iMember.getElementType() == IJavaElement.INITIALIZER) 214 return firstOpeningBraceOffset((IInitializer)iMember); 215 216 if (iMember.getNameRange() != null && iMember.getNameRange().getOffset() >= 0) 217 return iMember.getNameRange().getOffset(); 218 return iMember.getSourceRange().getOffset(); 219 } 220 221 private static int firstOpeningBraceOffset(IInitializer iInitializer) throws JavaModelException { 222 try { 223 IScanner scanner= ToolFactory.createScanner(false, false, false, false); 224 scanner.setSource(iInitializer.getSource().toCharArray()); 225 int token= scanner.getNextToken(); 226 while (token != ITerminalSymbols.TokenNameEOF && token != ITerminalSymbols.TokenNameLBRACE) 227 token= scanner.getNextToken(); 228 if (token == ITerminalSymbols.TokenNameLBRACE) 229 return iInitializer.getSourceRange().getOffset() + scanner.getCurrentTokenStartPosition() + scanner.getRawTokenSource().length; 230 return iInitializer.getSourceRange().getOffset(); 231 } catch (InvalidInputException e) { 232 return iInitializer.getSourceRange().getOffset(); 233 } 234 } 235 236 238 private static ISourceRange createSourceRange(ITextSelection ts) { 239 return new SourceRange(ts.getOffset(), ts.getLength()); 240 } 241 242 private static void addOffset(List result, int offset) { 243 if (offset >= 0) 244 result.add(new Integer (offset)); 245 } 246 } 247 | Popular Tags |