compileFrame static method

Danger<FileSystemModelList<FileSystemModel>, CitrusLanguageException> compileFrame(
  1. CitrusSymbolTable symbolTable,
  2. TemplateFileSetting templateFileSetting
)

Implementation

static Danger<FileSystemModelList<FileSystemModel>, CitrusLanguageException> compileFrame(CitrusSymbolTable symbolTable, TemplateFileSetting templateFileSetting) {

    final log = Log(classLocation: CitrusLanguage, functionLocation: 'compileFrame');

    final nestFormResult = FileSystemModelRouteRoster.fromNestForm([], templateFileSetting.template);
    log.add(nestFormResult);
    if (nestFormResult is! Success<FileSystemModelRouteRoster<FileSystemModelRoute>, FileSystemModelExceptionV>) return Failure(CitrusLanguageExceptionE(), log);

    FileSystemModelRouteRoster<FileSystemModelRoute> base = nestFormResult.wrapped;

    final List<FileSystemModelRoute> definition = [];

    // frame の処理の exception は失敗として user に報告する.
    //  無限ループを防ぐため
    // frame semantic が無い場合 base が削除されていき while は止まる.
    while (true) {

        base = base.sort((a, b) => a.route.length.compareTo(b.route.length));

        final fileSystemModel = base.firstOrNull;
        if (fileSystemModel == null) break;

        // 構造変化は name 部分だけに記述がある
        final rootCitrusSyntaxResult = RootCitrusSyntax.fromFrameSource(fileSystemModel.name);
        log.add(rootCitrusSyntaxResult);

        final frameResult = Frame.fromRootCitrusSyntax(rootCitrusSyntaxResult.wrapped);
        log.add(frameResult);
        final frame = frameResult.wrapped;

        // 解析したものは base から削除する
        final removeResult = base.remove(fileSystemModel.route);
        log.add(removeResult);
        // 必ず存在する route なので throw out.
        if (removeResult is! Success<FileSystemModelRouteRoster<FileSystemModelRoute>, FileSystemModelExceptionW>) Result.panic(CitrusLanguageErrorA(), log);

        base = removeResult.wrapped;

        switch (frame.frameCitrusSemanticList.length) {
        // 存在しない場合 変化しないのでそのまま definition へ追加する.
        case 0:

            definition.add(fileSystemModel);

        // frame semantic が 1つ以上存在する場合 resolve の結果を base に追加する.
        //  それらはまた解析されるので frame semantic が無くなるまで繰り返される.
        case _:

            final result = frame.resolve(symbolTable, fileSystemModel, base);
            log.add(result);
            if (result is! Success<Iterable<FileSystemModelRoute>, CitrusSemanticException>) return Failure(result.asException, log);

            final addResult = base.add(result.wrapped);
            log.add(addResult);
            if (addResult is! Success<FileSystemModelRouteRoster<FileSystemModelRoute>, FileSystemModelExceptionV>) return Failure(CitrusLanguageExceptionF(), log);

            base = addResult.wrapped;

        }

    }

    // log.debug({'definition': definition});

    final routeResult = FileSystemModelRouteRoster.result(definition);
    log.add(routeResult);
    if (routeResult is! Success<FileSystemModelRouteRoster<FileSystemModelRoute>, FileSystemModelExceptionV>) return Failure(CitrusLanguageExceptionC(), log);

    // log.debug({'routeResult': routeResult.wrapped});

    final result = FileSystemModelList.fromRouteForm(routeResult.wrapped);
    log.add(result);

    return Success(result.wrapped, log);

}