private static void readTestStructureFromClass()

in src/jvm/main/org/jetbrains/kotlinx/lincheck/CTestStructure.java [110:194]


    private static void readTestStructureFromClass(
            Class<?> clazz,
            Map<String, OperationGroup> groupConfigs,
            List<ActorGenerator> actorGenerators,
            Map<Class<?>, ParameterGenerator<?>> parameterGeneratorsMap,
            List<Actor> validationFunctions,
            List<Method> stateRepresentations,
            RandomProvider randomProvider
    ) {
        // Read named parameter generators (declared for class)
        Map<String, ParameterGenerator<?>> namedGens = createNamedGens(clazz, randomProvider);
        // Create map for default (not named) gens
        Map<Class<?>, ParameterGenerator<?>> defaultGens = createDefaultGenerators(randomProvider);
        // Read group configurations
        for (org.jetbrains.kotlinx.lincheck.annotations.OpGroupConfig opGroupConfigAnn :
             clazz.getAnnotationsByType(org.jetbrains.kotlinx.lincheck.annotations.OpGroupConfig.class))
        {
            groupConfigs.put(
                opGroupConfigAnn.name(),
                new OperationGroup(opGroupConfigAnn.name(), opGroupConfigAnn.nonParallel())
            );
        }

        // Process class methods
        for (Method m : getDeclaredMethodSorted(clazz)) {
            // Operation
            OperationConfig opConfig = parseOperationAnnotation(m);
            if (opConfig != null) {
                boolean isSuspendableMethod = isSuspendable(m);
                // Check that params() in @Operation is empty or has the same size as the method
                if (opConfig.getParams().length > 0 && opConfig.getParams().length != m.getParameterCount()) {
                    throw new IllegalArgumentException("Invalid count of parameter generators for " + m);
                }
                // Construct a list of parameter generators
                final List<ParameterGenerator<?>> gens = new ArrayList<>();
                int nParameters = m.getParameterCount() - (isSuspendableMethod ? 1 : 0);
                for (int i = 0; i < nParameters; i++) {
                    String nameInOperation = opConfig.getParams().length > 0 ? opConfig.getParams()[i] : null;
                    Parameter parameter = m.getParameters()[i];
                    ParameterGenerator<?> parameterGenerator = getOrCreateGenerator(m,
                            parameter,
                            nameInOperation,
                            namedGens,
                            defaultGens,
                            randomProvider
                    );
                    parameterGeneratorsMap.putIfAbsent(parameter.getType(), parameterGenerator);
                    gens.add(parameterGenerator);
                }
                ActorGenerator actorGenerator = new ActorGenerator(m, gens, opConfig.isRunOnce(),
                    opConfig.isCancellableOnSuspension(), opConfig.isBlocking(), opConfig.isCausesBlocking(),
                    opConfig.isPromptCancellation());
                actorGenerators.add(actorGenerator);
                // Get list of groups and add this operation to specified ones
                String opGroup = opConfig.getGroup();
                if (!opGroup.isEmpty()) {
                    OperationGroup operationGroup = groupConfigs.get(opGroup);
                    if (operationGroup == null)
                        throw new IllegalStateException("Operation group " + opGroup + " is not configured");
                    operationGroup.actors.add(actorGenerator);
                }
                String opNonParallelGroupName = opConfig.getNonParallelGroup();
                if (!opNonParallelGroupName.isEmpty()) { // is `nonParallelGroup` specified?
                    groupConfigs.computeIfAbsent(opNonParallelGroupName, name -> new OperationGroup(name, true));
                    groupConfigs.get(opNonParallelGroupName).actors.add(actorGenerator);
                }
            }

            ValidateConfig validateConfig = parseValidateAnnotation(m);
            if (validateConfig != null) {
                if (m.getParameterCount() != 0)
                    throw new IllegalStateException("Validation function " + m.getName() + " should not have parameters");
                validationFunctions.add(new Actor(m, Collections.emptyList()));
            }

            StateRepresentationConfig stateRepConfig = parseStateRepresentationAnnotation(m);
            if (stateRepConfig != null) {
                if (m.getParameterCount() != 0)
                    throw new IllegalStateException("State representation function " + m.getName() + " should not have parameters");
                if (m.getReturnType() != String.class)
                    throw new IllegalStateException("State representation function " + m.getName() + " should have String return type");
                stateRepresentations.add(m);
            }
        }
    }