KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > SortElementBuilder


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

11 package org.eclipse.jdt.internal.core;
12
13 import java.util.Comparator JavaDoc;
14 import java.util.Stack JavaDoc;
15
16 import org.eclipse.jdt.core.compiler.InvalidInputException;
17 import org.eclipse.jdt.core.dom.AST;
18 import org.eclipse.jdt.core.dom.ASTNode;
19 import org.eclipse.jdt.core.dom.FieldDeclaration;
20 import org.eclipse.jdt.core.dom.Initializer;
21 import org.eclipse.jdt.core.dom.MethodDeclaration;
22 import org.eclipse.jdt.core.dom.Name;
23 import org.eclipse.jdt.core.dom.PrimitiveType;
24 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
25 import org.eclipse.jdt.core.dom.Type;
26 import org.eclipse.jdt.core.dom.TypeDeclaration;
27 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
28 import org.eclipse.jdt.core.util.CompilationUnitSorter;
29 import org.eclipse.jdt.internal.compiler.SourceElementRequestorAdapter;
30 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
31 import org.eclipse.jdt.internal.compiler.env.IConstants;
32 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
33 import org.eclipse.jdt.internal.compiler.parser.Scanner;
34 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
35
36 /**
37  *
38  * @since 2.1
39  */

40 public class SortElementBuilder extends SourceElementRequestorAdapter {
41
42     abstract class SortElement extends SortJavaElement {
43         SortElement(int sourceStart, int modifiers) {
44             super(SortElementBuilder.this);
45             this.sourceStart = normalizeSourceStart(sourceStart);
46             modifiers &= ~IConstants.AccInterface; // remove AccInterface flags
47
modifiers &= CompilerModifiers.AccJustFlag;
48             this.modifiers = modifiers;
49             this.children_count = 0;
50         }
51
52         protected void setParameters(MethodDeclaration methodDeclaration, String JavaDoc[] parameterNames, String JavaDoc[] parameterTypes) {
53             for (int i = 0, max = parameterNames.length; i < max; i++) {
54                 String JavaDoc paramType = parameterTypes[i];
55                 SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
56                 singleVariableDeclaration.setName(ast.newSimpleName(parameterNames[i]));
57                 int indexOfArrayBrace;
58                 if (paramType.indexOf('.') != -1) {
59                     String JavaDoc[] typeParts = splitOn('.', paramType);
60                     int length = typeParts.length;
61                     indexOfArrayBrace = typeParts[length - 1].indexOf('[');
62                     if (indexOfArrayBrace != -1) {
63                         int dimensions = occurencesOf('[', typeParts[length - 1]);
64                         typeParts[length - 1] = typeParts[length - 1].substring(0, indexOfArrayBrace);
65                         String JavaDoc[] typeSubstrings = new String JavaDoc[length];
66                         for (int j = 0; j < length; j++) {
67                             typeSubstrings[j] = typeParts[j];
68                         }
69                         singleVariableDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newName(typeSubstrings)), dimensions));
70                     } else {
71                         String JavaDoc[] typeSubstrings = new String JavaDoc[length];
72                         for (int j = 0; j < length; j++) {
73                             typeSubstrings[j] = new String JavaDoc(typeParts[j]);
74                         }
75                         singleVariableDeclaration.setType(ast.newSimpleType(ast.newName(typeSubstrings)));
76                     }
77                 } else if ((indexOfArrayBrace = paramType.indexOf('[')) != -1) {
78                     int dimensions = occurencesOf('[', paramType);
79                     paramType = paramType.substring(0, indexOfArrayBrace);
80                     singleVariableDeclaration.setType(ast.newArrayType(newType(paramType), dimensions));
81                 } else {
82                     singleVariableDeclaration.setType(newType(paramType));
83                 }
84                 methodDeclaration.parameters().add(singleVariableDeclaration);
85             }
86         }
87             
88         protected String JavaDoc[] splitOn(char divider, String JavaDoc stringToSplit) {
89             int length = stringToSplit == null ? 0 : stringToSplit.length();
90             if (length == 0)
91                 return new String JavaDoc[] { stringToSplit };
92     
93             int wordCount = 1;
94             for (int i = 0; i < length; i++)
95                 if (stringToSplit.charAt(i) == divider)
96                     wordCount++;
97             String JavaDoc[] split = new String JavaDoc[wordCount];
98             int last = 0, currentWord = 0;
99             for (int i = 0; i < length; i++) {
100                 if (stringToSplit.charAt(i) == divider) {
101                     split[currentWord++] = stringToSplit.substring(last, i);
102                     last = i + 1;
103                 }
104             }
105             split[currentWord] = stringToSplit.substring(last, length);
106             return split;
107         }
108         
109         protected int occurencesOf(char toBeFound, String JavaDoc s) {
110             if (s == null) return 0;
111             int count = 0;
112             for (int i = 0, max = s.length(); i < max; i++)
113                 if (toBeFound == s.charAt(i))
114                     count++;
115             return count;
116         }
117         
118         protected Type newType(String JavaDoc typeSource) {
119             // check if type is a primitive type
120
scanner.setSource(typeSource.toCharArray());
121             scanner.resetTo(0, typeSource.length());
122             int token = 0;
123             try {
124                 token = scanner.getNextToken();
125             } catch(InvalidInputException e) {
126                 return null;
127             }
128             if (token == TerminalTokens.TokenNameIdentifier) {
129                 return ast.newSimpleType(ast.newSimpleName(typeSource));
130             } else {
131                 switch(token) {
132                     case TerminalTokens.TokenNameint :
133                         return ast.newPrimitiveType(PrimitiveType.INT);
134                     case TerminalTokens.TokenNamebyte :
135                         return ast.newPrimitiveType(PrimitiveType.BYTE);
136                     case TerminalTokens.TokenNameboolean :
137                         return ast.newPrimitiveType(PrimitiveType.BOOLEAN);
138                     case TerminalTokens.TokenNamechar :
139                         return ast.newPrimitiveType(PrimitiveType.CHAR);
140                     case TerminalTokens.TokenNamedouble :
141                         return ast.newPrimitiveType(PrimitiveType.DOUBLE);
142                     case TerminalTokens.TokenNamefloat :
143                         return ast.newPrimitiveType(PrimitiveType.FLOAT);
144                     case TerminalTokens.TokenNamelong :
145                         return ast.newPrimitiveType(PrimitiveType.LONG);
146                     case TerminalTokens.TokenNameshort :
147                         return ast.newPrimitiveType(PrimitiveType.SHORT);
148                     case TerminalTokens.TokenNamevoid :
149                         return ast.newPrimitiveType(PrimitiveType.VOID);
150                 }
151             }
152             return null;
153         }
154
155         abstract ASTNode convert();
156     }
157     
158     abstract class SortAbstractMethodDeclaration extends SortElement {
159
160         SortAbstractMethodDeclaration(int sourceStart, int modifiers, char[] name, char[][] parametersNames, char[][] parametersTypes, char[][] thrownExceptions) {
161             super(sourceStart, modifiers);
162             this.name = new String JavaDoc(name);
163             if (parametersNames != null) {
164                 int length = parametersNames.length;
165                 this.parametersNames = new String JavaDoc[length];
166                 this.parametersTypes = new String JavaDoc[length];
167                 for (int i = 0; i < length; i++) {
168                     this.parametersNames[i] = new String JavaDoc(parametersNames[i]);
169                     this.parametersTypes[i] = new String JavaDoc(parametersTypes[i]);
170                 }
171             }
172             if (thrownExceptions != null) {
173                 int length = thrownExceptions.length;
174                 this.thrownExceptions = new String JavaDoc[length];
175                 for (int i = 0; i < length; i++) {
176                     this.thrownExceptions[i] = new String JavaDoc(thrownExceptions[i]);
177                 }
178             }
179
180         }
181         public String JavaDoc decodeSignature() {
182             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
183             buffer.append("("); //$NON-NLS-1$
184
if (this.parametersNames != null) {
185                 int length = parametersNames.length;
186                 for (int i = 0; i < length - 1; i++) {
187                     buffer.append(parametersTypes[i] + " " + parametersNames[i] + ", "); //$NON-NLS-1$ //$NON-NLS-2$
188
}
189                 buffer.append(parametersTypes[length - 1] + " " + parametersNames[length - 1]); //$NON-NLS-1$
190
}
191             buffer.append(")"); //$NON-NLS-1$
192
return buffer.toString();
193         }
194
195         /**
196          * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
197          */

198         protected void generateSource(StringBuffer JavaDoc buffer) {
199             super.generateSource(buffer);
200             int length = this.children_count;
201             if (length != 0) {
202                 int start = this.sourceStart;
203                 int end = this.firstChildBeforeSorting.sourceStart - 1;
204
205                 for (int i = 0; i < length; i++) {
206                     buffer.append(SortElementBuilder.this.source, start, end - start + 1);
207                     this.children[i].generateSource(buffer);
208                     if (i < length - 1) {
209                         start = this.children[i].sourceEnd + 1;
210                     } else {
211                         start = this.lastChildBeforeSorting.sourceEnd + 1;
212                     }
213                     if (i < length - 1) {
214                         end = this.children[i + 1].sourceStart - 1;
215                     } else {
216                         end = this.sourceEnd;
217                     }
218                 }
219                 buffer.append(SortElementBuilder.this.source, start, end - start + 1);
220             } else {
221                 buffer.append(SortElementBuilder.this.source, this.sourceStart, this.sourceEnd - this.sourceStart + 1);
222             }
223         }
224
225         protected void mapPositions() {
226             int length = this.children_count;
227             if (length != 0) {
228                 int start = this.sourceStart;
229                 int end = this.firstChildBeforeSorting.sourceStart - 1;
230
231                 for (int i = 0; i < length; i++) {
232                     mapNextPosition(this, start, end);
233                     this.children[i].mapPositions();
234                     if (i < length - 1) {
235                         start = this.children[i].sourceEnd + 1;
236                     } else {
237                         start = this.lastChildBeforeSorting.sourceEnd + 1;
238                     }
239                     if (i < length - 1) {
240                         end = this.children[i + 1].sourceStart - 1;
241                     } else {
242                         end = this.sourceEnd;
243                     }
244                 }
245                 mapNextPosition(this, start, end);
246             } else {
247                 mapNextPosition(this, this.sourceStart, this.sourceEnd);
248             }
249         }
250     }
251     
252     class SortMethodDeclaration extends SortAbstractMethodDeclaration {
253         SortMethodDeclaration(int sourceStart, int modifiers, char[] name, char[][] parametersNames, char[][] parametersTypes, char[][] thrownExceptions, char[] returnType) {
254             super(sourceStart, modifiers, name, parametersNames, parametersTypes, thrownExceptions);
255             this.id = METHOD;
256             if (returnType != null) {
257                 this.returnType = new String JavaDoc(returnType);
258             }
259         }
260         
261         void display(StringBuffer JavaDoc buffer, int tab) {
262             buffer
263                 .append(tab(tab))
264                 .append("method ") //$NON-NLS-1$
265
.append(name)
266                 .append(decodeSignature());
267             if (returnType != null) {
268                 buffer.append(" " + returnType + LINE_SEPARATOR); //$NON-NLS-1$
269
} else {
270                 buffer.append(LINE_SEPARATOR); //$NON-NLS-1$
271
}
272         }
273         
274         ASTNode convert() {
275             MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
276             methodDeclaration.setConstructor(false);
277             methodDeclaration.setModifiers(this.modifiers);
278             methodDeclaration.setName(ast.newSimpleName(this.name));
279             methodDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer JavaDoc(this.sourceStart));
280             // set parameter names and types
281
if (this.parametersNames != null) {
282                 setParameters(methodDeclaration, this.parametersNames, this.parametersTypes);
283             }
284             // set thrown exceptions
285
if (this.thrownExceptions != null) {
286                 for (int j = 0, max2 = this.thrownExceptions.length; j < max2; j++) {
287                     String JavaDoc currentException = this.thrownExceptions[j];
288                     Name exceptionName;
289                     if (currentException.indexOf('.') == -1) {
290                         exceptionName = ast.newSimpleName(currentException);
291                     } else {
292                         exceptionName = ast.newName(splitOn('.', currentException));
293                     }
294                     methodDeclaration.thrownExceptions().add(exceptionName);
295                 }
296             }
297             // set return type
298
int indexOfArrayBrace;
299             String JavaDoc currentReturnType = this.returnType;
300             if (currentReturnType != null) {
301                 if (currentReturnType.indexOf('.') != -1) {
302                     String JavaDoc[] returnTypeSubstrings = splitOn('.', currentReturnType);
303                     int length = returnTypeSubstrings.length;
304                     indexOfArrayBrace = returnTypeSubstrings[length - 1].indexOf('[');
305                     if (indexOfArrayBrace != -1) {
306                         int dimensions = occurencesOf('[', returnTypeSubstrings[length - 1]);
307                         returnTypeSubstrings[length - 1] = returnTypeSubstrings[length - 1].substring(0, indexOfArrayBrace);
308                         methodDeclaration.setReturnType(ast.newArrayType(ast.newSimpleType(ast.newName(returnTypeSubstrings)), dimensions));
309                     } else {
310                         methodDeclaration.setReturnType(ast.newSimpleType(ast.newName(returnTypeSubstrings)));
311                     }
312                 } else if ((indexOfArrayBrace = currentReturnType.indexOf('[')) != -1) {
313                     int dimensions = occurencesOf('[', currentReturnType);
314                     currentReturnType = currentReturnType.substring(0, indexOfArrayBrace);
315                     methodDeclaration.setReturnType(ast.newArrayType(newType(currentReturnType), dimensions));
316                 } else {
317                     methodDeclaration.setReturnType(newType(currentReturnType));
318                 }
319             }
320             return methodDeclaration;
321         }
322     }
323
324     class SortConstructorDeclaration extends SortAbstractMethodDeclaration {
325         SortConstructorDeclaration(int sourceStart, int modifiers, char[] name, char[][] parametersNames, char[][] parametersTypes, char[][] thrownExceptions) {
326             super(sourceStart, modifiers, name, parametersNames, parametersTypes, thrownExceptions);
327             this.id = CONSTRUCTOR;
328         }
329
330         void display(StringBuffer JavaDoc buffer, int tab) {
331             buffer
332                 .append(tab(tab))
333                 .append("constructor ") //$NON-NLS-1$
334
.append(decodeSignature() + LINE_SEPARATOR);
335         }
336         
337         ASTNode convert() {
338             MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
339             methodDeclaration.setConstructor(true);
340             methodDeclaration.setModifiers(this.modifiers);
341             methodDeclaration.setName(ast.newSimpleName(this.name));
342             methodDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer JavaDoc(this.sourceStart));
343             // set parameter names and types
344
if (this.parametersNames != null) {
345                 setParameters(methodDeclaration, this.parametersNames, this.parametersTypes);
346             }
347             // set thrown exceptions
348
if (this.thrownExceptions != null) {
349                 for (int j = 0, max2 = this.thrownExceptions.length; j < max2; j++) {
350                     String JavaDoc currentException = this.thrownExceptions[j];
351                     Name exceptionName;
352                     if (currentException.indexOf('.') == -1) {
353                         exceptionName = ast.newSimpleName(currentException);
354                     } else {
355                         exceptionName = ast.newName(splitOn('.', currentException));
356                     }
357                     methodDeclaration.thrownExceptions().add(exceptionName);
358                 }
359             }
360             return methodDeclaration;
361         }
362     }
363     
364     public class SortFieldDeclaration extends SortElement {
365         int previousSourceEnd;
366
367         SortFieldDeclaration(int sourceStart, int modifiers, char[] type, char[] name, int nameSourceStart) {
368             super(sourceStart, modifiers);
369             this.declarationStart = sourceStart;
370             this.id = FIELD;
371             this.type = new String JavaDoc(type);
372             this.name = new String JavaDoc(name);
373             this.nameSourceStart = nameSourceStart;
374         }
375
376         void display(StringBuffer JavaDoc buffer, int tab) {
377             buffer
378                 .append(tab(tab))
379                 .append("field ") //$NON-NLS-1$
380
.append(type + " " + name + LINE_SEPARATOR); //$NON-NLS-1$
381
}
382         
383         ASTNode convert() {
384             VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
385             variableDeclarationFragment.setName(ast.newSimpleName(this.name));
386             FieldDeclaration fieldDeclaration = ast.newFieldDeclaration(variableDeclarationFragment);
387
388             String JavaDoc currentFieldType = this.type;
389             
390             int indexOfArrayBrace;
391             if (currentFieldType.indexOf('.') != -1) {
392                 String JavaDoc[] typeParts = splitOn('.', currentFieldType);
393                 int length = typeParts.length;
394                 indexOfArrayBrace = typeParts[length - 1].indexOf('[');
395                 if (indexOfArrayBrace != -1) {
396                     int dimensions = occurencesOf('[', typeParts[length - 1]);
397                     typeParts[length - 1] = typeParts[length - 1].substring(0, indexOfArrayBrace);
398                     fieldDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newName(typeParts)), dimensions));
399                 } else {
400                     fieldDeclaration.setType(ast.newSimpleType(ast.newName(typeParts)));
401                 }
402             } else if ((indexOfArrayBrace = currentFieldType.indexOf('[')) != -1) {
403                 int dimensions = occurencesOf('[', currentFieldType);
404                 currentFieldType = currentFieldType.substring(0, indexOfArrayBrace);
405                 fieldDeclaration.setType(ast.newArrayType(newType(currentFieldType), dimensions));
406             } else {
407                 fieldDeclaration.setType(newType(currentFieldType));
408             }
409             fieldDeclaration.setModifiers(this.modifiers);
410             fieldDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer JavaDoc(this.sourceStart));
411             return fieldDeclaration;
412         }
413         /**
414          * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
415          */

