removed Makefile; lifted repo/org.ibex.tool/src/ to src/
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / parser / diagnose / RangeUtil.java
diff --git a/src/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java b/src/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java
new file mode 100644 (file)
index 0000000..4c53fa2
--- /dev/null
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser.diagnose;
+
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
+
+public class RangeUtil {
+       
+       // flags
+       public static final int NO_FLAG = 0;
+       public static final int LBRACE_MISSING = 1;
+       public static final int IGNORE = 2;
+       
+       static class RangeResult {
+               private static final int INITIAL_SIZE = 10;
+               int pos;
+               int[] intervalStarts;
+               int[] intervalEnds;
+               int[] intervalFlags;
+               
+               RangeResult() {
+                       this.pos = 0;
+                       this.intervalStarts = new int[INITIAL_SIZE];
+                       this.intervalEnds = new int[INITIAL_SIZE];
+                       this.intervalFlags = new int[INITIAL_SIZE];
+               }
+               
+               void addInterval(int start, int end){
+                       addInterval(start, end, NO_FLAG);
+               }
+               
+               void addInterval(int start, int end, int flags){
+                       if(pos >= intervalStarts.length) {
+                               System.arraycopy(intervalStarts, 0, intervalStarts = new int[pos * 2], 0, pos);
+                               System.arraycopy(intervalEnds, 0, intervalEnds = new int[pos * 2], 0, pos);
+                               System.arraycopy(intervalFlags, 0, intervalFlags = new int[pos * 2], 0, pos);
+                       }
+                       intervalStarts[pos] = start;
+                       intervalEnds[pos] = end;
+                       intervalFlags[pos] = flags;
+                       pos++;
+               }
+               
+               int[][] getRanges() {
+                       int[] resultStarts = new int[pos];
+                       int[] resultEnds = new int[pos];
+                       int[] resultFlags = new int[pos];
+                       
+                       System.arraycopy(intervalStarts, 0, resultStarts, 0, pos);
+                       System.arraycopy(intervalEnds, 0, resultEnds, 0, pos);
+                       System.arraycopy(intervalFlags, 0, resultFlags, 0, pos);
+
+                       if (resultStarts.length > 1) {
+                               quickSort(resultStarts, resultEnds, resultFlags, 0, resultStarts.length - 1);
+                       }
+                       return new int[][]{resultStarts, resultEnds, resultFlags};
+               }
+               
+               private void quickSort(int[] list, int[] list2, int[] list3, int left, int right) {
+                       int original_left= left;
+                       int original_right= right;
+                       int mid= list[(left + right) / 2];
+                       do {
+                               while (compare(list[left], mid) < 0) {
+                                       left++;
+                               }
+                               while (compare(mid, list[right]) < 0) {
+                                       right--;
+                               }
+                               if (left <= right) {
+                                       int tmp= list[left];
+                                       list[left]= list[right];
+                                       list[right]= tmp;
+                                       
+                                       tmp = list2[left];
+                                       list2[left]= list2[right];
+                                       list2[right]= tmp;
+                                       
+                                       tmp = list3[left];
+                                       list3[left]= list3[right];
+                                       list3[right]= tmp;
+                                       
+                                       left++;
+                                       right--;
+                               }
+                       } while (left <= right);
+                       
+                       if (original_left < right) {
+                               quickSort(list, list2, list3, original_left, right);
+                       }
+                       if (left < original_right) {
+                               quickSort(list, list2, list3, left, original_right);
+                       }
+               }
+               
+               private int compare(int i1, int i2) {
+                       return i1 - i2;
+               }
+       }
+       
+       
+       
+       public static boolean containsErrorInSignature(AbstractMethodDeclaration method){
+               return method.sourceEnd + 1 == method.bodyStart || method.bodyEnd == method.declarationSourceEnd;
+       }
+
+       public static int[][] computeDietRange(TypeDeclaration[] types) {
+               if(types == null || types.length == 0) {
+                       return new int[3][0];
+               } else {
+                       RangeResult result = new RangeResult();
+                       computeDietRange0(types, result);
+                       return result.getRanges();
+               }
+       }
+       
+       private static void computeDietRange0(TypeDeclaration[] types, RangeResult result) {
+               for (int j = 0; j < types.length; j++) {
+                       //members
+                       TypeDeclaration[] memberTypeDeclarations = types[j].memberTypes;
+                       if(memberTypeDeclarations != null && memberTypeDeclarations.length > 0) {
+                               computeDietRange0(types[j].memberTypes, result);
+                       }
+                       //methods
+                       AbstractMethodDeclaration[] methods = types[j].methods;
+                       if (methods != null) {
+                               int length = methods.length;
+                               for (int i = 0; i < length; i++) {
+                                       AbstractMethodDeclaration method = methods[i];
+                                       if(containsIgnoredBody(method)) {
+                                               if(containsErrorInSignature(method)) {
+                                                       method.errorInSignature = true;
+                                                       result.addInterval(method.declarationSourceStart, method.declarationSourceEnd, IGNORE);
+                                               } else {
+                                                       int flags = method.sourceEnd + 1 == method.bodyStart ? LBRACE_MISSING : NO_FLAG;
+                                                       result.addInterval(method.bodyStart, method.bodyEnd, flags);
+                                               }
+                                       }
+                               }
+                       }
+       
+                       //initializers
+                       FieldDeclaration[] fields = types[j].fields;
+                       if (fields != null) {
+                               int length = fields.length;
+                               for (int i = 0; i < length; i++) {
+                                       if (fields[i] instanceof Initializer) {
+                                               Initializer initializer = (Initializer)fields[i];
+                                               if(initializer.declarationSourceEnd == initializer.bodyEnd){
+                                                       initializer.errorInSignature = true;
+                                                       result.addInterval(initializer.declarationSourceStart, initializer.declarationSourceEnd, IGNORE);
+                                               } else {
+                                                       result.addInterval(initializer.bodyStart, initializer.bodyEnd);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       public static boolean isInInterval(int start, int end, int[] intervalStart, int[] intervalEnd) {
+               int length = intervalStart.length;
+               for (int i = 0; i < length; i++) {
+                       if(intervalStart[i] <= start && intervalEnd[i] >= end) {
+                               return true;
+                       } else if(intervalStart[i] > end) {
+                               return false;
+                       }
+               }
+               return false;
+       }
+       
+       public static int getPreviousInterval(int start, int end, int[] intervalStart, int[] intervalEnd) {
+               int length = intervalStart.length;
+               for (int i = 0; i < length; i++) {
+                       if(intervalStart[i] > end) {
+                               return i - 1;
+                       }
+               }
+               return length - 1;
+       }
+       
+       public static boolean containsIgnoredBody(AbstractMethodDeclaration method){
+               return !method.isDefaultConstructor()
+                       && !method.isClinit()
+                       && (method.modifiers & CompilerModifiers.AccSemicolonBody) == 0;
+       }
+}