/** * Returns a sequence that creates an object of type compatible the given class. Wraps the object * in a list, and returns the list. * * <p>CURRENTLY, will return a sequence (i.e. a non-empty list) only if cls is an array. */ public static SimpleList<Sequence> createSequence(ComponentManager components, Class<?> cls) { // Class<?> cls = statement.getInputTypes().get(i); if (!cls.isArray()) { return new ArrayListSimpleList<Sequence>(); } Sequence s = null; if (cls.getComponentType().isPrimitive()) { s = randPrimitiveArray(cls.getComponentType()); } else { SimpleList<Sequence> candidates = components.getSequencesForType(cls.getComponentType(), false); if (candidates.isEmpty()) { if (GenInputsAbstract.forbid_null) { // No sequences that produce appropriate component values found, and null forbidden. // Return the empty array. ArrayDeclaration decl = new ArrayDeclaration(cls.getComponentType(), 0); s = new Sequence(); s = s.extend(decl); } else { // No sequences that produce appropriate component values found, and null allowed. // TODO: We should also randomly return the empty array--it's a perfectly good case // even if null is allowed. // Return the array [ null ]. ArrayDeclaration decl = new ArrayDeclaration(cls.getComponentType(), 1); s = new Sequence(); s = s.extend(PrimitiveOrStringOrNullDecl.nullOrZeroDecl(cls.getComponentType())); List<Variable> ins = new ArrayList<Variable>(); ins.add(s.getVariable(0)); s = s.extend(decl, ins); } } else { // Return the array [ x ] where x is the last value in the sequence. ArrayDeclaration decl = new ArrayDeclaration(cls.getComponentType(), 1); s = candidates.get(Randomness.nextRandomInt(candidates.size())); List<Variable> ins = new ArrayList<Variable>(); // XXX IS THIS OLD COMMENT TRUE? : this assumes that last statement will have such a var, // which I know is currently true because of SequenceCollection implementation. ins.add( s.randomVariableForTypeLastStatement(cls.getComponentType(), Match.COMPATIBLE_TYPE)); s = s.extend(decl, ins); } } assert s != null; ArrayListSimpleList<Sequence> l = new ArrayListSimpleList<Sequence>(); l.add(s); return l; }
private static Sequence randPrimitiveArray(Class<?> componentType) { assert componentType.isPrimitive(); Set<Object> potentialElts = SeedSequences.getSeeds(componentType); int length = Randomness.nextRandomInt(4); Sequence s = new Sequence(); List<Variable> emptylist = new ArrayList<Variable>(); for (int i = 0; i < length; i++) { Object elt = Randomness.randomSetMember(potentialElts); s = s.extend(new PrimitiveOrStringOrNullDecl(componentType, elt), emptylist); } List<Variable> inputs = new ArrayList<Variable>(); for (int i = 0; i < length; i++) { inputs.add(s.getVariable(i)); } s = s.extend(new ArrayDeclaration(componentType, length), inputs); return s; }
public static Sequence predecessorSequence(Sequence s, int idx) { List<Integer> indices = new ArrayList<Integer>(predecessors(s, idx)); indices.add(idx); // Also add the index corresponding to the requested statement index. Collections.sort(indices); Map<Integer, Integer> newIdx = new LinkedHashMap<Integer, Integer>(); for (int j = 0; j < indices.size(); j++) { newIdx.put(indices.get(j), j); } Sequence news = new Sequence(); for (int i = 0; i < indices.size(); i++) { int oldidx = indices.get(i); List<Variable> oldins = s.getInputs(oldidx); List<Variable> newins = new ArrayList<Variable>(oldins.size()); for (Variable oldv : oldins) { newins.add(news.getVariable(newIdx.get(oldv.index))); } news = news.extend(s.getStatementKind(oldidx), newins); } return news; }
public static Set<Integer> predecessors(Sequence s, int idx) { Set<Integer> ret = new LinkedHashSet<Integer>(); Set<Variable> depvars = new LinkedHashSet<Variable>(s.getInputs(idx)); for (int i = idx - 1; i >= 0; i--) { boolean toadd = false; if (depvars.contains(s.getVariable(i))) { toadd = true; } else { for (Variable v : s.getInputs(i)) { if (depvars.contains(v)) { toadd = true; break; } } } if (toadd) { ret.add(i); depvars.addAll(s.getInputs(i)); } } return ret; }
public static Sequence getLongestDepSetSubSequence(Sequence s) { BitSet indices = longestDepSet(s, s.size() - 1); int length = indices.length(); assert indices.get(length - 1); Map<Integer, Integer> newIdx = new LinkedHashMap<Integer, Integer>(); int count = 0; for (int i = 0; i < length; i++) { if (!indices.get(i)) continue; newIdx.put(i, count++); } Sequence news = new Sequence(); for (int i = 0; i < length; i++) { if (!indices.get(i)) continue; List<Variable> oldins = s.getInputs(i); List<Variable> newins = new ArrayList<Variable>(oldins.size()); for (Variable oldv : oldins) { newins.add(news.getVariable(newIdx.get(oldv.index))); } news = news.extend(s.getStatementKind(i), newins); } return news; }
/** * Tries to create and execute a new sequence. If the sequence is new (not already in the * specified component manager), then it is executed and added to the manager's sequences. If the * sequence created is already in the manager's sequences, this method has no effect, and returns * null. */ private ExecutableSequence createNewUniqueSequence() { Tracer.trace("createNewUniqueSequence"); if (Log.isLoggingOn()) Log.logLine("-------------------------------------------"); StatementKind statement = null; if (this.statements.isEmpty()) return null; // Select a StatementInfo statement = Randomness.randomMember(this.statements); if (Log.isLoggingOn()) Log.logLine("Selected statement: " + statement.toString()); // jhp: add flags here InputsAndSuccessFlag sequences = selectInputs(statement); if (!sequences.success) { if (Log.isLoggingOn()) Log.logLine("Failed to find inputs for statement."); return null; } Sequence concatSeq = Sequence.concatenate(sequences.sequences); // Figure out input variables. List<Variable> inputs = new ArrayList<Variable>(); for (Integer oneinput : sequences.indices) { Variable v = concatSeq.getVariable(oneinput); inputs.add(v); } Sequence newSequence = concatSeq.extend(statement, inputs); // With .5 probability, do a primitive value heuristic. Tracer.trace("heuristic-uniquesequence"); if (GenInputsAbstract.repeat_heuristic && Randomness.nextRandomInt(10) == 0) { Tracer.trace("repeat_heuristic@heuristic-uniquesequence"); int times = Randomness.nextRandomInt(100); newSequence = newSequence.repeatLast(times); if (Log.isLoggingOn()) Log.log(">>>" + times + newSequence.toCodeString()); } Tracer.trace("NO_repeat_heuristic@heuristic-uniquesequence"); // If parameterless statement, subsequence inputs // will all be redundant, so just remove it from list of statements. if (statement.getInputTypes().size() == 0) { statements.remove(statement); } // If sequence is larger than size limit, try again. Tracer.trace("evaluating-maxsize"); if (newSequence.size() > GenInputsAbstract.maxsize) { Tracer.trace(">maxsize@evaluating-maxsize"); if (Log.isLoggingOn()) Log.logLine( "Sequence discarded because size " + newSequence.size() + " exceeds maximum allowed size " + GenInputsAbstract.maxsize); return null; } Tracer.trace("<maxsize@evaluating-maxsize"); randoopConsistencyTests(newSequence); if (this.allSequences.contains(newSequence)) { Tracer.trace("discard existing"); if (Log.isLoggingOn()) Log.logLine("Sequence discarded because the same sequence was previously created."); return null; } this.allSequences.add(newSequence); for (Sequence s : sequences.sequences) { s.lastTimeUsed = java.lang.System.currentTimeMillis(); } randoopConsistencyTest2(newSequence); if (Log.isLoggingOn()) { Log.logLine("Successfully created new unique sequence:" + newSequence.toString()); } // System.out.println("###" + statement.toStringVerbose() + "###" + statement.getClass()); // Keep track of any input sequences that are used in this sequence // Tests that contain only these sequences are probably redundant for (Sequence is : sequences.sequences) { subsumed_sequences.add(is); } return new ExecutableSequence(newSequence); }