///*******************************************************************************
// * Copyright (c) 2005, 2009 IBM Corporation and others.
// * All rights reserved. This program and the accompanying materials
// * are made available under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available at
// * http://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// * IBM Corporation - initial API and implementation
// *******************************************************************************/
//package org.eclipse.jdt.core.tests.compiler.regression;
//
//import java.io.BufferedReader;
//import java.io.BufferedWriter;
//import java.io.File;
//import java.io.FileReader;
//import java.io.FileWriter;
//import java.io.IOException;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.Iterator;
//import java.util.List;
//import java.util.Map;
//import java.util.SortedMap;
//import java.util.TreeMap;
//
//import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
//import org.eclipse.jdt.internal.compiler.flow.NullInfoRegistry;
//import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
//import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo.AssertionFailedException;
//import org.eclipse.jdt.internal.compiler.impl.Constant;
//import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
//import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
//import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
//
//import junit.framework.AssertionFailedError;
//import junit.framework.Test;
//import junit.framework.TestSuite;
//
///**
// * A tests series especially meant to validate the internals of our null
// * reference analysis. See NullReferenceTest for tests targetted at
// * the source code compiler behavior level.
// */
//public class NullReferenceImplTests extends NullReferenceTest {
// // Static initializer to specify tests subset using TESTS_* static variables
// // All specified tests which does not belong to the class are skipped...
// // Only the highest compliance level is run; add the VM argument
// // -Dcompliance=1.4 (for example) to lower it if needed
// static {
//// TESTS_NAMES = new String[] { "test2050" };
//// TESTS_NUMBERS = new int[] { 2061 };
//// TESTS_NUMBERS = new int[] { 2999 };
//// TESTS_RANGE = new int[] { 2050, -1 };
// }
//
///**
// * A class to hold states as seen by the low level validation tests and machinery.
// * State provides:
// * - singletons for all possible states given the number of bits for the said
// * states;
// * - semantic names for known states;
// * - printable representation of states as bit fields;
// * - coordination with other classes to perform transitive closure analysis, etc.
// */
// /*
// This is a tabular definition for states. It can be completed/leveraged by
// the Generator class so as to smoothen the transition between differing encodings
// of the states.
// // STATES DEFINITION START
// 000000 start
// 000001
// 000010
// 000011
// 000100 pot. unknown
// 000101
// 000110
// 000111
// 001000 pot. non null
// 001001
// 001010
// 001011
// 001100 pot. nn & pot. un
// 001101
// 001110
// 001111
// 010000 pot. null
// 010001
// 010010
// 010011
// 010100 pot. n & pot. un
// 010101
// 010110
// 010111
// 011000 pot. n & pot. nn
// 011001
// 011010
// 011011
// 011100
// 011101
// 011110
// 011111
// 100000
// 100001
// 100010
// 100011
// 100100 def. unknown
// 100101
// 100110
// 100111
// 101000 def. non null
// 101001
// 101010
// 101011
// 101100 pot. nn & prot. nn
// 101101
// 101110
// 101111
// 110000 def. null
// 110001
// 110010
// 110011
// 110100 pot. n & prot. n
// 110101
// 110110
// 110111
// 111000 prot. null
// 111001
// 111010
// 111011
// 111100 prot. non null
// 111101
// 111110
// 111111
// // STATES DEFINITION END
// */
// public static class State implements Comparable {
// // PREMATURE consider moving initialization to test setup/dispose
// public final static State[] states = {
// // STATES INITIALIZER START
// new State(0, "start"), // 000000
// new State(1), // 000001
// new State(2), // 000010
// new State(3), // 000011
// new State(4, "pot. unknown"), // 000100
// new State(5), // 000101
// new State(6), // 000110
// new State(7), // 000111
// new State(8, "pot. non null"), // 001000
// new State(9), // 001001
// new State(10), // 001010
// new State(11), // 001011
// new State(12, "pot. nn & pot. un"), // 001100
// new State(13), // 001101
// new State(14), // 001110
// new State(15), // 001111
// new State(16, "pot. null"), // 010000
// new State(17), // 010001
// new State(18), // 010010
// new State(19), // 010011
// new State(20, "pot. n & pot. un"), // 010100
// new State(21), // 010101
// new State(22), // 010110
// new State(23), // 010111
// new State(24, "pot. n & pot. nn"), // 011000
// new State(25), // 011001
// new State(26), // 011010
// new State(27), // 011011
// new State(28), // 011100
// new State(29), // 011101
// new State(30), // 011110
// new State(31), // 011111
// new State(32), // 100000
// new State(33), // 100001
// new State(34), // 100010
// new State(35), // 100011
// new State(36, "def. unknown"), // 100100
// new State(37), // 100101
// new State(38), // 100110
// new State(39), // 100111
// new State(40, "def. non null"), // 101000
// new State(41), // 101001
// new State(42), // 101010
// new State(43), // 101011
// new State(44, "pot. nn & prot. nn"), // 101100
// new State(45), // 101101
// new State(46), // 101110
// new State(47), // 101111
// new State(48, "def. null"), // 110000
// new State(49), // 110001
// new State(50), // 110010
// new State(51), // 110011
// new State(52, "pot. n & prot. n"), // 110100
// new State(53), // 110101
// new State(54), // 110110
// new State(55), // 110111
// new State(56, "prot. null"), // 111000
// new State(57), // 111001
// new State(58), // 111010
// new State(59), // 111011
// new State(60, "prot. non null"), // 111100
// new State(61), // 111101
// new State(62), // 111110
// new State(63), // 111111
// // STATES INITIALIZER END
// };
// public final static State start = states[0];
// public static final int
// stateMaxValue = 0x3F,
// stateWidth = 6,
// statesNb = stateMaxValue + 1;
// String name, printableBitsField, hexString;
// public byte value;
// boolean symbolic;
// private State() {
// }
// private State(int numericValue) {
// this(numericValue, null);
// }
// private State(int numericValue, String publicName) {
// if (numericValue > stateMaxValue) {
// throw new IllegalArgumentException("state value overflow");
// }
// this.value = (byte) numericValue;
// StringBuffer printableValue = new StringBuffer(6);
// for (int i = stateWidth - 1; i >= 0; i--) {
// printableValue.append((numericValue >>> i & 1) != 0 ? '1' : '0');
// }
// this.printableBitsField = printableValue.toString();
// if (this.value > 0xF) {
// this.hexString = "0x" + Integer.toHexString(this.value).toUpperCase();
// }
// else {
// this.hexString = "0x0" + Integer.toHexString(this.value).toUpperCase();
// }
// if (publicName != null) {
// this.name = publicName;
// this.symbolic = true;
// }
// else {
// this.name = this.printableBitsField;
// }
// }
// private State(String commentLine) {
// char current = ' '; // keep the initialization status quiet
// int cursor, length;
// for (cursor = 0, length = commentLine.length();
// cursor < length;
// cursor++) {
// if ((current = commentLine.charAt(cursor)) == '0' ||
// current == '1') {
// break;
// }
// }
// if (cursor == length) {
// throw new RuntimeException("bad state definition format (missing bits field): " + commentLine);
// // PREMATURE adopt consistent error policy
// }
// int valueDigits;
// for (valueDigits = 1; cursor < (length - 1) && valueDigits < stateWidth; valueDigits++) {
// this.value = (byte) ((this.value << 1) + (current - '0'));
// if ((current = commentLine.charAt(++cursor)) != '0' &&
// current != '1') {
// throw new RuntimeException("bad state definition format (inappropriate character in bits field): " + commentLine);
// // PREMATURE adopt consistent error policy
// }
// }
// if (valueDigits < stateWidth) {
// throw new RuntimeException("bad state definition format (bits field is too short): " + commentLine);
// // PREMATURE adopt consistent error policy
// }
// this.value = (byte) ((this.value << 1) + (current - '0'));
// this.printableBitsField = commentLine.substring(cursor - stateWidth + 1, cursor + 1);
// if (this.value > 0xF) {
// this.hexString = "0x" + Integer.toHexString(this.value).toUpperCase();
// }
// else {
// this.hexString = "0x0" + Integer.toHexString(this.value).toUpperCase();
// }
// while (++cursor < length && Character.isWhitespace(current = commentLine.charAt(++cursor)) && current != '\n') {
// // loop
// }
// if (cursor < length && current != '\n') {
// this.name = commentLine.substring(cursor, length);
// }
// if (this.name == null) {
// this.name = this.printableBitsField;
// } else {
// this.symbolic = true;
// }
// }
// private String asInitializer() {
// StringBuffer result = new StringBuffer(70);
// result.append(" new State(");
// result.append(this.value);
// char first;
// boolean nameIsSymbolic = (first = this.name.charAt(0)) != '0'
// && first != '1';
// if (nameIsSymbolic) {
// result.append(", \"");
// result.append(this.name);
// result.append('"');
// }
// result.append("), // ");
// result.append(this.printableBitsField);
// return result.toString();
// }
// long [] asLongArray() {
// long[] result = new long[stateWidth];
// for (int i = 0; i < stateWidth; i++) {
// result[i] = ((this.value >> (stateWidth - i - 1)) & 1) == 0 ? 0 : 1;
// }
// return result;
// }
// private String asSourceComment() {
// StringBuffer result = new StringBuffer(70);
// result.append("\t\t");
// result.append(this.printableBitsField);
// char first;
// boolean nameIsSymbolic = (first = this.name.charAt(0)) != '0'
// && first != '1';
// if (nameIsSymbolic) {
// result.append('\t');
// result.append(this.name);
// }
// return result.toString();
// }
// public int compareTo(Object o) {
// return this.value - ((State) o).value;
// }
// static State fromLongValues(long bit1, long bit2, long bit3, long bit4, long bit5, long bit6) {
// // PREMATURE consider taking an UnconditionalFlowInfo in parameter
// return states[(int)(
// (bit6 & 1) +
// 2 * ((bit5 & 1) +
// 2 * ((bit4 & 1) +
// 2 * ((bit3 & 1) +
// 2 * ((bit2 & 1) +
// 2 * (bit1 & 1))))))];
// }
// private static Map namesIndex;
// static State fromSymbolicName (String name) {
// if (namesIndex == null) {
// namesIndex = new HashMap(states.length);
// for (int i = 0; i < states.length; i++) {
// if (states[i].name != null) {
// namesIndex.put(states[i].name, states[i]);
// }
// }
// }
// return (State) namesIndex.get(name);
// }
// private static void grabDefinitionFromComment(BufferedReader input) {
// String line;
// State current;
// // use when the initializer is incomplete, hence needs to be reinitialized
// // states = new State[stateMaxValue + 1];
// // use when the states field is final, with the appropriate size:
// for (int i = 0; i <= stateMaxValue; i++) {
// states[i] = null;
// }
// try {
// while ((line = input.readLine()) != null && line.indexOf(definitionEndMarker) == -1) {
// current = new State(line);
// if (states[current.value] != null) {
// throw new RuntimeException("duplicate state for index: " + current.value);
// }
// else {
// states[current.value] = current;
// }
// }
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// for (int i = 0; i < stateMaxValue; i++) {
// if (states[i] == null) {
// states[i] = new State(i);
// }
// }
// }
// // PREMATURE may decide to remove
// //private static void printAsInitializer() {
// // int i, length;
// // System.out.println(initializerStartMarker);
// // for (i = 0, length = states.length; i < length; i++) {
// // System.out.println(states[i].asInitializer());
// // }
// // for (/* continue */; i <= stateMaxValue; i++) {
// // System.out.println((new State(i)).asInitializer() + " CHECK");
// // }
// // System.out.println(initializerEndMarker);
// //}
// // PREMATURE may decide to remove
// //private static void printAsSourceComment() {
// // int i, length;
// // System.out.println("/*");
// // System.out.println(definitionStartMarker);
// // for (i = 0, length = states.length; i < length; i++) {
// // System.out.println(states[i].asSourceComment());
// // }
// // for (/* continue */; i <= stateMaxValue; i++) {
// // System.out.println((new State(i)).asSourceComment());
// // }
// // System.out.println(definitionEndMarker);
// // System.out.println("*/");
// //}
// private final static String
// definitionStartMarker = "// STATES " + CodeAnalysis.definitionStartMarker,
// definitionEndMarker = "// STATES " + CodeAnalysis.definitionEndMarker,
// initializerStartMarker = "// STATES " + CodeAnalysis.initializerStartMarker,
// initializerEndMarker = "// STATES " + CodeAnalysis.initializerEndMarker;
// static void reinitializeFromComment(BufferedReader input, BufferedWriter output) {
// String line, tab = "";
// int cursor;
// char c;
// try {
// while ((line = input.readLine()) != null) {
// output.write(line);
// output.write('\n');
// if ((cursor = line.indexOf(definitionStartMarker)) != -1) {
// // check the line format
// boolean reachedStart = true;
// for (int i = 0; i < cursor; i++) {
// if (!Character.isWhitespace(c = line.charAt(i))) {
// reachedStart = false;
// break;
// }
// else {
// tab += c;
// }
// }
// if (reachedStart) {
// grabDefinitionFromComment(input); // consumes up to the END line
// int i, length;
// for (i = 0, length = states.length; i < length; i++) {
// output.write(states[i].asSourceComment());
// output.write('\n');
// }
// output.write(tab + definitionEndMarker + "\n");
// }
// }
// if ((cursor = line.indexOf(initializerStartMarker)) != -1) {
// // check the line format
// boolean reachedStart = true;
// tab = "";
// for (int i = 0; i < cursor; i++) {
// if (!Character.isWhitespace(c = line.charAt(i))) {
// reachedStart = false;
// break;
// }
// else {
// tab += c;
// }
// }
// if (reachedStart) {
// while ((line = input.readLine()) != null &&
// line.indexOf(initializerEndMarker) == -1) {
// // loop
// }
// int i, length;
// for (i = 0, length = states.length; i < length; i++) {
// output.write(states[i].asInitializer());
// output.write('\n');
// }
// output.write(tab + initializerEndMarker + "\n");
// }
// }
// }
// output.flush();
// namesIndex = null;
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// }
// static Iterator symbolicStates() {
// return new Iterator() {
// int nextSymbolic = -1;
// public boolean hasNext() {
// if (nextSymbolic == -1) {
// for (nextSymbolic = 0; nextSymbolic < states.length; nextSymbolic++) {
// if (states[nextSymbolic].symbolic) {
// break;
// }
// }
// } else {
// for (; nextSymbolic < states.length; nextSymbolic++) {
// if (states[nextSymbolic].symbolic) {
// break;
// }
// }
// }
// return nextSymbolic < states.length;
// }
// public Object next() {
// State result = null;
// if (nextSymbolic < states.length) {
// result = states[nextSymbolic];
// nextSymbolic++;
// }
// return result;
// }
// public void remove() {
// throw new RuntimeException("unimplemented");
// }
// };
// }
// public String toString() {
// return this.name;
// }
// }
//
//public NullReferenceImplTests(String name) {
// super(name);
//}
//
// // Tests tuning
// static final boolean
// skipHighOrderBits = false; // define to true when tuning encoding
// static final int
// combinationTestsloopsNb = 1; // define to 10000s to measure performances
//
//public static Test suite() {
// // we do not want to run for 1.3, 1.4, 1.5 but once only
// Class clazz = testClass();
// TestSuite all = new TestSuite(clazz.getName());
// List tests = buildTestsList(testClass());
// for (int i = 0, length = tests.size(); i < length; i++) {
// all.addTest((Test) tests.get(i));
// }
// return all;
//}
//
//public static Class testClass() {
// return NullReferenceImplTests.class;
//}
//
//public void test2050_markAsComparedEqualToNonNull() {
// int failures = NullReferenceImplTransformations.markAsComparedEqualToNonNull.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2051_markAsComparedEqualToNull() {
// int failures = NullReferenceImplTransformations.markAsComparedEqualToNull.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2055_markAsDefinitelyNonNull() {
// int failures = NullReferenceImplTransformations.markAsDefinitelyNonNull.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2056_markAsDefinitelyNull() {
// int failures = NullReferenceImplTransformations.markAsDefinitelyNull.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2057_markAsDefinitelyUnknown() {
// int failures = NullReferenceImplTransformations.markAsDefinitelyUnknown.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2060_addInitializationsFrom() {
// int failures = NullReferenceImplTransformations.addInitializationsFrom.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2061_addPotentialInitializationsFrom() {
// int failures = NullReferenceImplTransformations.addPotentialInitializationsFrom.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2062_mergedWith() {
// int failures = NullReferenceImplTransformations.mergedWith.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2070_newNullInfoRegistry() {
// int failures = NullReferenceImplTransformations.newNullInfoRegistry.test();
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//// PREMATURE rewrite from scratch
////public void _test2058_recode() {
//// long [][][] testData = transitionsTablesData[recode];
//// int failures = 0;
//// long start;
//// if (combinationTestsloopsNb > 1) {
//// start = System.currentTimeMillis();
//// }
//// String header = "recode failures: ";
//// for (int l = 0; l < combinationTestsloopsNb ; l++) {
//// for (int i = 0; i < testData.length; i++) {
//// UnconditionalFlowInfoTestHarness result;
//// result = UnconditionalFlowInfoTestHarness.
//// testUnconditionalFlowInfo(testData[i][0]);
//// result.encode();
//// result.decode();
////
//// if (!result.testEquals(UnconditionalFlowInfoTestHarness.
//// testUnconditionalFlowInfo(testData[i][0]))) {
//// if (failures == 0) {
//// System.out.println(header);
//// }
//// failures++;
//// System.out.println("\t\t{" + result.testString() +
//// "}, // instead of: " + testStringValueOf(testData[i][0]));
//// }
//// }
//// }
//// if (combinationTestsloopsNb > 1) {
//// System.out.println("mergedWith\t\t\t" + combinationTestsloopsNb + "\t" +
//// (System.currentTimeMillis() - start));
//// }
//// for (int i = 0; i < testData.length; i++) {
//// UnconditionalFlowInfoTestHarness result;
//// result = UnconditionalFlowInfoTestHarness.
//// testUnconditionalFlowInfo(testData[i][0], 64);
//// result.encode();
//// result.decode();
////
//// if (!result.testEquals(UnconditionalFlowInfoTestHarness.
//// testUnconditionalFlowInfo(testData[i][0], 64))) {
//// if (failures == 0) {
//// System.out.println(header);
//// }
//// failures++;
//// System.out.println("\t\t{" + result.testString() +
//// "}, // (64) - instead of: " + testStringValueOf(testData[i][0]));
//// }
//// }
//// assertTrue("nb of failures: " + failures, failures == 0);
////}
//
//public void test2400_state_consistency() {
// int failures = 0;
// long start;
// if (combinationTestsloopsNb > 1) {
// start = System.currentTimeMillis();
// }
// String header = "state consistency failures: ";
// for (int l = 0; l < combinationTestsloopsNb ; l++) {
// for (int i = 0; i < State.states.length; i++) {
// if (State.states[i].symbolic) {
// UnconditionalFlowInfoTestHarness
// state = UnconditionalFlowInfoTestHarness.
// testUnconditionalFlowInfo(State.states[i]);
// boolean
// isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local0),
// isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local0),
// isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local0),
// isPotentiallyNonNull = state.isPotentiallyNonNull(TestLocalVariableBinding.local0),
// isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local0),
// isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local0),
// isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local0),
// isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local0),
// cannotBeDefinitelyNullOrNonNull = state.cannotBeDefinitelyNullOrNonNull(TestLocalVariableBinding.local0),
// cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local0),
// canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local0);
// if (isDefinitelyNonNull
// && (isDefinitelyNull || isDefinitelyUnknown
// || isPotentiallyNull
// || isProtectedNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage for definitely non null state " + State.states[i].name);
// }
// if (isDefinitelyNull
// && (isDefinitelyNonNull || isDefinitelyUnknown
// || isPotentiallyUnknown || isProtectedNonNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage for definitely null state " + State.states[i].name);
// }
// if (isDefinitelyUnknown
// && (isDefinitelyNonNull || isDefinitelyNull
// || isPotentiallyNull || isProtectedNonNull
// || isProtectedNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage for definitely unknown state " + State.states[i].name);
// }
// if (isProtectedNonNull && !isDefinitelyNonNull
// || isProtectedNull && !isDefinitelyNull
// || i > 0 // not start
// && !State.states[i].name.equals("pot. non null")
// && !(isDefinitelyNonNull || isDefinitelyNull
// || isDefinitelyUnknown || isPotentiallyNull
// || isPotentiallyUnknown || isProtectedNonNull
// || isProtectedNull)
// || cannotBeDefinitelyNullOrNonNull !=
// (isPotentiallyUnknown ||
// isPotentiallyNull && isPotentiallyNonNull)
// || cannotBeNull != (isProtectedNonNull ||
// isDefinitelyNonNull)
// || canOnlyBeNull != (isProtectedNull ||
// isDefinitelyNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage for " + State.states[i].name);
// }
// }
// }
// }
// if (combinationTestsloopsNb > 1) {
// System.out.println("mergedWith\t\t\t" + combinationTestsloopsNb + "\t" +
// (System.currentTimeMillis() - start));
// }
// for (int i = 0; i < State.states.length; i++) {
// if (State.states[i].symbolic) {
// UnconditionalFlowInfoTestHarness state;
// state = UnconditionalFlowInfoTestHarness.
// testUnconditionalFlowInfo(State.states[i], 64);
// boolean
// isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local64),
// isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local64),
// isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local64),
// isPotentiallyNonNull = state.isPotentiallyNonNull(TestLocalVariableBinding.local64),
// isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local64),
// isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local64),
// isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local64),
// isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local64),
// cannotBeDefinitelyNullOrNonNull = state.cannotBeDefinitelyNullOrNonNull(TestLocalVariableBinding.local64),
// cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local64),
// canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local64);
// if (isDefinitelyNonNull
// && (isDefinitelyNull || isDefinitelyUnknown
// || isPotentiallyNull
// || isProtectedNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage (64) for definitely non null state " + State.states[i].name);
// }
// if (isDefinitelyNull
// && (isDefinitelyNonNull || isDefinitelyUnknown
// || isPotentiallyUnknown || isProtectedNonNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage (64) for definitely null state " + State.states[i].name);
// }
// if (isDefinitelyUnknown
// && (isDefinitelyNonNull || isDefinitelyNull
// || isPotentiallyNull || isProtectedNonNull
// || isProtectedNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage (64) for definitely unknown state " + State.states[i].name);
// }
// if (isProtectedNonNull && !isDefinitelyNonNull
// || isProtectedNull && !isDefinitelyNull
// || i > 0 // not start
// && !State.states[i].name.equals("pot. non null")
// && !(isDefinitelyNonNull || isDefinitelyNull
// || isDefinitelyUnknown || isPotentiallyNull
// || isPotentiallyUnknown || isProtectedNonNull
// || isProtectedNull)
// || cannotBeDefinitelyNullOrNonNull !=
// (isPotentiallyUnknown ||
// isPotentiallyNull &&
// isPotentiallyNonNull)
// || cannotBeNull != (isProtectedNonNull ||
// isDefinitelyNonNull)
// || canOnlyBeNull != (isProtectedNull ||
// isDefinitelyNull)) {
// if (failures == 0) {
// System.out.println(header);
// }
// failures++;
// System.out.println("\t\tconsistency breakage (64) for " + State.states[i].name);
// }
// }
// }
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//public void test2500_addInitializationsFrom_for_definites() {
// // when an added initialization is a def. something, it should
// // affect the left hand term as the markAsDefinite* method would
// // do
// int failures = 0;
// for (int i = 0; i < State.states.length; i++) {
// if (State.states[i].symbolic) {
// UnconditionalFlowInfoTestHarness source1, source2, result1, result2;
// source1 = UnconditionalFlowInfoTestHarness.
// testUnconditionalFlowInfo(State.states[i]);
// for (int j = 0; j < State.states.length; j++) {
// if (State.states[j].symbolic) {
// source2 = UnconditionalFlowInfoTestHarness.
// testUnconditionalFlowInfo(State.states[j]);
// result1 = (UnconditionalFlowInfoTestHarness) source1.copy();
// result2 = (UnconditionalFlowInfoTestHarness) source1.copy();
// if (source2.isDefinitelyNonNull(TestLocalVariableBinding.local0)) {
// if (! source2.isProtectedNonNull(TestLocalVariableBinding.local0)) {
// result1.markAsDefinitelyNonNull(TestLocalVariableBinding.local0);
// } else {
// continue;
// }
// }
// else if (source2.isDefinitelyNull(TestLocalVariableBinding.local0)) {
// if (! source2.isProtectedNull(TestLocalVariableBinding.local0)) {
// result1.markAsDefinitelyNull(TestLocalVariableBinding.local0);
// } else {
// continue;
// }
// }
// else if (source2.isDefinitelyUnknown(TestLocalVariableBinding.local0)) {
// result1.markAsDefinitelyUnknown(TestLocalVariableBinding.local0);
// }
// else if (source2.nullBit1 != 0) {
// if (failures == 0) {
// System.out.println("addInitializationsFrom_for_definites failures: ");
// }
// failures++;
// System.out.println("\t\t" + State.states[j].name +
// " should answer true to at least one isDefinite* query");
// // PREMATURE move to specific queries test case
// }
// else {
// continue;
// }
// result2.addInitializationsFrom(source2);
// if (!result1.testEquals(result2)) {
// if (failures == 0) {
// System.out.println("addInitializationsFrom_for_definites failures: ");
// }
// failures++;
// System.out.println("\t\t" + State.states[i].name +
// " + " + State.states[j].name +
// " => " + result2.asState().name +
// " instead of: " + result1.asState().name);
// }
// }
// }
// }
// }
// assertTrue("nb of failures: " + failures, failures == 0);
//}
//
//// Use for coverage tests only. Needs specific instrumentation of code,
//// that is controled by UnconditionalFlowInfo#coverageTestFlag.
//// Note: coverage tests tend to fill the console with messages, and the
//// instrumented code is slower, so never release code with active
//// coverage tests.
//private static int coveragePointsNb = 39;
//
//// PREMATURE reactivate coverage tests
//// Coverage by state transition tables methods.
//public void test2998_coverage() {
// if (UnconditionalFlowInfo.coverageTestFlag) {
// // sanity check: need to be sure that the tests execute properly when not
// // trying to check coverage
// UnconditionalFlowInfo.coverageTestId = 0;
// test0053_array();
// test0070_type_reference();
// test2050_markAsComparedEqualToNonNull();
// test2051_markAsComparedEqualToNull();
// test2055_markAsDefinitelyNonNull();
// test2056_markAsDefinitelyNull();
// test2057_markAsDefinitelyUnknown();
// test2060_addInitializationsFrom();
// test2061_addPotentialInitializationsFrom();
// test2062_mergedWith();
// // coverage check
// int failuresNb = 0;
// for (int i = 1; i <= coveragePointsNb; i++) {
// if (i == 11 || i == 12 || i == 14) {
// continue;
// // these can only be reached via a direct call to addPotentialNullInfoFrom,
// // which is not implemented in low level tests - all those go through
// // addPotentialInitsFrom
// }
// try {
// UnconditionalFlowInfo.coverageTestId = i;
// test0053_array();
// test0070_type_reference();
// test2050_markAsComparedEqualToNonNull();
// test2051_markAsComparedEqualToNull();
// test2055_markAsDefinitelyNonNull();
// test2056_markAsDefinitelyNull();
// test2057_markAsDefinitelyUnknown();
// test2060_addInitializationsFrom();
// test2061_addPotentialInitializationsFrom();
// test2062_mergedWith();
// }
// catch (AssertionFailedError e) {
// continue;
// }
// catch (AssertionFailedException e) {
// continue;
// }
// failuresNb++;
// System.out.println("Missing coverage point: " + i);
// }
// UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests
// assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0);
// }
//}
//
//// Coverage by code samples.
//public void test2999_coverage() {
// if (UnconditionalFlowInfo.coverageTestFlag) {
// // sanity check: need to be sure that the tests execute properly when not
// // trying to check coverage
// UnconditionalFlowInfo.coverageTestId = 0;
// test0001_simple_local();
// test0053_array();
// test0070_type_reference();
// test0327_if_else();
// test0401_while();
// test0420_while();
// test0509_try_finally_embedded();
// test2000_flow_info();
// test2004_flow_info();
// test2008_flow_info();
// test2011_flow_info();
// test2013_flow_info();
// test2018_flow_info();
// test2019_flow_info();
// test2020_flow_info();
// // coverage check
// int failuresNb = 0;
// for (int i = 1; i <= coveragePointsNb; i++) {
// if (i < 3
// || 4 < i && i < 11
// || 11 < i && i < 16
// || 16 < i && i < 20
// || i == 21
// || 23 < i && i < 27
// || 29 < i && i < 33
// || 36 < i) { // TODO (maxime) complete coverage tests
// continue;
// }
// try {
// UnconditionalFlowInfo.coverageTestId = i;
// test0001_simple_local();
// test0053_array();
// test0070_type_reference();
// test0327_if_else();
// test0401_while();
// test0420_while();
// test0509_try_finally_embedded();
// test2000_flow_info();
// test2004_flow_info();
// test2008_flow_info();
// test2011_flow_info();
// test2013_flow_info();
// test2018_flow_info();
// test2019_flow_info();
// test2020_flow_info();
// }
// catch (AssertionFailedError e) {
// continue;
// }
// catch (AssertionFailedException e) {
// continue;
// }
// failuresNb++;
// System.out.println("Missing coverage point: " + i);
// }
// UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests
// assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0);
// }
//}
//
//// only works for info coded on bit 0 - least significant
//String testCodedValueOf(long[] data) {
// int length;
// StringBuffer result = new StringBuffer(length = data.length);
// for (int i = 0; i < length; i++) {
// result.append(data[i] == 0 ? '0' : '1');
// }
// return result.toString();
//}
//
//static String testStringValueOf(long[] data) {
// int length;
// StringBuffer result = new StringBuffer((length = data.length) * 2 + 1);
// result.append('{');
// for (int i = 0; i < length; i++) {
// if (i > 0) {
// result.append(',');
// }
// result.append(data[i]);
// }
// result.append('}');
// return result.toString();
//}
//}
//
///**
// * A specific extension of LocalVariableBinding suitable for flow info
// * manipulation at an implementation level.
// */
//class TestLocalVariableBinding extends LocalVariableBinding {
// static class TestTypeBinding extends TypeBinding {
// public TestTypeBinding() {
// tagBits = 0L;
// }
// public char[] constantPoolName() {
// return null;
// }
// public PackageBinding getPackage() {
// return null;
// }
// public boolean isCompatibleWith(TypeBinding right) {
// return false;
// }
// public char[] qualifiedSourceName() {
// return null;
// }
// public char[] sourceName() {
// return null;
// }
// public char[] readableName() {
// return null;
// }
// }
// final static TypeBinding testTypeBinding = new TestTypeBinding();
// final static char [] testName = {'t', 'e', 's', 't'};
// TestLocalVariableBinding(int id) {
// super(testName, testTypeBinding, 0, false);
// this.id = id;
// }
// public Constant constant() {
// return Constant.NotAConstant;
// }
// static final TestLocalVariableBinding
// local0 = new TestLocalVariableBinding(0),
// local64 = new TestLocalVariableBinding(64),
// local128 = new TestLocalVariableBinding(128);
//}
//
///**
// * A class meant to augment
// * @link{org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo} with
// * capabilities in the test domain. It especially provides factories to build
// * fake flow info instances for use in state transitions validation.
// */
///*
// * Moreover, this class defines the implementation of key operations for the
// * benefit of itself and NullInfoRegistryTestHarness. Given the fact that the
// * latter could not extend UnconditionalFlowInfoTestHarness and
// * NullInfoRegistry, the code is factorized into static methods.
// */
//class UnconditionalFlowInfoTestHarness extends UnconditionalFlowInfo {
// int testPosition;
// // Interface
///**
// * Return the state represented by this.
// * @return the state represented by this
// */
//NullReferenceImplTests.State asState() {
// return asState(this, 0);
//}
//
///**
// * Return the state represented by this for a variable encoded at a given position.
// * @param position - int the position of the considered variable
// * @return the state represented by this for a variable encoded at a given position
// */
//NullReferenceImplTests.State asState(int position) {
// return asState(this, position);
//}
//
//public FlowInfo copy() {
// UnconditionalFlowInfoTestHarness copy =
// new UnconditionalFlowInfoTestHarness();
// copy.testPosition = this.testPosition;
// copy(this, copy);
// return copy;
//}
//
//public void markAsDefinitelyNonNull(LocalVariableBinding local) {
// grow(local.id + this.maxFieldCount);
// super.markAsDefinitelyNonNull(local);
//}
//
//public void markAsDefinitelyNull(LocalVariableBinding local) {
// grow(local.id + this.maxFieldCount);
// super.markAsDefinitelyNull(local);
//}
//
//public void markAsDefinitelyUnknown(LocalVariableBinding local) {
// grow(local.id + this.maxFieldCount);
// super.markAsDefinitelyUnknown(local);
//}
//
///**
// * Return a fake unconditional flow info which bit fields represent the given
// * null bits for a local variable of id 0 within a class that would have no
// * field.
// * @param nullBits the bits that must be set, given in the same order as the
// * nullAssignment* fields in UnconditionalFlowInfo definition; use 0
// * for a bit that is not set, 1 else
// * @return a fake unconditional flow info which bit fields represent the
// * null bits given in parameter
// */
//public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo(
// long [] nullBits) {
// return testUnconditionalFlowInfo(nullBits, 0);
//}
//
///**
// * Return a fake unconditional flow info which bit fields represent the given
// * null bits for a local variable of id position within a class that would have
// * no field.
// * @param nullBits the bits that must be set, given in the same order as the
// * nullAssignment* fields in UnconditionalFlowInfo definition; use 0
// * for a bit that is not set, 1 else
// * @param position the position of the variable within the bit fields; use
// * various values to test different parts of the bit fields, within
// * or beyond BitCacheSize
// * @return a fake unconditional flow info which bit fields represent the
// * null bits given in parameter
// */
//public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo(
// long [] nullBits, int position) {
// UnconditionalFlowInfoTestHarness result =
// new UnconditionalFlowInfoTestHarness();
// result.testPosition = position;
// init(result, nullBits, position);
// return result;
//}
//
///**
// * Return a fake unconditional flow info which bit fields represent the given
// * state for a local variable of id 0 within a class that would have
// * no field.
// * @param state - State the desired state for the variable
// * @return a fake unconditional flow info which bit fields represent the
// * state given in parameter
// */
//public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo(NullReferenceImplTests.State state) {
// return testUnconditionalFlowInfo(state, 0);
//}
//
///**
// * Return a fake unconditional flow info which bit fields represent the given
// * state for a local variable of id position within a class that would have
// * no field.
// * @param state - State the desired state for the variable
// * @param position the position of the variable within the bit fields; use
// * various values to test different parts of the bit fields, within
// * or beyond BitCacheSize
// * @return a fake unconditional flow info which bit fields represent the
// * state given in parameter
// */
//public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo(
// NullReferenceImplTests.State state, int position) {
// UnconditionalFlowInfoTestHarness result =
// new UnconditionalFlowInfoTestHarness();
// long[] nullBits = state.asLongArray();
// result.testPosition = position;
// init(result, nullBits, position);
// return result;
//}
//
///**
// * Return true iff this flow info can be considered as equal to the one passed
// * in parameter.
// * @param other the flow info to compare to
// * @return true iff this flow info compares equal to other
// */
//public boolean testEquals(UnconditionalFlowInfo other) {
// return testEquals(this, other);
//}
//
///**
// * Return true iff this flow info can be considered as equal to the one passed
// * in parameter in respect with a single local variable which id would be
// * position in a class with no field.
// * @param other the flow info to compare to
// * @param position the position of the local to consider
// * @return true iff this flow info compares equal to other for a given local
// */
//public boolean testEquals(UnconditionalFlowInfo other, int position) {
// return testEquals(this, other, position);
//}
//
///**
// * Return a string suitable for use as a representation of this flow info
// * within test series.
// * @return a string suitable for use as a representation of this flow info
// */
//public String testString() {
// if (this == DEAD_END) {
// return "FlowInfo.DEAD_END";
// }
// return testString(this, this.testPosition);
//}
//
///**
// * Return a string suitable for use as a representation of this flow info
// * within test series.
// * @param position a position to consider instead of this flow info default
// * test position
// * @return a string suitable for use as a representation of this flow info
// */
//public String testString(int position) {
// return testString(this, position);
//}
//
// // Factorized implementation
//static NullReferenceImplTests.State asState(UnconditionalFlowInfo zis, int position) {
// if ((zis.tagBits & NULL_FLAG_MASK) == 0) {
// return NullReferenceImplTests.State.start;
// }
// if (position < BitCacheSize) {
// return NullReferenceImplTests.State.fromLongValues(
// (zis.nullBit1 >> position) & 1,
// (zis.nullBit2 >> position) & 1,
// (zis.nullBit3 >> position) & 1,
// (zis.nullBit4 >> position) & 1,
// 0,
// 0);
// }
// else {
// int vectorIndex = (position / BitCacheSize) - 1;
// position %= BitCacheSize;
// if (vectorIndex >= zis.extra[2].length) {
// return NullReferenceImplTests.State.start;
// }
// return NullReferenceImplTests.State.fromLongValues(
// (zis.extra[2][vectorIndex] >> position) & 1,
// (zis.extra[3][vectorIndex] >> position) & 1,
// (zis.extra[4][vectorIndex] >> position) & 1,
// (zis.extra[5][vectorIndex] >> position) & 1,
// 0 //(zis.extra[6][vectorIndex] >> position) & 1,
// , 0 //(zis.extra[7][vectorIndex] >> position) & 1
// );
// }
//}
//
//static void copy(UnconditionalFlowInfo source, UnconditionalFlowInfo target) {
// target.definiteInits = source.definiteInits;
// target.potentialInits = source.potentialInits;
// boolean hasNullInfo = (source.tagBits & NULL_FLAG_MASK) != 0;
// if (hasNullInfo) {
// target.nullBit1 = source.nullBit1;
// target.nullBit2 = source.nullBit2;
// target.nullBit3 = source.nullBit3;
// target.nullBit4 = source.nullBit4;
//// target.nullBit5 = source.nullBit5;
//// target.nullBit6 = source.nullBit6;
// }
// target.tagBits = source.tagBits;
// target.maxFieldCount = source.maxFieldCount;
// if (source.extra != null) {
// int length;
// target.extra = new long[extraLength][];
// System.arraycopy(source.extra[0], 0,
// (target.extra[0] = new long[length = source.extra[0].length]), 0, length);
// System.arraycopy(source.extra[1], 0,
// (target.extra[1] = new long[length]), 0, length);
// if (hasNullInfo) {
// for (int j = 0; j < extraLength; j++) {
// System.arraycopy(source.extra[j], 0,
// (target.extra[j] = new long[length]), 0, length);
// }
// }
// else {
// for (int j = 0; j < extraLength; j++) {
// target.extra[j] = new long[length];
// }
// }
// }
//}
//
//public void grow(int position) {
// int vectorIndex = ((position) / BitCacheSize) - 1;
// int length = vectorIndex + 1, oldLength;
// if (this.extra == null) {
// this.extra = new long[extraLength][];
// for (int j = 0; j < extraLength; j++) {
// this.extra[j] = new long[length];
// }
// } else if (length > (oldLength = this.extra[2].length)) {
// for (int j = 0; j < extraLength; j++) {
// System.arraycopy(this.extra[j], 0,
// this.extra[j] = new long[length], 0, oldLength);
// }
// }
//}
//
//static void init(UnconditionalFlowInfo zis, long [] nullBits, int position) {
// if (position < BitCacheSize) {
// zis.nullBit1 = nullBits[0] << position;
// zis.nullBit2 = nullBits[1] << position;
// zis.nullBit3 = nullBits[2] << position;
// zis.nullBit4 = nullBits[3] << position;
//// zis.nullBit5 = nullBits[4] << position;
//// zis.nullBit6 = nullBits[5] << position;
// }
// else {
// int vectorIndex = (position / BitCacheSize) - 1,
// length = vectorIndex + 1;
// position %= BitCacheSize;
// zis.extra = new long[extraLength][];
// zis.extra[0] = new long[length];
// zis.extra[1] = new long[length];
// for (int j = 2; j < extraLength; j++) {
// zis.extra[j] = new long[length];
// zis.extra[j][vectorIndex] = nullBits[j - 2] << position;
// }
// }
// if (nullBits[0] != 0 || nullBits[1] != 0
// || nullBits[2] != 0 || nullBits[3] != 0
// || nullBits[4] != 0 || nullBits[5] != 0) {
// // cascade better than nullBits[0] | nullBits[1] | nullBits[2] | nullBits[3]
// // by 10%+
// // TODO (maxime) run stats to determine which is the better order
// zis.tagBits |= NULL_FLAG_MASK;
// }
// zis.maxFieldCount = 0;
//}
//
//static boolean testEquals(UnconditionalFlowInfo zis, UnconditionalFlowInfo other) {
// if (zis.tagBits != other.tagBits) {
// return false;
// }
// if (zis.nullBit1 != other.nullBit1
// || zis.nullBit2 != other.nullBit2
// || zis.nullBit3 != other.nullBit3
// || zis.nullBit4 != other.nullBit4
// /* || zis.nullBit5 != other.nullBit5
// || zis.nullBit6 != other.nullBit6 */) {
// return false;
// }
// int left = zis.extra == null ? 0 : zis.extra[2].length,
// right = other.extra == null ? 0 : other.extra[2].length,
// both = 0, i;
// if (left > right) {
// both = right;
// }
// else {
// both = left;
// }
// for (i = 0; i < both ; i++) {
// for (int j = 2; j < extraLength; j++) {
// if (zis.extra[j][i] !=
// other.extra[j][i]) {
// return false;
// }
// }
// }
// for (; i < left; i++) {
// for (int j = 2; j < extraLength; j++) {
// if (zis.extra[j][i] != 0) {
// return false;
// }
// }
// }
// for (; i < right; i++) {
// for (int j = 2; j < extraLength; j++) {
// if (other.extra[j][i] != 0) {
// return false;
// }
// }
// }
// return true;
//}
//
//static boolean testEquals(UnconditionalFlowInfo zis, UnconditionalFlowInfo other,
// int position) {
// int vectorIndex = position / BitCacheSize - 1;
// if ((zis.tagBits & other.tagBits & NULL_FLAG_MASK) == 0) {
// return true;
// }
// long mask;
// if (vectorIndex < 0) {
// return ((zis.nullBit1 & (mask = (1L << position))) ^
// (other.nullBit1 & mask)) == 0 &&
// ((zis.nullBit2 & mask) ^
// (other.nullBit2 & mask)) == 0 &&
// ((zis.nullBit3 & mask) ^
// (other.nullBit3 & mask)) == 0 &&
// ((zis.nullBit4 & mask) ^
// (other.nullBit4 & mask)) == 0 /* &&
// ((zis.nullBit5 & mask) ^
// (other.nullBit5 & mask)) == 0 &&
// ((zis.nullBit6 & mask) ^
// (other.nullBit6 & mask)) == 0 */;
// }
// else {
// int left = zis.extra == null ?
// 0 :
// zis.extra[0].length;
// int right = other.extra == null ?
// 0 :
// other.extra[0].length;
// int both = left < right ? left : right;
// if (vectorIndex < both) {
// mask = (1L << (position % BitCacheSize));
// for (int j = 2; j < extraLength; j++) {
// if (((zis.extra[j][vectorIndex] & mask)
// ^ (other.extra[j][vectorIndex] & mask)) != 0) {
// return false;
// }
// }
// return true;
// }
// if (vectorIndex < left) {
// return ((zis.extra[2][vectorIndex] |
// zis.extra[3][vectorIndex] |
// zis.extra[4][vectorIndex] |
// zis.extra[5][vectorIndex] |
// zis.extra[6][vectorIndex] |
// zis.extra[7][vectorIndex]) &
// (1L << (position % BitCacheSize))) == 0;
// }
// return ((other.extra[2][vectorIndex] |
// other.extra[3][vectorIndex] |
// other.extra[4][vectorIndex] |
// other.extra[5][vectorIndex] |
// other.extra[6][vectorIndex] |
// other.extra[7][vectorIndex]) &
// (1L << (position % BitCacheSize))) == 0;
// }
//}
//
//static String testString(UnconditionalFlowInfo zis, int position) {
// if (zis == DEAD_END) {
// return "FlowInfo.DEAD_END";
// }
// if (position < BitCacheSize) {
// return "{" + (zis.nullBit1 >> position)
// + "," + (zis.nullBit2 >> position)
// + "," + (zis.nullBit3 >> position)
// + "," + (zis.nullBit4 >> position)
//// + "," + (zis.nullBit5 >> position)
//// + "," + (zis.nullBit6 >> position)
// + "}";
// }
// else {
// int vectorIndex = position / BitCacheSize - 1,
// shift = position % BitCacheSize;
// return "{" + (zis.extra[2][vectorIndex]
// >> shift)
// + "," + (zis.extra[3][vectorIndex]
// >> shift)
// + "," + (zis.extra[4][vectorIndex]
// >> shift)
// + "," + (zis.extra[5][vectorIndex]
// >> shift)
//// + "," + (zis.extra[6][vectorIndex]
//// >> shift)
//// + "," + (zis.extra[7][vectorIndex]
//// >> shift)
// + "}";
// }
//}
//}
///**
// * A class meant to augment
// * @link{org.eclipse.jdt.internal.compiler.flow.NullInfoRegistry} with
// * capabilities in the test domain. It especially provides factories to build
// * fake flow info instances for use in state transitions validation.
// */
///*
// * The reason why UnconditionalFlowInfoTestHarness and this class were
// * separated is that NullInfoRegistry redefines part of the markAs* methods,
// * in effect preventing a harness extending NullInfoRegistry to access
// * UnconditionalFlowInfo implementations of the said methods.
// */
//class NullInfoRegistryTestHarness extends NullInfoRegistry {
// private int testPosition;
//
//private NullInfoRegistryTestHarness() {
// super(FlowInfo.DEAD_END);
//}
//
// // Interface
///**
// * Return the state represented by this.
// * @return the state represented by this
// */
//NullReferenceImplTests.State asState() {
// return UnconditionalFlowInfoTestHarness.asState(this, 0);
//}
//
///**
// * Return the state represented by this for a variable encoded at a given position.
// * @param position - int the position of the considered variable
// * @return the state represented by this for a variable encoded at a given position
// */
//NullReferenceImplTests.State asState(int position) {
// return UnconditionalFlowInfoTestHarness.asState(this, position);
//}
//
//public FlowInfo copy() {
// NullInfoRegistryTestHarness copy =
// new NullInfoRegistryTestHarness();
// copy.testPosition = this.testPosition;
// UnconditionalFlowInfoTestHarness.copy(this, copy);
// return copy;
//}
//
///**
// * Return a fake null info registry derived from an unconditional flow
// * info.
// * @param upstream - UnconditionalFlowInfoTestHarness the upstream flow info
// * @return a fake null info registry derived from upstream
// */
//public static NullInfoRegistryTestHarness testNullInfoRegistry(
// UnconditionalFlowInfoTestHarness upstream) {
// NullInfoRegistry nullInfoRegistry = new NullInfoRegistry(upstream);
// NullInfoRegistryTestHarness result =
// new NullInfoRegistryTestHarness();
// result.testPosition = upstream.testPosition;
// if (result.testPosition < BitCacheSize) {
// result.nullBit1 = nullInfoRegistry.nullBit1;
// result.nullBit2 = nullInfoRegistry.nullBit2;
// result.nullBit3 = nullInfoRegistry.nullBit3;
// result.nullBit4 = nullInfoRegistry.nullBit4;
//// result.nullBit5 = nullInfoRegistry.nullBit5;
//// result.nullBit6 = nullInfoRegistry.nullBit6;
// }
// else if ((nullInfoRegistry.tagBits & NULL_FLAG_MASK) != 0){
// int vectorIndex = (result.testPosition / BitCacheSize) - 1,
// length = vectorIndex + 1;
// result.extra = new long[extraLength][];
// result.extra[0] = new long[length];
// result.extra[1] = new long[length];
// for (int j = 2; j < extraLength; j++) {
// result.extra[j] = new long[length];
// result.extra[j][vectorIndex] = nullInfoRegistry.extra[j][vectorIndex];
// }
// }
// if ((nullInfoRegistry.tagBits & NULL_FLAG_MASK) != 0) {
// result.tagBits |= NULL_FLAG_MASK;
// }
// result.maxFieldCount = 0;
// return result;
//}
//
///**
// * Return true iff this flow info can be considered as equal to the one passed
// * in parameter.
// * @param other the flow info to compare to
// * @return true iff this flow info compares equal to other
// */
//public boolean testEquals(UnconditionalFlowInfo other) {
// return UnconditionalFlowInfoTestHarness.testEquals(this, other);
//}
//
///**
// * Return true iff this flow info can be considered as equal to the one passed
// * in parameter in respect with a single local variable which id would be
// * position in a class with no field.
// * @param other the flow info to compare to
// * @param position the position of the local to consider
// * @return true iff this flow info compares equal to other for a given local
// */
//public boolean testEquals(UnconditionalFlowInfo other, int position) {
// return UnconditionalFlowInfoTestHarness.testEquals(this, other, position);
//}
//
///**
// * Return a string suitable for use as a representation of this flow info
// * within test series.
// * @return a string suitable for use as a representation of this flow info
// */
//public String testString() {
// if (this == DEAD_END) {
// return "FlowInfo.DEAD_END";
// }
// return UnconditionalFlowInfoTestHarness.testString(this, this.testPosition);
//}
//
///**
// * Return a string suitable for use as a representation of this flow info
// * within test series.
// * @param position a position to consider instead of this flow info default
// * test position
// * @return a string suitable for use as a representation of this flow info
// */
//public String testString(int position) {
// return UnconditionalFlowInfoTestHarness.testString(this, position);
//}
//}
//
//interface CodeAnalysis {
// public static final String
// definitionStartMarker = "DEFINITION START",
// definitionEndMarker = "DEFINITION END",
// initializerStartMarker = "INITIALIZER START",
// initializerEndMarker = "INITIALIZER END";
//}
//class TransitiveClosureHolder {
//static class Element {
// NullReferenceImplTests.State value;
// boolean alreadyKnown;
// Element(NullReferenceImplTests.State value) {
// if (value == null) {
// throw new IllegalArgumentException("not a valid element");
// }
// this.value = value;
// }
//}
//Map elements = new TreeMap();
//public TransitiveClosureHolder() {
// Element start = new Element(NullReferenceImplTests.State.start);
// this.elements.put(start.value, start);
//}
//void add(NullReferenceImplTests.State value) {
// if (value == null) {
// throw new IllegalArgumentException("not a valid state");
// }
// if (! this.elements.containsKey(value)) {
// this.elements.put(value, new Element(value));
// }
//}
//void add(NullReferenceImplTests.State[] values) {
// if (values == null) {
// throw new IllegalArgumentException("not a valid states set");
// }
// for (int i = 0, length = values.length; i < length; i++) {
// add(values[i]);
// }
//}
//NullReferenceImplTests.State[] asArray() {
// int length;
// NullReferenceImplTests.State[] result = new NullReferenceImplTests.State[length = this.elements.size()];
// Iterator elementsIterator = this.elements.keySet().iterator();
// for (int j = 0; j < length; j++) {
// result[j] = (NullReferenceImplTests.State) elementsIterator.next();
// }
// return result;
//}
//NullReferenceImplTests.State[] notAlreadyKnowns() {
// List resultAccumulator = new ArrayList(this.elements.size());
// Iterator i = this.elements.values().iterator();
// Element current;
// while (i.hasNext()) {
// if (! (current = (Element) i.next()).alreadyKnown) {
// resultAccumulator.add(current.value);
// }
// }
// int length;
// NullReferenceImplTests.State[] result = new NullReferenceImplTests.State[length = resultAccumulator.size()];
// for (int j = 0; j < length; j++) {
// result[j] = (NullReferenceImplTests.State) resultAccumulator.get(j);
// }
// return result;
//}
//void markAllAsAlreadyKnown() {
// Iterator i = this.elements.values().iterator();
// while (i.hasNext()) {
// ((Element) i.next()).alreadyKnown = true;
// }
//}
//public String toString() {
// StringBuffer output = new StringBuffer();
// output.append("Transitive closure:\n");
// SortedMap sorted = new TreeMap(this.elements);
// Iterator i = sorted.keySet().iterator();
// while (i.hasNext()) {
// output.append(i.next().toString());
// output.append('\n');
// }
// return output.toString();
//}
//}
//
//// PREMATURE segregate pure tooling into a separate project, keep tests only here
///**
// * The Generator class is meant to generate the tabular data needed by the
// * flow information implementation level tests. While the tests should ensure
// * non regression by leveraging their initialization tables only, any change
// * into the flow information logic or encoding is due to yield considerable
// * changes into the literal values sets of the initializers themselves.
// * Tooling the production of those literals buys us flexibility.
// * {@link #printHelp printHelp} for details.
// */
//class Generator {
//static NullReferenceImplTests.State[] computeTransitiveClosure() {
// TransitiveClosureHolder transitiveClosure = new TransitiveClosureHolder();
// NullReferenceImplTests.State[] unknowns;
// unknowns = transitiveClosure.notAlreadyKnowns();
// while (unknowns.length != 0) {
// transitiveClosure.markAllAsAlreadyKnown();
// for (int i = 0, length = NullReferenceImplTransformations.transformations.length; i < length; i ++) {
// transitiveClosure.add(
// NullReferenceImplTransformations.transformations[i].
// computeOutputs(transitiveClosure.asArray()));
// }
// unknowns = transitiveClosure.notAlreadyKnowns();
// }
// return transitiveClosure.asArray();
//}
//public static void main(String[] args) {
// if (args.length == 0) {
// printHelp(false);
// System.exit(1);
// }
// switch (args.length) {
// case 1:
// if (args[0].equals("--help")) {
// printHelp(true);
// System.exit(0);
// }
// else {
// printHelp(false);
// System.exit(1);
// }
// case 2:
// if (args[0].equals("--printTruthTables")) {
// File outputDir = new File(args[1]);
// if (outputDir.isDirectory()) {
// for (int i = 0, length = NullReferenceImplTransformations.transformations.length; i < length; i++) {
// NullReferenceImplTransformations.transformations[i].printTruthTables(outputDir);
// }
// }
// else {
// // PREMATURE error handling
// }
// System.exit(0);
// }
// else {
// printHelp(false);
// System.exit(1);
// }
// case 3:
// if (args[0].equals("--reinitializeFromComputedValues")) {
// reinitializeFromComputedValues(args[1], args[2]);
// System.out.println("Generator generated new file into " + args[2]);
// System.exit(0);
// }
// case 5:
// if (args[0].equals("--reinitializeFromComments")) {
// reinitializeFromComments(args[1], args[2], args[3], args[4]);
// System.out.println("Generator generated new files into " + args[2]
// + " and " + args[4]);
// System.exit(0);
// }
// default:
// printHelp(false);
// System.exit(1);
// }
//}
//
//private static void reinitializeFromComments(
// String statesSource, String statesTarget,
// String transformationsSource, String transformationsTarget) {
// if (statesSource.equals(transformationsSource) ||
// statesTarget.equals(transformationsTarget)) {
// throw new RuntimeException();
// }
// try {
// BufferedReader in;
// BufferedWriter out;
// NullReferenceImplTests.State.reinitializeFromComment(
// in = new BufferedReader(
// new FileReader(statesSource)),
// out = new BufferedWriter(new FileWriter(statesTarget)));
// in.close();
// out.close();
// File[] tempFiles = new File[2];
// tempFiles[0] = File.createTempFile("generator", "java");
// tempFiles[1] = File.createTempFile("generator", "java");
// NullReferenceImplTransformations.transformations[0].reinitializeFromComments(
// in = new BufferedReader(
// new FileReader(transformationsSource)),
// out = new BufferedWriter(new FileWriter(tempFiles[0])));
// in.close();
// out.close();
// int i, length;
// for (i = 1, length = NullReferenceImplTransformations.transformations.length - 1; i < length; i++) {
// NullReferenceImplTransformations.transformations[i].reinitializeFromComments(
// in = new BufferedReader(
// new FileReader(tempFiles[(i + 1) % 2])),
// out = new BufferedWriter(new FileWriter(tempFiles[i % 2])));
// in.close();
// out.close();
// }
// NullReferenceImplTransformations.transformations[i].reinitializeFromComments(
// in = new BufferedReader(
// new FileReader(tempFiles[(i + 1) % 2])),
// out = new BufferedWriter(new FileWriter(transformationsTarget)));
// in.close();
// out.close();
// } catch (Throwable t) {
// System.err.println("Generator error:");
// t.printStackTrace(System.err);
// System.exit(2);
// }
//}
//
//private static void reinitializeFromComputedValues(String source, String target) {
// for (int i = 0, length = NullReferenceImplTransformations.transformations.length;
// i < length; i++) {
// NullReferenceImplTransformations.transformations[i].hydrate();
// }
// NullReferenceImplTests.State[] transitiveClosure = computeTransitiveClosure();
// try {
// BufferedReader in;
// BufferedWriter out;
// File[] tempFiles = new File[2];
// tempFiles[0] = File.createTempFile("generator", "java");
// tempFiles[1] = File.createTempFile("generator", "java");
// NullReferenceImplTransformations.transformations[0].reinitializeFromComputedValues(
// in = new BufferedReader(
// new FileReader(source)),
// out = new BufferedWriter(new FileWriter(tempFiles[0])),
// transitiveClosure);
// in.close();
// out.close();
// int i, length;
// for (i = 1, length = NullReferenceImplTransformations.transformations.length - 1; i < length; i++) {
// NullReferenceImplTransformations.transformations[i].reinitializeFromComputedValues(
// in = new BufferedReader(
// new FileReader(tempFiles[(i + 1) % 2])),
// out = new BufferedWriter(new FileWriter(tempFiles[i % 2])),
// transitiveClosure);
// in.close();
// out.close();
// }
// NullReferenceImplTransformations.transformations[i].reinitializeFromComputedValues(
// in = new BufferedReader(
// new FileReader(tempFiles[(i + 1) % 2])),
// out = new BufferedWriter(new FileWriter(target)),
// transitiveClosure);
// in.close();
// out.close();
// } catch (Throwable t) {
// System.err.println("Generator error:");
// t.printStackTrace(System.err);
// System.exit(2);
// }
//}
//
//private static void printHelp(boolean longText) {
// if (longText) {
// System.out.println(
// "Generator use cases\n" +
// " - when a brand new logic is experimented for the transitions, the best\n" +
// " way to go is to write explicit (inefficient) transformation code within\n" +
// " UnconditionalFlowInfo, then generate the literal initializers from\n" +
// " there; use the command\n" +
// " --reinitializeFromComputedValues <source file> <target file>\n" +
// " to this effect; in case of inconsistencies or errors, messages are\n" +
// " printed to the error output stream and the result should be considered as non reliable;\n" +
// " - when only a few changes are made to state names or a specific\n" +
// " transitions, it should be possible to get the test initializers fixed\n" +
// " before UnconditionalFlowInfo implements those changes; use the command\n" +
// " --reinitializeFromComments <states source file> <states target file> <transformations source file> <transformations target file>\n" +
// " to this effect;\n" +
// " - the same command can be used when, while the semantics of the system\n" +
// " are unchanged, the encoding is modified; it should then produce the\n" +
// " initializers according to the new encoding, as defined by the comment\n" +
// " for State.states, and the transformations as defined by their\n" +
// " respective comment;\n" +
// " - when a given encoding is retained, its optimization may leverage truth\n" +
// " tables; use the --printTruthTables command to this effect.\n" +
// " \n\n");
// printHelp(false);
// }
// else {
// System.out.println(
// "Usage:\n" +
// "Generator --help\n" +
// " prints a more detailed help message\n" +
// "Generator --printTruthTables\n" +
// " prints the truth tables of the transformations\n" +
// "Generator --reinitializeFromComments <source file> <target file>\n" +
// " generates into target file a copy of source file into which\n" +
// " transformations initializers have been reset from their definitions\n" +
// "Generator --reinitializeFromComputedValues <source file> <target file>\n" +
// " generates into target file a copy of source file into which\n" +
// " transformations definitions and initializers have been reset\n" +
// " according to the behavior of the current UnconditionalFlowInfo\n"
// );
// }
//}
//}