416         protected void generateSource(StringBuffer JavaDoc buffer) {
417             super.generateSource(buffer);
418             int length = this.children_count;
419             if (length != 0) {
420                 int start = this.sourceStart;
421                 int end = this.firstChildBeforeSorting.sourceStart - 1;
422
423                 for (int i = 0; i < length; i++) {
424                     buffer.append(SortElementBuilder.this.source, start, end - start + 1);
425                     this.children[i].generateSource(buffer);
426                     if (i < length - 1) {
427                         start = this.children[i].sourceEnd + 1;
428                     } else {
429                         start = this.lastChildBeforeSorting.sourceEnd + 1;
430                     }
431                     if (i < length - 1) {
432                         end = this.children[i + 1].sourceStart - 1;
433                     } else {
434                         end = this.declarationSourceEnd;
435                     }
436                 }
437                 buffer.append(SortElementBuilder.this.source, start, end - start + 1);
438             } else {
439                 buffer.append(SortElementBuilder.this.source, this.sourceStart, this.declarationSourceEnd - this.sourceStart + 1);
440             }
441         }
442         protected void generateReduceSource(StringBuffer JavaDoc buffer) {
443             int length = this.children_count;
444             if (length != 0) {
445                 int start = this.nameSourceStart;
446                 int end = this.firstChildBeforeSorting.sourceStart - 1;
447     
448                 for (int i = 0; i < length; i++) {
449                     buffer.append(SortElementBuilder.this.source, start, end - start + 1);
450                     this.children[i].generateSource(buffer);
451                     if (i < length - 1) {
452                         start = this.children[i].sourceEnd + 1;
453                     } else {
454                         start = this.lastChildBeforeSorting.sourceEnd + 1;
455                     }
456                     if (i < length - 1) {
457                         end = this.children[i + 1].sourceStart - 1;
458                     } else {
459                         end = this.sourceEnd;
460                     }
461                 }
462                 buffer.append(SortElementBuilder.this.source, start, end - start + 1);
463             } else {
464                 buffer.append(SortElementBuilder.this.source, this.nameSourceStart, this.sourceEnd - this.nameSourceStart + 1);
465             }
466         }
467         protected void mapReducedPositions() {
468             int length = this.children_count;
469             if (length != 0) {
470                 int start = this.nameSourceStart;
471                 int end = this.firstChildBeforeSorting.sourceStart - 1;
472                 mapNextPosition(this, start, end);
473                 for (int i = 0; i < length; i++) {
474                     this.children[i].mapPositions();
475                     if (i < length - 1) {
476                         start = this.children[i].sourceEnd + 1;
477                     } else {
478                         start = this.lastChildBeforeSorting.sourceEnd + 1;
479                     }
480                     if (i < length - 1) {
481                         end = this.children[i + 1].sourceStart - 1;
482                     } else {
483                         end = this.sourceEnd;
484                     }
485                 }
486                 mapNextPosition(this, start, end);
487             } else {
488                 mapNextPosition(this, this.nameSourceStart, this.sourceEnd);
489             }
490         }
491         
492         protected void mapPositions() {
493             int length = this.children_count;
494             if (length != 0) {
495                 int start = this.sourceStart;
496                 int end = this.firstChildBeforeSorting.sourceStart - 1;
497
498                 for (int i = 0; i < length; i++) {
499                     mapNextPosition(this, start, end);
500                     this.children[i].mapPositions();
501                     if (i < length - 1) {
502                         start = this.children[i].sourceEnd + 1;
503                     } else {
504                         start = this.lastChildBeforeSorting.sourceEnd + 1;
505                     }
506                     if (i < length - 1) {
507                         end = this.children[i + 1].sourceStart - 1;
508                     } else {
509                         end = this.declarationSourceEnd;
510                     }
511                 }
512                 mapNextPosition(this, start, end);
513             } else {
514                 mapNextPosition(this, this.sourceStart, this.declarationSourceEnd);
515             }
516         }
517     }
518     
519     class SortMultipleFieldDeclaration extends SortElement {
520         SortMultipleFieldDeclaration(SortFieldDeclaration fieldDeclaration) {
521             super(fieldDeclaration.declarationStart, fieldDeclaration.modifiers);
522             this.declarationStart = fieldDeclaration.declarationStart;
523             this.id = MULTIPLE_FIELD;
524             this.innerFields = new SortFieldDeclaration[1];
525             this.fieldCounter = 0;
526             this.innerFields[this.fieldCounter++] = fieldDeclaration;
527             this.type = fieldDeclaration.type;
528             this.sourceStart = fieldDeclaration.sourceStart;
529             fieldDeclaration.sourceEnd = fieldDeclaration.previousSourceEnd;
530         }
531         
532         void addField(SortFieldDeclaration fieldDeclaration) {
533             System.arraycopy(this.innerFields, 0, this.innerFields = new SortFieldDeclaration[this.fieldCounter + 1], 0, this.fieldCounter);
534             this.innerFields[this.fieldCounter++] = fieldDeclaration;
535             fieldDeclaration.sourceEnd = fieldDeclaration.previousSourceEnd;
536         }
537         
538         void display(StringBuffer JavaDoc buffer, int tab) {
539             buffer
540                 .append(tab(tab))
541                 .append("multiple fields ") //$NON-NLS-1$
542
.append(LINE_SEPARATOR);
543             if (this.innerFields != null) {
544                 buffer
545                     .append(tab(tab + 1))
546                     .append("INNER FIELDS ------------------------------" + LINE_SEPARATOR); //$NON-NLS-1$
547
for (int i = 0; i < this.fieldCounter; i++) {
548                     buffer.append(this.innerFields[i].toString(tab + 2));
549                     buffer.append(LINE_SEPARATOR);
550                 }
551             }
552         }
553
554         ASTNode convert() {
555             VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
556             variableDeclarationFragment.setName(ast.newSimpleName(this.innerFields[0].name));
557             FieldDeclaration fieldDeclaration = ast.newFieldDeclaration(variableDeclarationFragment);
558
559             for (int j = 1, max2 = this.innerFields.length; j < max2; j++) {
560                 VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment();
561                 fragment.setName(ast.newSimpleName(new String JavaDoc(this.innerFields[j].name)));
562             }
563             String JavaDoc currentFieldType = this.type;
564             
565             int indexOfArrayBrace;
566             if (currentFieldType.indexOf('.') != -1) {
567                 String JavaDoc[] typeParts = splitOn('.', currentFieldType);
568                 int length = typeParts.length;
569                 indexOfArrayBrace = typeParts[length - 1].indexOf('[');
570                 if (indexOfArrayBrace != -1) {
571                     int dimensions = occurencesOf('[', typeParts[length - 1]);
572                     typeParts[length - 1] = typeParts[length - 1].substring(0, indexOfArrayBrace);
573                     fieldDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newName(typeParts)), dimensions));
574                 } else {
575                     fieldDeclaration.setType(ast.newSimpleType(ast.newName(typeParts)));
576                 }
577             } else if ((indexOfArrayBrace = currentFieldType.indexOf('[')) != -1) {
578                 int dimensions = occurencesOf('[', currentFieldType);
579                 currentFieldType = currentFieldType.substring(0, indexOfArrayBrace);
580                 fieldDeclaration.setType(ast.newArrayType(newType(currentFieldType), dimensions));
581             } else {
582                 fieldDeclaration.setType(newType(currentFieldType));
583             }
584             fieldDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer JavaDoc(this.sourceStart));
585             fieldDeclaration.setModifiers(this.modifiers);
586             return fieldDeclaration;
587         }
588         /**
589          * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
590          */

