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