KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > reorg > SourceRangeComputer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.refactoring.reorg;
12
13 import org.eclipse.jface.text.BadLocationException;
14 import org.eclipse.jface.text.Document;
15 import org.eclipse.jface.text.IDocument;
16 import org.eclipse.jface.text.IRegion;
17
18 import org.eclipse.jdt.core.IClassFile;
19 import org.eclipse.jdt.core.ICompilationUnit;
20 import org.eclipse.jdt.core.IJavaElement;
21 import org.eclipse.jdt.core.IMember;
22 import org.eclipse.jdt.core.ISourceRange;
23 import org.eclipse.jdt.core.ISourceReference;
24 import org.eclipse.jdt.core.JavaModelException;
25 import org.eclipse.jdt.core.ToolFactory;
26 import org.eclipse.jdt.core.compiler.IScanner;
27 import org.eclipse.jdt.core.compiler.ITerminalSymbols;
28 import org.eclipse.jdt.core.compiler.InvalidInputException;
29
30 import org.eclipse.jdt.internal.ui.JavaPlugin;
31
32 import org.eclipse.jdt.internal.corext.SourceRange;
33
34 /**
35  * Utility class used to get better source ranges for <code>ISourceReference</code>
36  * and temp declarations.
37  */

38 public class SourceRangeComputer {
39     
40     private final ISourceRange fSourceRange;
41     private final String JavaDoc fCuSource;
42     
43     private SourceRangeComputer(ISourceRange sourceRange, String JavaDoc cuSource){
44         fSourceRange= sourceRange;
45         fCuSource= cuSource;
46     }
47     
48     /**
49      * Returns the computed source of the elements.
50      * @see SourceRangeComputer#computeSourceRange(ISourceReference, String)
51      */

52     public static String JavaDoc computeSource(ISourceReference elem) throws JavaModelException{
53         String JavaDoc cuSource= getCuSource(elem);
54         ISourceRange range= SourceRangeComputer.computeSourceRange(elem, cuSource);
55         return cuSource.substring(range.getOffset(), range.getOffset() + range.getLength());
56     }
57
58     private static String JavaDoc getCuSource(ISourceReference elem) throws JavaModelException {
59         ICompilationUnit cu= SourceReferenceUtil.getCompilationUnit(elem);
60         if (cu != null && cu.exists()){
61             return cu.getSource();
62         } else if (elem instanceof IMember){
63             IMember member= (IMember)elem;
64             if (! member.isBinary())
65                 return null;
66             IClassFile classFile= (IClassFile)member.getAncestor(IJavaElement.CLASS_FILE);
67             if (classFile == null)
68                 return null;
69             return classFile.getSource();
70         }
71         return null;
72     }
73     
74     public static ISourceRange computeSourceRange(ISourceReference element, String JavaDoc cuSource) throws JavaModelException{
75             if (! element.exists())
76                 return element.getSourceRange();
77             if (cuSource == null)
78                 return element.getSourceRange();
79             return computeSourceRange(element.getSourceRange(), cuSource);
80     }
81     
82     public static ISourceRange computeSourceRange(ISourceRange sourceRange, String JavaDoc cuSource) {
83         SourceRangeComputer inst= new SourceRangeComputer(sourceRange, cuSource);
84         try {
85             int offset= inst.computeOffset();
86             int end= inst.computeEnd();
87             return new SourceRange(offset, (end - offset));
88         } catch (BadLocationException exception) {
89             // Should never happen
90
JavaPlugin.log(exception);
91         }
92         return null;
93     }
94
95     private int computeEnd() throws BadLocationException {
96         int end= fSourceRange.getOffset() + fSourceRange.getLength();
97         try{
98             IScanner scanner= ToolFactory.createScanner(true, true, false, true);
99             scanner.setSource(fCuSource.toCharArray());
100             scanner.resetTo(end, fCuSource.length() - 1);
101             IDocument document= new Document(fCuSource);
102             int startLine= document.getLineOfOffset(scanner.getCurrentTokenEndPosition() + 1);
103             
104             int token= scanner.getNextToken();
105             while (token != ITerminalSymbols.TokenNameEOF) {
106                 switch (token) {
107                     case ITerminalSymbols.TokenNameWHITESPACE:
108                         break;
109                     case ITerminalSymbols.TokenNameSEMICOLON:
110                         break;
111                     case ITerminalSymbols.TokenNameCOMMENT_LINE :
112                         if (startLine == document.getLineOfOffset(scanner.getCurrentTokenStartPosition() + 1))
113                             break;
114                         else
115                             return stopProcessing(end, scanner, document, startLine);
116                     case ITerminalSymbols.TokenNameCOMMENT_BLOCK :
117                         if (startLine == document.getLineOfOffset(scanner.getCurrentTokenStartPosition() + 1))
118                             break;
119                         else
120                             return stopProcessing(end, scanner, document, startLine);
121                     default:
122                         return stopProcessing(end, scanner, document, startLine);
123                 }
124                 token= scanner.getNextToken();
125             }
126             return end;//fallback
127
} catch (InvalidInputException e){
128             return end;//fallback
129
}
130     }
131
132     private int stopProcessing(int end, IScanner scanner, IDocument buff, int startLine) throws BadLocationException {
133         int currentTokenStartLine= buff.getLineOfOffset(scanner.getCurrentTokenStartPosition() + 1);
134         int currentTokenEndLine= buff.getLineOfOffset(scanner.getCurrentTokenEndPosition() + 1);
135         if (endOnCurrentTokenStart(startLine, currentTokenStartLine, currentTokenEndLine))
136             return scanner.getCurrentTokenEndPosition() - scanner.getCurrentTokenSource().length + 1;
137         IRegion tokenStartLine= buff.getLineInformation(currentTokenStartLine);
138         if (tokenStartLine != null)
139             return tokenStartLine.getOffset();
140         else
141             return end; //fallback
142
}
143
144     private boolean endOnCurrentTokenStart(int startLine, int currentTokenStartLine,int currentTokenEndLine) {
145         if (startLine == currentTokenEndLine)
146             return true;
147         return (startLine == currentTokenStartLine && currentTokenStartLine != currentTokenEndLine);
148     }
149     
150     private int computeOffset() throws BadLocationException {
151         int offset= fSourceRange.getOffset();
152         try{
153             IDocument document= new Document(fCuSource);
154             int lineOffset= document.getLineInformationOfOffset(offset).getOffset();
155             IScanner scanner= ToolFactory.createScanner(true, true, false, true);
156             scanner.setSource(document.get().toCharArray());
157             scanner.resetTo(lineOffset, document.getLength() - 1);
158             
159             int token= scanner.getNextToken();
160             while (token != ITerminalSymbols.TokenNameEOF) {
161                 switch (token) {
162                     case ITerminalSymbols.TokenNameWHITESPACE:
163                         break;
164                     case ITerminalSymbols.TokenNameSEMICOLON:
165                         break;
166                     default:
167                         if (scanner.getCurrentTokenStartPosition() == offset)
168                             return lineOffset;
169                         else
170                             return offset;
171                 }
172                 token= scanner.getNextToken();
173             }
174             return offset; //should never get here really
175
} catch (InvalidInputException e){
176             return offset;//fallback
177
}
178     }
179 }
180
181
Popular Tags