591         protected void generateSource(StringBuffer JavaDoc buffer) {
592             super.generateSource(buffer);
593             int length = this.fieldCounter;
594             int start = this.innerFields[0].sourceStart;
595             int end = this.innerFields[0].nameSourceStart - 1;
596             buffer.append(SortElementBuilder.this.source, start, end - start + 1);
597             for (int i = 0; i < length; i++) {
598                 this.innerFields[i].newSourceStart = this.newSourceStart;
599                 this.innerFields[i].generateReduceSource(buffer);
600                 if (i < length - 1) {
601                     start = this.innerFields[i].sourceEnd + 1;
602                     end = this.innerFields[i + 1].nameSourceStart - 1;
603                     buffer.append(SortElementBuilder.this.source, start, end - start + 1);
604                 }
605             }
606             start = this.innerFields[length - 1].sourceEnd + 1;
607             end = this.innerFields[length - 1].declarationSourceEnd;
608             buffer.append(SortElementBuilder.this.source, start, end - start + 1);
609         }
610
611         protected void mapPositions() {
612             int length = this.fieldCounter;
613             int start = this.innerFields[0].sourceStart;
614             int end = this.innerFields[0].nameSourceStart - 1;
615             mapNextPosition(this, start, end);
616             for (int i = 0; i < length; i++) {
617                 this.innerFields[i].newSourceStart = this.newSourceStart;
618                 this.innerFields[i].mapReducedPositions();
619                 if (i < length - 1) {
620                     start = this.innerFields[i].sourceEnd + 1;
621                     end = this.innerFields[i + 1].nameSourceStart - 1;
622                     mapNextPosition(this, start, end);
623                 }
624             }
625             start = this.innerFields[length - 1].sourceEnd + 1;
626             end = this.innerFields[length - 1].declarationSourceEnd;
627             mapNextPosition(this, start, end);
628         }
629
630         protected void sort() {
631             for (int i = 0, max = this.fieldCounter; i < max; i++) {
632                 this.innerFields[i].sort();
633             }
634         }
635     }
636
637     class SortInitializer extends SortElement {
638         SortInitializer(int sourceStart, int modifiers) {
639             super(sourceStart, modifiers);
640             this.id = INITIALIZER;
641         }
642
643         void display(StringBuffer JavaDoc buffer, int tab) {
644             buffer
645                 .append(tab(tab))
646                 .append("initializer " + LINE_SEPARATOR); //$NON-NLS-1$
647
}
648         
649         ASTNode convert() {
650             Initializer initializer = ast.newInitializer();
651             initializer.setModifiers(this.modifiers);
652             initializer.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer JavaDoc(this.sourceStart));
653             return initializer;
654         }
655         /**
656          * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
657          */

