private void collectWorkerDefinitions()

in doc-architect/doc-architect-core/src/main/java/com/docarchitect/core/scanner/impl/ruby/SidekiqScanner.java [214:290]


    private void collectWorkerDefinitions(Path file, Map<String, WorkerDefinition> workerDefinitions) throws IOException {
        List<String> lines = readFileLines(file);
        String componentId = extractModuleName(file);

        List<String> moduleStack = new ArrayList<>();

        for (int i = 0; i < lines.size(); i++) {
            String line = lines.get(i);

            // Track module nesting
            Matcher moduleMatcher = MODULE_DEFINITION_PATTERN.matcher(line);
            if (moduleMatcher.find()) {
                moduleStack.add(moduleMatcher.group(1));
                continue;
            }

            // Check for class definition
            Matcher classMatcher = CLASS_DEFINITION_PATTERN.matcher(line);
            if (classMatcher.find()) {
                String className = classMatcher.group(1);

                // Build fully qualified class name with module namespace
                String fullyQualifiedName = className;
                if (!moduleStack.isEmpty() && !className.contains("::")) {
                    // Only prepend module if class name doesn't already have namespace
                    fullyQualifiedName = String.join("::", moduleStack) + "::" + className;
                }

                // Check if this class includes Sidekiq::Worker or ApplicationWorker
                boolean isSidekiqWorker = false;
                String queueName = null;

                // Look ahead for include Sidekiq::Worker and sidekiq_options
                for (int j = i + 1; j < Math.min(i + MAX_CLASS_SEARCH_LINES, lines.size()); j++) {
                    String lookAheadLine = lines.get(j);

                    // Stop at next class definition
                    if (CLASS_DEFINITION_PATTERN.matcher(lookAheadLine).find()) {
                        break;
                    }

                    // Check for Sidekiq worker include
                    if (WORKER_INCLUDE_PATTERN.matcher(lookAheadLine).find()) {
                        isSidekiqWorker = true;
                    }

                    // Check for sidekiq_options queue
                    Matcher optionsMatcher = SIDEKIQ_OPTIONS_PATTERN.matcher(lookAheadLine);
                    if (optionsMatcher.find()) {
                        queueName = optionsMatcher.group(1);
                    }

                    // Stop at 'end' that likely closes the class (simplified check)
                    if (lookAheadLine.trim().equals("end")) {
                        break;
                    }
                }

                if (isSidekiqWorker) {
                    WorkerDefinition workerDef = new WorkerDefinition(
                        fullyQualifiedName,
                        componentId,
                        queueName != null ? queueName : DEFAULT_QUEUE
                    );

                    workerDefinitions.put(fullyQualifiedName, workerDef);
                    log.debug("Found Sidekiq worker: {} in queue: {}", fullyQualifiedName, workerDef.queueName);
                }
            }

            // Handle 'end' statements - pop module stack when we see 'end'
            // This is simplified - a proper implementation would track nesting depth
            if (line.trim().equals("end") && !moduleStack.isEmpty()) {
                moduleStack.remove(moduleStack.size() - 1);
            }
        }
    }