const {pythonCode, sep1} = require('./python');
module.exports = grammar({
name: 'bitbake',
conflicts: $ => [
[$.primary_expression, $.pattern],
[$.primary_expression, $.list_splat_pattern],
[$.tuple, $.tuple_pattern],
[$.list, $.list_pattern],
[$.with_item, $._collection_elements],
[$.named_expression, $.as_pattern],
[$.print_statement, $.primary_expression],
],
externals: $ => [
$._concat,
$._newline,
$._indent,
$._dedent,
$.string_start,
$._string_content,
$.escape_interpolation,
$.string_end,
$.comment,
']',
')',
'}',
$.shell_content,
],
extras: $ => [
/\s/,
$.comment,
],
inline: $ => [
$._simple_statement,
$._compound_statement,
$._suite,
$._expressions,
$._left_hand_side,
$.keyword_identifier,
$._dotted_identifier,
],
supertypes: $ => [
$._simple_statement,
$._compound_statement,
$.expression,
$.primary_expression,
$.pattern,
$.parameter,
],
rules: {
recipe: $ => repeat(seq(
choice(
$.variable_assignment,
$.unset_statement,
$.inherit_directive,
$.include_directive,
$.require_directive,
$.export_statement,
$.overrides_statement,
$.export_functions_statement,
$.addtask_statement,
$.deltask_statement,
$.addhandler_statement,
$.anonymous_python_function,
$.function_definition,
$.python_function_definition,
),
choice(/\r?\n/, '\0'),
)),
variable_assignment: $ => seq(
choice($.identifier, $.concatenation),
optional(choice(
$.variable_flag,
$.variable_expansion,
$.override,
)),
field('operator',
choice(
'=',
'?=',
'??=',
':=',
'+=',
'=+',
'.=',
'=.',
),
),
$.literal,
),
variable_flag: $ => seq(
'[',
choice(
'noexec',
alias(/[^ \r\n\]]+/, $.flag),
),
']',
),
override: $ => seq(
':',
sep1(
choice(
'append',
'prepend',
'remove',
seq($.identifier, optional($.variable_flag)),
$.variable_expansion,
$.concatenation,
),
':',
),
),
unset_statement: $ => seq(
'unset',
$.identifier,
optional($.variable_flag),
),
inherit_directive: $ => seq(
'inherit',
repeat1(choice(
$.variable_expansion,
$.inline_python,
$.inherit_path,
)),
),
inherit_path: _ => /[^$ \r\n][^ \r\n]+/,
inherit_configuration_directive: $ => seq(
'INHERIT',
'+=',
'"',
sep1($.identifier, ' '),
'"',
),
include_directive: $ => seq(
'include',
alias(/[^ \r\n]+/, $.include_path),
),
require_directive: $ => seq(
'require',
alias(/[^ \r\n]+/, $.include_path),
),
export_statement: $ => seq(
'export',
choice($.identifier, $.variable_assignment),
),
overrides_statement: $ => seq(
'OVERRIDES',
'=',
'"',
sep1($.identifier, ':'),
'"',
),
export_functions_statement: $ => seq(
'EXPORT_FUNCTIONS',
repeat1($.identifier),
),
addtask_statement: $ => seq(
'addtask',
$.identifier,
optional(choice(
seq(
'after',
repeat1($.identifier),
optional(seq(
'before',
repeat1($.identifier),
)),
),
seq(
'before',
repeat1($.identifier),
optional(seq(
'after',
repeat1($.identifier),
)),
),
)),
),
deltask_statement: $ => seq(
'deltask',
$.identifier,
),
addhandler_statement: $ => seq(
'addhandler',
$.identifier,
),
anonymous_python_function: $ => seq(
optional('fakeroot'),
'python',
optional(seq(
$.identifier,
optional($.override),
)),
'(',
')',
'{',
$._suite,
'}',
),
function_definition: $ => seq(
optional('fakeroot'),
$.identifier,
optional($.override),
'(',
')',
'{',
repeat(choice(
$.shell_content,
$.inline_python,
)),
'}',
),
literal: $ => choice(
$.string,
$.identifier,
),
string: $ => choice(
seq(
'"',
repeat(choice(
alias(token.immediate(prec(1, /([^"$\\]|\\.?|\\?\r?\n)+/)), $.string_content),
/"[^"$\\\s]+"/,
$.variable_expansion,
$.inline_python,
'$BB_ENV_PASSTHROUGH',
'$BB_ENV_PASSTHROUGH_ADDITIONS',
alias(token(prec(-1, '$')), $.string_content),
)),
'"',
),
seq(
'\'',
repeat(choice(
alias(token.immediate(prec(1, /([^'$\\]|\\?\r?\n)+/)), $.string_content),
token(prec(-1, /"[^"$\\\s]+"/)),
$.variable_expansion,
$.inline_python,
'$BB_ENV_PASSTHROUGH',
'$BB_ENV_PASSTHROUGH_ADDITIONS',
)),
'\'',
),
),
inline_python: $ => seq('${@', $.expression, '}'),
variable_expansion: $ => seq('${', optional($.identifier), '}'),
...pythonCode,
concatenation: $ => prec(-1, seq(
choice($.identifier, $.variable_expansion, $._dotted_identifier),
repeat1(seq(
$._concat,
choice($.identifier, $.variable_expansion, $._dotted_identifier),
)),
optional($._concat),
)),
identifier: _ => /[a-zA-Z0-9_-]+/,
_dotted_identifier: $ => alias(/[.a-zA-Z0-9_-]+/, $.identifier),
comment: _ => token(seq('#', /.*/)),
},
});