658         protected void generateSource(StringBuffer JavaDoc buffer) {
659             super.generateSource(buffer);
660             int length = this.children_count;
661             if (length != 0) {
662                 int start = this.sourceStart;
663                 int end = this.firstChildBeforeSorting.sourceStart - 1;
664         
665                 for (int i = 0; i < length; i++) {
666                     buffer.append(SortElementBuilder.this.source, start, end - start + 1);
667                     this.children[i].generateSource(buffer);
668                     if (i < length - 1) {
669                         start = this.children[i].sourceEnd + 1;
670                     } else {
671                         start = this.lastChildBeforeSorting.sourceEnd + 1;
672                     }
673                     if (i < length - 1) {
674                         end = this.children[i + 1].sourceStart - 1;
675                     } else {
676                         end = this.sourceEnd;
677                     }
678                 }
679                 buffer.append(SortElementBuilder.this.source, start, end - start + 1);
680             } else {
681                 buffer.append(SortElementBuilder.this.source, this.sourceStart, this.sourceEnd - this.sourceStart + 1);
682             }
683         }
684
685         protected void mapPositions() {
686             int length = this.children_count;
687             if (length != 0) {
688                 int start = this.sourceStart;
689                 int end = this.firstChildBeforeSorting.sourceStart - 1;
690         
691                 for (int i = 0; i < length; i++) {
692                     mapNextPosition(this, start, end);
693                     this.children[i].mapPositions();
694                     if (i < length - 1) {
695                         start = this.children[i].sourceEnd + 1;
696                     } else {
697                         start = this.lastChildBeforeSorting.sourceEnd + 1;
698                     }
699                     if (i < length - 1) {
700                         end = this.children[i + 1].sourceStart - 1;
701                     } else {
702                         end = this.sourceEnd;
703                     }
704                 }
705                 mapNextPosition(this, start, end);
706             } else {
707                 mapNextPosition(this, this.sourceStart, this.sourceEnd);
708             }
709         }
710     }
711
712     class SortClassDeclaration extends SortType {
713         SortClassDeclaration(int sourceStart, int modifiers, char[] name, char[] superclass, char[][] superinterfaces) {
714             super(sourceStart, modifiers, name, superinterfaces);
715             this.id = CLASS | TYPE;
716             if (superclass != null) {
717                 this.superclass = new String JavaDoc(superclass);
718             }
719         }
720
721         void display(StringBuffer JavaDoc buffer, int tab) {
722             buffer
723                 .append(tab(tab))
724                 .append("class ") //$NON-NLS-1$
725
.append(this.name);
726             if (this.superclass != null) {
727                 buffer.append(" extends " + this.superclass); //$NON-NLS-1$
728
}
729             if (this.superInterfaces != null) {
730                 int length = this.superInterfaces.length;
731                 buffer.append(" implements "); //$NON-NLS-1$
732
for (int i = 0; i < length - 1; i++) {
733                     buffer.append(this.superInterfaces[i] + ", "); //$NON-NLS-1$
734
}
735                 buffer.append(this.superInterfaces[length - 1]);
736             }
737             buffer.append(LINE_SEPARATOR);
738         }
739         
740         ASTNode convert() {
741             TypeDeclaration typeDeclaration = ast.newTypeDeclaration();
742             typeDeclaration.setInterface(false);
743             typeDeclaration.setModifiers(this.modifiers);
744             typeDeclaration.setName(ast.newSimpleName(this.name));
745             // set superclass
746
if (this.superclass != null) {
747                 if (this.superclass.indexOf('.') == -1) {
748                     // the superclass is a simple name
749
typeDeclaration.setSuperclass(ast.newSimpleName(this.superclass));
750                 } else {
751                     // the superclass is a qualified name
752
String JavaDoc[] superclassNames = splitOn('.', this.superclass);
753                     typeDeclaration.setSuperclass(ast.newName(superclassNames));
754                 }
755             }
756             // set superinterfaces
757
if (this.superInterfaces != null) {
758                 for (int j = 0, max2 = this.superInterfaces.length; j < max2; j++) {
759                     String JavaDoc currentInterfaceName = this.superInterfaces[j];
760                     Name interfaceName;
761                     if (currentInterfaceName.indexOf('.') == -1) {
762                         // the superclass is a simple name
763
interfaceName = ast.newSimpleName(currentInterfaceName);
764                     } else {
765                         // the superclass is a qualified name
766
String JavaDoc[] interfaceNames = splitOn('.', currentInterfaceName);
767                         interfaceName = ast.newName(interfaceNames);
768                     }
769                     typeDeclaration.superInterfaces().add(interfaceName);
770                 }
771             }
772             typeDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer JavaDoc(this.sourceStart));
773             return typeDeclaration;
774         }
775     }
776
777     abstract class SortType extends SortElement {
778         SortType(int sourceStart, int modifier, char[] name, char[][] superinterfaces) {
779             super(sourceStart, modifier);
780             this.name = new String JavaDoc(name);
781             if (superinterfaces != null) {
782                 int length = superinterfaces.length;
783                 this.superInterfaces = new String JavaDoc[length];
784                 for (int i = 0; i < length; i++) {
785                     this.superInterfaces[i] = new String JavaDoc(superinterfaces[i]);
786                 }
787             }
788         }
789         /**
790          * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
791          */

792         protected void generateSource(StringBuffer JavaDoc buffer) {
793             super.generateSource(buffer);
794             int length = this.children_count;
795             int start = this.sourceStart;
796             if (length != 0) {
797                 int end = this.firstChildBeforeSorting.sourceStart;
798                 
799                 buffer.append(SortElementBuilder.this.source, start, end - start);
800                 for (int i = 0; i < length; i++) {
801                     ((SortElementBuilder.SortElement)this.astNodes[i].getProperty(CORRESPONDING_ELEMENT)).generateSource(buffer);
802                 }
803                 start = this.lastChildBeforeSorting.sourceEnd + 1;
804                 buffer.append(SortElementBuilder.this.source, start, this.sourceEnd - start + 1);
805             } else {
806                 buffer.append(SortElementBuilder.this.source, start, this.sourceEnd - start + 1);
807             }
808         }
809
810         protected void mapPositions() {
811             int length = this.children_count;
812             int start = this.sourceStart;
813             if (length != 0) {
814                 int end = this.firstChildBeforeSorting.sourceStart - 1;
815                 mapNextPosition(this, start, end);
816                 for (int i = 0; i < length; i++) {
817                     children[i].mapPositions();
818                 }
819                 start = this.lastChildBeforeSorting.sourceEnd + 1;
820                 mapNextPosition(this, start, this.sourceEnd);
821             } else {
822                 mapNextPosition(this, start, this.sourceEnd);
823             }
824         }
825     }
826     
827     class SortInterfaceDeclaration extends SortType {
828         SortInterfaceDeclaration(int sourceStart, int modifiers, char[] name, char[][] superinterfaces) {
829             super(sourceStart, modifiers, name, superinterfaces);
830             this.id = TYPE | INTERFACE;
831         }
832         void display(StringBuffer JavaDoc buffer, int tab) {
833             buffer
834                 .append(tab(tab))
835                 .append("interface ") //$NON-NLS-1$
836
.append(this.name);
837             if (this.superInterfaces != null) {
838                 int length = this.superInterfaces.length;
839                 buffer.append(" implements "); //$NON-NLS-1$
840
for (int i = 0; i < length - 1; i++) {
841                     buffer.append(this.superInterfaces[i] + ", "); //$NON-NLS-1$
842
}
843                 buffer.append(this.superInterfaces[length - 1]);
844             }
845             buffer.append(LINE_SEPARATOR);
846         }
847         ASTNode convert() {
848             TypeDeclaration typeDeclaration = ast.newTypeDeclaration();
849             typeDeclaration.setInterface(true);
850             typeDeclaration.setModifiers(this.modifiers);
851             typeDeclaration.setName(ast.newSimpleName(this.name));
852             // set superinterfaces
853
if (this.superInterfaces != null) {
854                 for (int j = 0, max2 = this.superInterfaces.length; j < max2; j++) {
855                     String JavaDoc currentInterfaceName = this.superInterfaces[j];
856                     Name interfaceName;
857                     if (currentInterfaceName.indexOf('.') == -1) {
858                         // the superclass is a simple name
859
interfaceName = ast.newSimpleName(currentInterfaceName);
860                     } else {
861                         // the superclass is a qualified name
862
String JavaDoc[] interfaceNames = splitOn('.', currentInterfaceName);
863                         interfaceName = ast.newName(interfaceNames);
864                     }
865                     typeDeclaration.superInterfaces().add(interfaceName);
866                 }
867             }
868             typeDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer JavaDoc(this.sourceStart));
869             return typeDeclaration;
870         }
871     }
872     
873     class SortCompilationUnit extends SortElement {
874         SortCompilationUnit(int sourceStart) {
875             super(sourceStart, 0);
876             this.id = COMPILATION_UNIT;
877         }
878         void display(StringBuffer JavaDoc buffer, int tab) {
879             // nothing to do
880
}
881         
882         ASTNode convert() {
883             return ast.newCompilationUnit();
884         }
885         /**
886          * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
887          */

888         protected void generateSource(StringBuffer JavaDoc buffer) {
889             super.generateSource(buffer);
890             int length = this.children_count;
891             if (length != 0) {
892                 int end = this.firstChildBeforeSorting.sourceStart;
893                 int start = this.lastChildBeforeSorting.sourceEnd + 1;
894                 buffer.append(SortElementBuilder.this.source, 0, end);
895                 for (int i = 0; i < length; i++) {
896                     ((SortElementBuilder.SortElement)this.astNodes[i].getProperty(CORRESPONDING_ELEMENT)).generateSource(buffer);
897                 }
898                 buffer.append(SortElementBuilder.this.source, start, this.sourceEnd - start + 1);
899             }
900         }
901
902         protected void mapPositions() {
903             int length = this.children_count;
904             if (length != 0) {
905                 int end = this.firstChildBeforeSorting.sourceStart;
906                 int start = this.lastChildBeforeSorting.sourceEnd + 1;
907                 mapNextPosition(this, 0, end);
908                 for (int i = 0; i < length; i++) {
909                     children[i].mapPositions();
910                 }
911                 mapNextPosition(this, start, this.sourceEnd);
912             } else {
913                 mapNextPosition(this, this.sourceStart, this.sourceEnd);
914             }
915         }
916     }
917
918     SortElement currentElement;
919     Stack JavaDoc stack;
920     SortCompilationUnit compilationUnit;
921     Scanner scanner;
922     AST ast;
923
924     char[] source;
925     int[] lineEnds;
926     Comparator JavaDoc comparator;
927     int[] positionsToMap;
928     int positionsToMapIndex;
929     
930     public SortElementBuilder(char[] source, int[] positionsToMap, Comparator JavaDoc comparator) {
931         this.source = source;
932         this.comparator = comparator;
933         this.positionsToMap = positionsToMap;
934         this.scanner = new Scanner(false, false, false, ClassFileConstants.JDK1_3/*sourceLevel*/, null, null, true/*taskCaseSensitive*/);
935         this.ast = AST.newAST(AST.JLS2);
936     }
937     
938     /*
939      * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[])
940      */

