// Returns the indices for the objects to check contracts over. // // If an element is primitive, a String, or null, its index is not returned. // // The indices are returned as a map, from types to the indices of // the given type. Binary contracts are only checked for objects // of equal types, so themap is handy. private static MultiMap<Class<?>, Integer> objectIndicesToCheck( ExecutableSequence s, int maxIdx) { MultiMap<Class<?>, Integer> map = new MultiMap<Class<?>, Integer>(); for (int i = 0; i <= maxIdx; i++) { ExecutionOutcome result = s.getResult(i); assert result instanceof NormalExecution; Class<?> outputType = s.sequence.getStatementKind(i).getOutputType(); if (outputType.equals(void.class)) continue; if (outputType.equals(String.class)) continue; if (PrimitiveTypes.isPrimitive(outputType)) continue; Object runtimeValue = ((NormalExecution) result).getRuntimeValue(); if (runtimeValue == null) continue; map.add(outputType, i); } return map; }
/** * Determines what indices in the given sequence are active. An active index i means that the i-th * method call creates an interesting/useful value that can be used as an input to a larger * sequence; inactive indices are never used as inputs. The effect of setting active/inactive * indices is that the SequenceCollection to which the given sequences is added only considers the * active indices when deciding whether the sequence creates values of a given type. * * <p>In addition to determining active indices, this method determines if any primitive values * created during execution of the sequence are new values not encountered before. Such values are * added to the component manager so they can be used during subsequent generation attempts. */ public void processSequence(ExecutableSequence seq) { Tracer.trace("processSequence"); if (GenInputsAbstract.offline) { Tracer.trace("offline@processSequence"); if (Log.isLoggingOn()) { Log.logLine( "Making all indices active (offline generation specified; sequences are not executed)."); } seq.sequence.setAllActiveFlags(); return; } Tracer.trace("NOT offline@processSequence"); if (seq.hasNonExecutedStatements()) { if (Log.isLoggingOn()) { Log.logLine( "Making all indices inactive (sequence has non-executed statements, so judging it inadequate for further extension)."); } seq.sequence.clearAllActiveFlags(); return; } if (seq.hasFailure()) { if (Log.isLoggingOn()) { Log.logLine( "Making all indices inactive (sequence reveals a failure, so judging it inadequate for further extension)"); } seq.sequence.clearAllActiveFlags(); return; } if (!seq.isNormalExecution()) { if (Log.isLoggingOn()) { Log.logLine( "Making all indices inactive (exception thrown, or failure revealed during execution)."); } seq.sequence.clearAllActiveFlags(); return; } // If runtime value is a primitive value, clear active flag, and // if the value is new, add a sequence corresponding to that value. for (int i = 0; i < seq.sequence.size(); i++) { // type ensured by isNormalExecution clause ealier in this method. NormalExecution e = (NormalExecution) seq.getResult(i); Object runtimeValue = e.getRuntimeValue(); if (runtimeValue == null) { if (Log.isLoggingOn()) { Log.logLine("Making index " + i + " inactive (value is null)"); } seq.sequence.clearActiveFlag(i); continue; } Class<?> objectClass = runtimeValue.getClass(); Tracer.trace("processSequence-useobjcache"); if (PrimitiveTypes.isBoxedOrPrimitiveOrStringType(objectClass)) { if (Log.isLoggingOn()) { Log.logLine("Making index " + i + " inactive (value is a primitive)"); } seq.sequence.clearActiveFlag(i); boolean looksLikeObjToString = (runtimeValue instanceof String) && PrimitiveTypes.looksLikeObjectToString((String) runtimeValue); boolean tooLongString = (runtimeValue instanceof String) && !PrimitiveTypes.stringLengthOK((String) runtimeValue); if (!looksLikeObjToString && !tooLongString && runtimePrimitivesSeen.add(runtimeValue)) { // Have not seen this value before; add it to the component set. componentManager.addGeneratedSequence( PrimitiveOrStringOrNullDecl.sequenceForPrimitive(runtimeValue)); } } else if (GenInputsAbstract.use_object_cache) { Tracer.trace("use_object_cache@processSequence-useobjcache"); objectCache.setActiveFlags(seq, i); } else { if (Log.isLoggingOn()) { Log.logLine("Making index " + i + " active."); } } } }