KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > parser > diagnose > RangeUtil


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.compiler.parser.diagnose;
12
13 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
14 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
15 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
16 import org.eclipse.jdt.internal.compiler.ast.Initializer;
17 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
18 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
19
20 public class RangeUtil {
21     
22     // flags
23
public static final int NO_FLAG = 0;
24     public static final int LBRACE_MISSING = 1;
25     public static final int IGNORE = 2;
26     
27     static class RangeResult {
28         private static final int INITIAL_SIZE = 10;
29         int pos;
30         int[] intervalStarts;
31         int[] intervalEnds;
32         int[] intervalFlags;
33         
34         RangeResult() {
35             this.pos = 0;
36             this.intervalStarts = new int[INITIAL_SIZE];
37             this.intervalEnds = new int[INITIAL_SIZE];
38             this.intervalFlags = new int[INITIAL_SIZE];
39         }
40         
41         void addInterval(int start, int end){
42             addInterval(start, end, NO_FLAG);
43         }
44         
45         void addInterval(int start, int end, int flags){
46             if(pos >= intervalStarts.length) {
47                 System.arraycopy(intervalStarts, 0, intervalStarts = new int[pos * 2], 0, pos);
48                 System.arraycopy(intervalEnds, 0, intervalEnds = new int[pos * 2], 0, pos);
49                 System.arraycopy(intervalFlags, 0, intervalFlags = new int[pos * 2], 0, pos);
50             }
51             intervalStarts[pos] = start;
52             intervalEnds[pos] = end;
53             intervalFlags[pos] = flags;
54             pos++;
55         }
56         
57         int[][] getRanges() {
58             int[] resultStarts = new int[pos];
59             int[] resultEnds = new int[pos];
60             int[] resultFlags = new int[pos];
61             
62             System.arraycopy(intervalStarts, 0, resultStarts, 0, pos);
63             System.arraycopy(intervalEnds, 0, resultEnds, 0, pos);
64             System.arraycopy(intervalFlags, 0, resultFlags, 0, pos);
65
66             if (resultStarts.length > 1) {
67                 quickSort(resultStarts, resultEnds, resultFlags, 0, resultStarts.length - 1);
68             }
69             return new int[][]{resultStarts, resultEnds, resultFlags};
70         }
71         
72         private void quickSort(int[] list, int[] list2, int[] list3, int left, int right) {
73             int original_left= left;
74             int original_right= right;
75             int mid= list[left + (right - left) / 2];
76             do {
77                 while (compare(list[left], mid) < 0) {
78                     left++;
79                 }
80                 while (compare(mid, list[right]) < 0) {
81                     right--;
82                 }
83                 if (left <= right) {
84                     int tmp= list[left];
85                     list[left]= list[right];
86                     list[right]= tmp;
87                     
88                     tmp = list2[left];
89                     list2[left]= list2[right];
90                     list2[right]= tmp;
91                     
92                     tmp = list3[left];
93                     list3[left]= list3[right];
94                     list3[right]= tmp;
95                     
96                     left++;
97                     right--;
98                 }
99             } while (left <= right);
100             
101             if (original_left < right) {
102                 quickSort(list, list2, list3, original_left, right);
103             }
104             if (left < original_right) {
105                 quickSort(list, list2, list3, left, original_right);
106             }
107         }
108         
109         private int compare(int i1, int i2) {
110             return i1 - i2;
111         }
112     }
113     
114     
115     
116     public static boolean containsErrorInSignature(AbstractMethodDeclaration method){
117         return method.sourceEnd + 1 == method.bodyStart || method.bodyEnd == method.declarationSourceEnd;
118     }
119
120     public static int[][] computeDietRange(TypeDeclaration[] types) {
121         if(types == null || types.length == 0) {
122             return new int[3][0];
123         } else {
124             RangeResult result = new RangeResult();
125             computeDietRange0(types, result);
126             return result.getRanges();
127         }
128     }
129     
130     private static void computeDietRange0(TypeDeclaration[] types, RangeResult result) {
131         for (int j = 0; j < types.length; j++) {
132             //members
133
TypeDeclaration[] memberTypeDeclarations = types[j].memberTypes;
134             if(memberTypeDeclarations != null && memberTypeDeclarations.length > 0) {
135                 computeDietRange0(types[j].memberTypes, result);
136             }
137             //methods
138
AbstractMethodDeclaration[] methods = types[j].methods;
139             if (methods != null) {
140                 int length = methods.length;
141                 for (int i = 0; i < length; i++) {
142                     AbstractMethodDeclaration method = methods[i];
143                     if(containsIgnoredBody(method)) {
144                         if(containsErrorInSignature(method)) {
145                             method.bits |= ASTNode.ErrorInSignature;
146                             result.addInterval(method.declarationSourceStart, method.declarationSourceEnd, IGNORE);
147                         } else {
148                             int flags = method.sourceEnd + 1 == method.bodyStart ? LBRACE_MISSING : NO_FLAG;
149                             result.addInterval(method.bodyStart, method.bodyEnd, flags);
150                         }
151                     }
152                 }
153             }
154     
155             //initializers
156
FieldDeclaration[] fields = types[j].fields;
157             if (fields != null) {
158                 int length = fields.length;
159                 for (int i = 0; i < length; i++) {
160                     if (fields[i] instanceof Initializer) {
161                         Initializer initializer = (Initializer)fields[i];
162                         if(initializer.declarationSourceEnd == initializer.bodyEnd && initializer.declarationSourceStart != initializer.declarationSourceEnd){
163                             initializer.bits |= ASTNode.ErrorInSignature;
164                             result.addInterval(initializer.declarationSourceStart, initializer.declarationSourceEnd, IGNORE);
165                         } else {
166                             result.addInterval(initializer.bodyStart, initializer.bodyEnd);
167                         }
168                     }
169                 }
170             }
171         }
172     }
173         
174     public static boolean containsIgnoredBody(AbstractMethodDeclaration method){
175         return !method.isDefaultConstructor()
176             && !method.isClinit()
177             && (method.modifiers & ExtraCompilerModifiers.AccSemicolonBody) == 0;
178     }
179 }
180
Popular Tags