941     public void acceptLineSeparatorPositions(int[] positions) {
942         this.lineEnds = positions;
943     }
944         
945     public String JavaDoc getSource() {
946         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
947         this.positionsToMapIndex = 0;
948         this.compilationUnit.generateSource(buffer);
949         if (this.positionsToMap != null) {
950             this.compilationUnit.mapPositions();
951         }
952         return buffer.toString();
953     }
954
955     private static int searchLineNumber(
956         int[] startLineIndexes,
957         int position) {
958         // this code is completely useless, but it is the same implementation than
959
// org.eclipse.jdt.internal.compiler.problem.ProblemHandler.searchLineNumber(int[], int)
960
// if (startLineIndexes == null)
961
// return 1;
962
int length = startLineIndexes.length;
963         if (length == 0)
964             return 1;
965         int g = 0, d = length - 1;
966         int m = 0;
967         while (g <= d) {
968             m = (g + d) / 2;
969             if (position < startLineIndexes[m]) {
970                 d = m - 1;
971             } else
972                 if (position > startLineIndexes[m]) {
973                     g = m + 1;
974                 } else {
975                     return m + 1;
976                 }
977         }
978         if (position < startLineIndexes[m]) {
979             return m + 1;
980         }
981         return m + 2;
982     }
983     
984     void sort() {
985         this.compilationUnit.sort();
986     }
987
988     void mapNextPosition(SortJavaElement node, int start, int end) {
989         int i = this.positionsToMapIndex;
990         for (; i < this.positionsToMap.length; i++) {
991             int nextPosition = this.positionsToMap[i];
992             if (nextPosition >= start
993                 && nextPosition <= end) {
994                     this.positionsToMap[i] += (node.newSourceStart - node.sourceStart);
995                 } else {
996                     break;
997                 }
998         }
999         this.positionsToMapIndex = i;
1000    }
1001    /**
1002     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterClass(int, int, char[], int, int, char[], char[][])
1003     */

