syntax_updater: Experimental support for input/output properties

This commit is contained in:
Olivier Goffart 2022-09-26 16:50:29 +02:00 committed by Olivier Goffart
parent bc4e57949c
commit 98a922bf42
3 changed files with 64 additions and 8 deletions

View file

@ -70,6 +70,18 @@ pub fn parse_element_content(p: &mut impl Parser) {
_ if p.peek().as_str() == "if" => {
parse_if_element(&mut *p);
}
SyntaxKind::Identifier if p.nth(1).as_str() == "property" => {
if matches!(p.peek().as_str(), "input" | "output" | "inout") {
// TODO: in/out property #191
parse_property_declaration(&mut *p);
} else {
p.consume();
if !had_parse_error {
p.error("Parse error");
had_parse_error = true;
}
}
}
SyntaxKind::LBracket if p.peek().as_str() == "states" => {
parse_states(&mut *p);
}
@ -322,14 +334,18 @@ fn parse_callback_declaration(p: &mut impl Parser) {
#[cfg_attr(test, parser_test)]
/// ```test,PropertyDeclaration
/// input property <int> xxx;
/// property<int> foobar;
/// property<string> text: "Something";
/// property<string> text <=> two.way;
/// property alias <=> two.way;
/// ```
fn parse_property_declaration(p: &mut impl Parser) {
debug_assert_eq!(p.peek().as_str(), "property");
let mut p = p.start_node(SyntaxKind::PropertyDeclaration);
if p.peek().as_str() != "property" {
p.consume(); // input/output/inout
}
debug_assert_eq!(p.peek().as_str(), "property");
p.consume(); // property
if p.test(SyntaxKind::LAngle) {

View file

@ -0,0 +1,30 @@
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
use crate::Cli;
use i_slint_compiler::parser::{SyntaxKind, SyntaxNode};
use std::io::Write;
pub(crate) fn fold_node(
node: &SyntaxNode,
file: &mut impl Write,
_state: &mut crate::State,
args: &Cli,
) -> std::io::Result<bool> {
debug_assert!(args.input_output_properties);
let kind = node.kind();
if kind == SyntaxKind::PropertyDeclaration
&& node
.parent()
.and_then(|n| n.parent())
.map_or(false, |n| n.kind() == SyntaxKind::Component)
{
// check that the first identifier is "property" as opposed to an already converted "inout" token
if node.child_token(SyntaxKind::Identifier).map_or(false, |t| t.text() == "property") {
// Consider that all property are inout, because we don't do enough analysis in the syntax_updater to know
// if they should be private
write!(file, "inout ")?;
}
}
Ok(false)
}

View file

@ -27,6 +27,7 @@ use std::path::Path;
use std::rc::Rc;
mod experiments {
pub(super) mod input_output_properties;
pub(super) mod lookup_changes;
}
@ -42,11 +43,15 @@ pub struct Cli {
/// Do the lookup changes from issue #273
#[clap(long, action)]
experimental_lookup_changes: bool,
fully_qualify: bool,
/// Move all properties declaration to root
/// Move all properties declaration to root (implies fully_qualify)
#[clap(long, action)]
experimental_move_declaration: bool,
move_declaration: bool,
/// Mark top level property as `inout` #191
#[clap(long, action)]
input_output_properties: bool,
}
fn main() -> std::io::Result<()> {
@ -164,7 +169,7 @@ fn process_file(
let syntax_node = i_slint_compiler::parser::parse(source.clone(), Some(path), &mut diag);
let len = syntax_node.node.text_range().end().into();
let mut state = State::default();
if args.experimental_lookup_changes {
if args.fully_qualify {
let doc = syntax_node.clone().into();
let mut type_loader = TypeLoader::new(
i_slint_compiler::typeregister::TypeRegister::builtin(),
@ -233,13 +238,13 @@ fn visit_node(
syntax_nodes::Component::from(node.clone()).DeclaredIdentifier().to_string();
state.current_component =
doc.inner_components.iter().find(|c| c.id == component_name).cloned();
if args.experimental_move_declaration {
if args.move_declaration {
experiments::lookup_changes::collect_movable_properties(&mut state);
}
}
}
SyntaxKind::RepeatedElement | SyntaxKind::ConditionalElement => {
if args.experimental_move_declaration {
if args.move_declaration {
experiments::lookup_changes::collect_movable_properties(&mut state);
}
}
@ -293,7 +298,12 @@ fn fold_node(
state: &mut State,
args: &Cli,
) -> std::io::Result<bool> {
if (args.experimental_lookup_changes || args.experimental_move_declaration)
if args.input_output_properties
&& experiments::input_output_properties::fold_node(node, file, state, args)?
{
return Ok(true);
}
if (args.fully_qualify || args.move_declaration)
&& experiments::lookup_changes::fold_node(node, file, state, args)?
{
return Ok(true);