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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.parser.diagnose;
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;
19 public class RangeUtil {
22 public static final int NO_FLAG = 0;
23 public static final int LBRACE_MISSING = 1;
24 public static final int IGNORE = 2;
26 static class RangeResult {
27 private static final int INITIAL_SIZE = 10;
35 this.intervalStarts = new int[INITIAL_SIZE];
36 this.intervalEnds = new int[INITIAL_SIZE];
37 this.intervalFlags = new int[INITIAL_SIZE];
40 void addInterval(int start, int end){
41 addInterval(start, end, NO_FLAG);
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);
50 intervalStarts[pos] = start;
51 intervalEnds[pos] = end;
52 intervalFlags[pos] = flags;
57 int[] resultStarts = new int[pos];
58 int[] resultEnds = new int[pos];
59 int[] resultFlags = new int[pos];
61 System.arraycopy(intervalStarts, 0, resultStarts, 0, pos);
62 System.arraycopy(intervalEnds, 0, resultEnds, 0, pos);
63 System.arraycopy(intervalFlags, 0, resultFlags, 0, pos);
65 if (resultStarts.length > 1) {
66 quickSort(resultStarts, resultEnds, resultFlags, 0, resultStarts.length - 1);
68 return new int[][]{resultStarts, resultEnds, resultFlags};
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];
76 while (compare(list[left], mid) < 0) {
79 while (compare(mid, list[right]) < 0) {
84 list[left]= list[right];
88 list2[left]= list2[right];
92 list3[left]= list3[right];
98 } while (left <= right);
100 if (original_left < right) {
101 quickSort(list, list2, list3, original_left, right);
103 if (left < original_right) {
104 quickSort(list, list2, list3, left, original_right);
108 private int compare(int i1, int i2) {
115 public static boolean containsErrorInSignature(AbstractMethodDeclaration method){
116 return method.sourceEnd + 1 == method.bodyStart || method.bodyEnd == method.declarationSourceEnd;
119 public static int[][] computeDietRange(TypeDeclaration[] types) {
120 if(types == null || types.length == 0) {
121 return new int[3][0];
123 RangeResult result = new RangeResult();
124 computeDietRange0(types, result);
125 return result.getRanges();
129 private static void computeDietRange0(TypeDeclaration[] types, RangeResult result) {
130 for (int j = 0; j < types.length; j++) {
132 TypeDeclaration[] memberTypeDeclarations = types[j].memberTypes;
133 if(memberTypeDeclarations != null && memberTypeDeclarations.length > 0) {
134 computeDietRange0(types[j].memberTypes, result);
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);
147 int flags = method.sourceEnd + 1 == method.bodyStart ? LBRACE_MISSING : NO_FLAG;
148 result.addInterval(method.bodyStart, method.bodyEnd, flags);
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);
165 result.addInterval(initializer.bodyStart, initializer.bodyEnd);
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) {
178 } else if(intervalStart[i] > end) {
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) {
195 public static boolean containsIgnoredBody(AbstractMethodDeclaration method){
196 return !method.isDefaultConstructor()
197 && !method.isClinit()
198 && (method.modifiers & CompilerModifiers.AccSemicolonBody) == 0;