1004    public void enterClass(
1005        int declarationStart,
1006        int modifiers,
1007        char[] name,
1008        int nameSourceStart,
1009        int nameSourceEnd,
1010        char[] superclass,
1011        char[][] superinterfaces) {
1012            SortType type = new SortClassDeclaration(declarationStart, modifiers, name, superclass, superinterfaces);
1013            this.currentElement.addChild(type);
1014            push(type);
1015    }
1016
1017    /**
1018     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterCompilationUnit()
1019     */

1020    public void enterCompilationUnit() {
1021        this.stack = new Stack JavaDoc();
1022        push(this.compilationUnit = new SortCompilationUnit(0));
1023    }
1024
1025    /**
1026     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterConstructor(int, int, char[], int, int, char[][], char[][], char[][])
1027     */

1028    public void enterConstructor(
1029        int declarationStart,
1030        int modifiers,
1031        char[] name,
1032        int nameSourceStart,
1033        int nameSourceEnd,
1034        char[][] parameterTypes,
1035        char[][] parameterNames,
1036        char[][] exceptionTypes) {
1037        if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
1038            SortConstructorDeclaration constructorDeclaration = new SortConstructorDeclaration(declarationStart, modifiers, name, parameterNames, parameterTypes, exceptionTypes);
1039            this.currentElement.addChild(constructorDeclaration);
1040            push(constructorDeclaration);
1041        }
1042    }
1043
1044    /**
1045     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterField(int, int, char[], char[], int, int)
1046     */

