TreeSitterHighlightConfiguration constructor

TreeSitterHighlightConfiguration({
  1. required TreeSitterLanguageTable language,
  2. required String languageName,
  3. required String highlightsQuery,
  4. String injectionsQuery = '',
  5. String localsQuery = '',
})

Implementation

factory TreeSitterHighlightConfiguration({
  required TreeSitterLanguageTable language,
  required String languageName,
  required String highlightsQuery,
  String injectionsQuery = '',
  String localsQuery = '',
}) {
  final supertypeRelations = <String, List<String>>{
    for (final type in language.queryNodeTypes)
      if (type.subtypes.isNotEmpty)
        type.type: [for (final subtype in type.subtypes) subtype.type],
  };
  final compiler = TreeSitterScmHighlightQueryCompiler(
    supertypeRelations: supertypeRelations,
  );
  final querySource = '$injectionsQuery$localsQuery$highlightsQuery';
  final localsOffset = _utf8Length(injectionsQuery);
  final highlightsOffset = localsOffset + _utf8Length(localsQuery);
  final query = compiler.compile(
    querySource,
    language: language,
    preserveAnonymousLiterals: true,
  );
  var localsPatternIndex = 0;
  var highlightsPatternIndex = 0;
  for (var index = 0; index < query.patternCount; index++) {
    final offset = query.startByteForPattern(index);
    if (offset < highlightsOffset) {
      highlightsPatternIndex++;
      if (offset < localsOffset) localsPatternIndex++;
    }
  }

  final combinedQuery = compiler.compile(
    injectionsQuery,
    language: language,
    preserveAnonymousLiterals: true,
  );
  var hasCombined = false;
  for (var index = 0; index < localsPatternIndex; index++) {
    final settings = _settingsForPattern(query, index);
    if (settings.containsKey('injection.combined')) {
      hasCombined = true;
      query.disablePattern(index);
    } else {
      combinedQuery.disablePattern(index);
    }
  }

  final nonLocalVariablePatterns = <bool>[
    for (var index = 0; index < query.patternCount; index++)
      _predicatesForPattern(query, index).any(
        (predicate) =>
            predicate.predicate.operator ==
                TreeSitterQueryPredicateOperator.isNotProperty &&
            predicate.predicate.values.isNotEmpty &&
            predicate.predicate.values.first == 'local',
      ),
  ];

  int? captureIndex(String name) {
    final index = query.captureNames.indexOf(name);
    return index < 0 ? null : index;
  }

  return TreeSitterHighlightConfiguration._(
    language: language,
    languageName: languageName,
    query: query,
    combinedInjectionsQuery: hasCombined ? combinedQuery : null,
    localsPatternIndex: localsPatternIndex,
    highlightsPatternIndex: highlightsPatternIndex,
    highlightIndices: List<TreeSitterHighlight?>.filled(
      query.captureNames.length,
      null,
    ),
    nonLocalVariablePatterns: List.unmodifiable(nonLocalVariablePatterns),
    injectionContentCaptureIndex: captureIndex('injection.content'),
    injectionLanguageCaptureIndex: captureIndex('injection.language'),
    localDefinitionCaptureIndex: captureIndex('local.definition'),
    localDefinitionValueCaptureIndex: captureIndex('local.definition-value'),
    localReferenceCaptureIndex: captureIndex('local.reference'),
    localScopeCaptureIndex: captureIndex('local.scope'),
  );
}