1047    public void enterField(
1048        int declarationStart,
1049        int modifiers,
1050        char[] type,
1051        char[] name,
1052        int nameSourceStart,
1053        int nameSourceEnd) {
1054            if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
1055                SortFieldDeclaration fieldDeclaration = new SortFieldDeclaration(declarationStart, modifiers, type, name, nameSourceStart);
1056                SortElement[] currentElementChildren = this.currentElement.children;
1057                if (currentElementChildren != null) {
1058                    SortElement previousElement = this.currentElement.children[this.currentElement.children_count - 1];
1059                    if (previousElement.id == SortJavaElement.FIELD && ((SortFieldDeclaration) previousElement).declarationStart == declarationStart) {
1060                        SortMultipleFieldDeclaration multipleFielDeclaration = new SortMultipleFieldDeclaration((SortFieldDeclaration) previousElement);
1061                        multipleFielDeclaration.addField(fieldDeclaration);
1062                        this.currentElement.children[this.currentElement.children_count - 1] = multipleFielDeclaration;
1063                    } else if (previousElement.id == SortJavaElement.MULTIPLE_FIELD && ((SortMultipleFieldDeclaration) previousElement).declarationStart == declarationStart) {
1064                        ((SortMultipleFieldDeclaration) previousElement).addField(fieldDeclaration);
1065                    } else {
1066                        this.currentElement.addChild(fieldDeclaration);
1067                    }
1068                } else {
1069                    this.currentElement.addChild(fieldDeclaration);
1070                }
1071                push(fieldDeclaration);
1072            }
1073    }
1074
1075    /**
1076     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterInitializer(int, int)
1077     */

1078    public void enterInitializer(int declarationStart, int modifiers) {
1079        if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
1080            SortInitializer initializer = new SortInitializer(declarationStart, modifiers);
1081            this.currentElement.addChild(initializer);
1082            push(initializer);
1083        }
1084    }
1085
1086    /**
1087     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterInterface(int, int, char[], int, int, char[][])
1088     */

1089    public void enterInterface(
1090        int declarationStart,
1091        int modifiers,
1092        char[] name,
1093        int nameSourceStart,
1094        int nameSourceEnd,
1095        char[][] superinterfaces) {
1096            SortType type = new SortInterfaceDeclaration(declarationStart, modifiers, name, superinterfaces);
1097            this.currentElement.addChild(type);
1098            push(type);
1099    }
1100
1101    /**
1102     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterMethod(int, int, char[], char[], int, int, char[][], char[][], char[][])
1103     */

1104    public void enterMethod(
1105        int declarationStart,
1106        int modifiers,
1107        char[] returnType,
1108        char[] name,
1109        int nameSourceStart,
1110        int nameSourceEnd,
1111        char[][] parameterTypes,
1112        char[][] parameterNames,
1113        char[][] exceptionTypes) {
1114            if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
1115                SortMethodDeclaration methodDeclaration = new SortMethodDeclaration(declarationStart, modifiers, name, parameterNames, parameterTypes, exceptionTypes, returnType);
1116                this.currentElement.addChild(methodDeclaration);
1117                push(methodDeclaration);
1118            }
1119    }
1120
1121    /**
1122     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitClass(int)
1123     */

1124    public void exitClass(int declarationEnd) {
1125        pop(declarationEnd);
1126    }
1127
1128    /**
1129     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitCompilationUnit(int)
1130     */

1131    public void exitCompilationUnit(int declarationEnd) {
1132        pop(declarationEnd);
1133        sort();
1134    }
1135
1136    /**
1137     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitConstructor(int)
1138     */

1139    public void exitConstructor(int declarationEnd) {
1140        pop(declarationEnd);
1141    }
1142
1143    /**
1144     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitField(int, int, int)
1145     */

1146    public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
1147        int normalizedDeclarationSourceEnd = this.normalizeSourceEnd(declarationSourceEnd);
1148        if (this.currentElement.id == SortJavaElement.FIELD) {
1149            SortFieldDeclaration fieldDeclaration = (SortFieldDeclaration) this.currentElement;
1150            fieldDeclaration.declarationSourceEnd = normalizedDeclarationSourceEnd;
1151        }
1152        pop(declarationEnd);
1153        if (this.currentElement.children != null) {
1154            SortElement element = this.currentElement.children[this.currentElement.children_count - 1];
1155            switch(element.id) {
1156                case SortJavaElement.MULTIPLE_FIELD :
1157                    SortMultipleFieldDeclaration multipleFielDeclaration = (SortMultipleFieldDeclaration) element;
1158                    multipleFielDeclaration.innerFields[multipleFielDeclaration.fieldCounter - 1].declarationSourceEnd = normalizedDeclarationSourceEnd;
1159                    multipleFielDeclaration.sourceEnd = normalizedDeclarationSourceEnd;
1160                    break;
1161                case SortJavaElement.FIELD :
1162                    SortFieldDeclaration fieldDeclaration = (SortFieldDeclaration) element;
1163                    /*
1164                     * we will revert to the previous source end in case this field is
1165                     * part of a multiple field declaration
1166                     */

1167                    fieldDeclaration.previousSourceEnd = fieldDeclaration.sourceEnd;
1168                    fieldDeclaration.sourceEnd = normalizedDeclarationSourceEnd;
1169            }
1170        }
1171    }
1172
1173    /**
1174     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitInitializer(int)
1175     */

1176    public void exitInitializer(int declarationEnd) {
1177        pop(declarationEnd);
1178    }
1179
1180    /**
1181     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitInterface(int)
1182     */

1183    public void exitInterface(int declarationEnd) {
1184        pop(declarationEnd);
1185    }
1186
1187    /**
1188     * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitMethod(int)
1189     */

1190    public void exitMethod(int declarationEnd) {
1191        pop(declarationEnd);
1192    }
1193
1194    final int normalizeSourceStart(int position) {
1195        if (position == 0) {
1196            return 0;
1197        }
1198        int index = position - 1;
1199        while(index >= 0 && Character.isWhitespace(this.source[index])) {
1200            index--;
1201        }
1202        
1203        int originalLineNumber = searchLineNumber(this.lineEnds, position);
1204        int newLineNumber = searchLineNumber(this.lineEnds, index);
1205        
1206        if (originalLineNumber == newLineNumber) {
1207            return index + 1;
1208        } else {
1209            return this.lineEnds[newLineNumber - 1] + 1;
1210        }
1211    }
1212
1213    final int normalizeSourceEnd(int position) {
1214        int lineNumber = searchLineNumber(this.lineEnds, position);
1215        if (lineNumber == 1) {
1216            return position;
1217        }
1218        int normalizeSourceEnd = 0;
1219        if (lineNumber - 1 >= this.lineEnds.length) {
1220            normalizeSourceEnd = this.source.length - 1;
1221        } else {
1222            normalizeSourceEnd = this.lineEnds[lineNumber - 1];
1223        }
1224        int index = position + 1;
1225        while (index < normalizeSourceEnd && Character.isWhitespace(this.source[index])) {
1226            index++;
1227        }
1228        if (index == normalizeSourceEnd) {
1229            return normalizeSourceEnd;
1230        } else {
1231            return position;
1232        }
1233    }
1234    
1235    private void pop(int declarationEnd) {
1236        this.currentElement.sourceEnd = normalizeSourceEnd(declarationEnd);
1237        this.currentElement.closeCollections();
1238        this.stack.pop();
1239        if (!this.stack.isEmpty()) {
1240            this.currentElement = (SortElement) this.stack.peek();
1241        }
1242    }
1243    
1244    private void push(SortElement sortElement) {
1245        this.currentElement = sortElement;
1246        this.stack.push(sortElement);
1247    }
1248}
1249
Popular Tags