diff --git a/docs/testing.md b/docs/testing.md index 922404db3e2..758e27e0fb6 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -10,14 +10,14 @@ The syntax tests are testing that the compiler show the right error messages in The syntax tests are located in [internal/compiler/tests/syntax/](../internal/compiler/tests/syntax/) and it's driven by the [`syntax_tests.rs`](../internal/compiler/tests/syntax_tests.rs) file. More info in the comments of that file. -In summary, each .slint files have comments with `^error` like so: +In summary, each .slint files have comments with `> ` and `<` arrows. Ideally, each error message must be tested like so. diff --git a/internal/compiler/diagnostics.rs b/internal/compiler/diagnostics.rs index fcf5034ef45..33dc2081850 100644 --- a/internal/compiler/diagnostics.rs +++ b/internal/compiler/diagnostics.rs @@ -10,12 +10,13 @@ use std::collections::BTreeSet; /// Span represent an error location within a file. /// -/// Currently, it is just an offset in byte within the file. +/// Currently, it is just an offset in byte within the file + the corresponding length. /// /// When the `proc_macro_span` feature is enabled, it may also hold a proc_macro span. #[derive(Debug, Clone)] pub struct Span { pub offset: usize, + pub length: usize, #[cfg(feature = "proc_macro_span")] pub span: Option, } @@ -26,8 +27,8 @@ impl Span { } #[allow(clippy::needless_update)] // needed when `proc_macro_span` is enabled - pub fn new(offset: usize) -> Self { - Self { offset, ..Default::default() } + pub fn new(offset: usize, length: usize) -> Self { + Self { offset, length, ..Default::default() } } } @@ -35,6 +36,7 @@ impl Default for Span { fn default() -> Self { Span { offset: usize::MAX, + length: 0, #[cfg(feature = "proc_macro_span")] span: Default::default(), } @@ -43,7 +45,7 @@ impl Default for Span { impl PartialEq for Span { fn eq(&self, other: &Span) -> bool { - self.offset == other.offset + self.offset == other.offset && self.length == other.length } } @@ -272,6 +274,36 @@ impl Diagnostic { } } + /// The exclusive end of this diagnostic. + /// Returns a tuple with the line (starting at 1) and column number (starting at 1) + /// + /// Can also return (0, 0) if the span is invalid + pub fn end_line_column(&self) -> (usize, usize) { + if !self.span.span.is_valid() { + return (0, 0); + } + // The end_line_column is exclusive. + // Even if the span indicates a length of 0, the diagnostic should always + // return an end_line_column that is at least one offset further, so that at least one + // character is covered by the diagnostic. + let offset = self.span.span.offset + self.span.span.length.max(1); + + match &self.span.source_file { + None => (0, 0), + Some(sl) => sl.line_column(offset), + } + } + + /// Return the length of this diagnostic in characters. + pub fn length(&self) -> usize { + // Like in end_line_column, the length should always be 1, even if the span indicates a + // length of 0, as otherwise there is no character to display the diagnostic on. + self.span.span.length.max(1) + } + + // NOTE: The return-type differs from the Spanned trait. + // Because this is public API (Diagnostic is re-exported by the Interpreter), we cannot change + // this. /// return the path of the source file where this error is attached pub fn source_file(&self) -> Option<&Path> { self.span.source_file().map(|sf| sf.path()) @@ -404,8 +436,10 @@ impl BuildDiagnostics { }); let file_span = file.span; let s = codemap_diagnostic::SpanLabel { - span: file_span - .subspan(d.span.span.offset as u64, d.span.span.offset as u64), + span: file_span.subspan( + d.span.span.offset as u64, + (d.span.span.offset + d.span.span.length) as u64, + ), style: codemap_diagnostic::SpanStyle::Primary, label: None, }; diff --git a/internal/compiler/lexer.rs b/internal/compiler/lexer.rs index 21c3a5a01bf..7b6c459d9dd 100644 --- a/internal/compiler/lexer.rs +++ b/internal/compiler/lexer.rs @@ -204,6 +204,7 @@ pub fn lex(mut source: &str) -> Vec { kind: SyntaxKind::Whitespace, text: source[..3].into(), offset: 0, + length: 3, ..Default::default() }); source = &source[3..]; @@ -215,6 +216,7 @@ pub fn lex(mut source: &str) -> Vec { kind, text: source[..len].into(), offset, + length: len, ..Default::default() }); offset += len; diff --git a/internal/compiler/parser.rs b/internal/compiler/parser.rs index 38d340e2589..5bda4986406 100644 --- a/internal/compiler/parser.rs +++ b/internal/compiler/parser.rs @@ -463,6 +463,7 @@ pub struct Token { pub kind: SyntaxKind, pub text: SmolStr, pub offset: usize, + pub length: usize, #[cfg(feature = "proc_macro_span")] pub span: Option, } @@ -473,6 +474,7 @@ impl Default for Token { kind: SyntaxKind::Eof, text: Default::default(), offset: 0, + length: 0, #[cfg(feature = "proc_macro_span")] span: None, } @@ -692,7 +694,7 @@ impl Parser for DefaultParser<'_> { fn error(&mut self, e: impl Into) { let current_token = self.current_token(); #[allow(unused_mut)] - let mut span = crate::diagnostics::Span::new(current_token.offset); + let mut span = crate::diagnostics::Span::new(current_token.offset, current_token.length); #[cfg(feature = "proc_macro_span")] { span.span = current_token.span; @@ -711,7 +713,7 @@ impl Parser for DefaultParser<'_> { fn warning(&mut self, e: impl Into) { let current_token = self.current_token(); #[allow(unused_mut)] - let mut span = crate::diagnostics::Span::new(current_token.offset); + let mut span = crate::diagnostics::Span::new(current_token.offset, current_token.length); #[cfg(feature = "proc_macro_span")] { span.span = current_token.span; @@ -946,7 +948,8 @@ impl NodeOrToken { impl Spanned for SyntaxNode { fn span(&self) -> crate::diagnostics::Span { - crate::diagnostics::Span::new(self.node.text_range().start().into()) + let range = self.node.text_range(); + crate::diagnostics::Span::new(range.start().into(), range.len().into()) } fn source_file(&self) -> Option<&SourceFile> { @@ -966,7 +969,8 @@ impl Spanned for Option { impl Spanned for SyntaxToken { fn span(&self) -> crate::diagnostics::Span { - crate::diagnostics::Span::new(self.token.text_range().start().into()) + let range = self.token.text_range(); + crate::diagnostics::Span::new(range.start().into(), range.len().into()) } fn source_file(&self) -> Option<&SourceFile> { diff --git a/internal/compiler/tests/syntax/accessibility/accessible_properties.slint b/internal/compiler/tests/syntax/accessibility/accessible_properties.slint index 4bbec9022cb..16bac6ea47f 100644 --- a/internal/compiler/tests/syntax/accessibility/accessible_properties.slint +++ b/internal/compiler/tests/syntax/accessibility/accessible_properties.slint @@ -2,27 +2,27 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 Button1 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > cond; accessible-role: cond ? button : AccessibleRole.text; -// ^error{The `accessible-role` property must be a constant expression} +// > { self.accessible-role = AccessibleRole.text; -// ^error{The property must be known at compile time and cannot be changed at runtime} +// > extra_background; property condition; background: yellow; //FIXME: ideally we'd keep the span within the state -// ^error{The binding for the property 'background' is part of a binding loop (extra-background -> background)} +// > background)} states [ xxx when condition : { background: extra_background; @@ -16,32 +16,32 @@ WithStates := Rectangle { } export Test := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > a: 45 + root.b; -// ^error{The binding for the property 'a' is part of a binding loop (root_window.d -> root_window.c -> root_window.b -> root_window.a)} +// > root_window.c -> root_window.b -> root_window.a)} property b: root.c; -// ^error{The binding for the property 'b' is part of a binding loop (root_window.d -> root_window.c -> root_window.b -> root_window.a)} +// > root_window.c -> root_window.b -> root_window.a)} property c <=> d; -// ^error{The binding for the property 'c' is part of a binding loop (root_window.d -> root_window.c -> root_window.b -> root_window.a)} +// > root_window.c -> root_window.b -> root_window.a)} property d: root.a + root.e; -// ^error{The binding for the property 'd' is part of a binding loop (root_window.d -> root_window.c -> root_window.b -> root_window.a)} +// > root_window.c -> root_window.b -> root_window.a)} property e: root.b; -// ^error{The binding for the property 'e' is part of a binding loop (root_window.e -> root_window.d -> root_window.c -> root_window.b)} +// > root_window.d -> root_window.c -> root_window.b)} property w: root.a + root.b; // This id not part of a loop property cond: xx.x == 0; -// ^error{The binding for the property 'cond' is part of a binding loop (xx.y -> xx.x -> root_window.cond)} +// > xx.x -> root_window.cond)} xx := Rectangle { x: y; -// ^error{The binding for the property 'x' is part of a binding loop (xx.y -> xx.x -> root_window.cond)} +// > xx.x -> root_window.cond)} y: root.cond ? 42px : 55px; -// ^error{The binding for the property 'y' is part of a binding loop (xx.y -> xx.x -> root_window.cond)} +// > xx.x -> root_window.cond)} } WithStates { extra_background: background; -// ^error{The binding for the property 'extra-background' is part of a binding loop (extra-background -> background)} +// > background)} } } diff --git a/internal/compiler/tests/syntax/analysis/binding_loop2.slint b/internal/compiler/tests/syntax/analysis/binding_loop2.slint index 7a8bb7dc393..6deffd1c8c0 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop2.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop2.slint @@ -3,54 +3,54 @@ T1 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > foo; property bar: foo; -// ^error{The binding for the property 'bar' is part of a binding loop (foo -> bar)} +// > bar)} Text { text: bar; } } T2 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > t2_text; t:= Text { text: t2_text; } -// ^error{The binding for the property 'text' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} -// ^^error{The binding for the property 'text' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > <^error{The binding for the property 'text' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} property t_alias <=> t.text; -// ^error{The binding for the property 't-alias' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} -// ^^error{The binding for the property 't-alias' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > <^error{The binding for the property 't-alias' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} } T3 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > hello; property al <=> a.t_alias; -// ^error{The binding for the property 'al' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} HorizontalLayout { a := T2 { t2_text: b.t_alias; } -// ^error{The binding for the property 't2-text' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} b := T2 { t2_text: root.hello; } -// ^error{The binding for the property 't2-text' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} } } T4 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > my_property <=> x; } export App := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > bar)} +// > bar)} T3 { hello: al; } -// ^error{The binding for the property 'hello' is part of a binding loop (hello -> b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} +// > b.t2-text -> t.text -> b.t-alias -> a.t2-text -> t.text -> a.t-alias -> al)} T4 { my_property: my_property; } -// ^error{Property 'my-property' cannot refer to itself} +// > a : aa(); -// ^error{The binding for the property 'a' is part of a binding loop (cc.aa -> cc.a)} +// > cc.a)} pure callback aa() -> int; function factorial(n: int) -> int { -// ^error{The binding for the property 'factorial' is part of a binding loop (cc.factorial)} +// >error{The binding for the property 'factorial' is part of a binding loop (cc.factorial)} return n == 0 ? 1 : factorial(n - 1) * n; } +// b; public pure function bb() -> int { return b; } -// ^error{The binding for the property 'bb' is part of a binding loop (cc.bb -> cc.b)} +// > cc.b)} } export App := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > { return self.a; } -// ^error{The binding for the property 'aa' is part of a binding loop (cc.aa -> cc.a)} +// >error{The binding for the property 'aa' is part of a binding loop (cc.aa -> cc.a)} b: self.bb(); -// ^error{The binding for the property 'b' is part of a binding loop (cc.bb -> cc.b)} +// cc.a)} +// > <^error{The binding for the property 'b' is part of a binding loop (cc.bb -> cc.b)} } diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_issue_772.slint b/internal/compiler/tests/syntax/analysis/binding_loop_issue_772.slint index 0d87fd1a281..01b4a8afb3c 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_issue_772.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_issue_772.slint @@ -2,18 +2,18 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 Alias := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > viewport_width ; property ps_width <=> viewport_width; } export Foo := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > base-prop: alias.viewport_width; -// ^error{The binding for the property 'base-prop' is part of a binding loop (alias.ps-width -> root_window.base-prop)} +// > root_window.base-prop)} alias := Alias { ps_width: base-prop; } -// ^error{The binding for the property 'ps-width' is part of a binding loop (alias.ps-width -> root_window.base-prop)} +// > root_window.base-prop)} Text { text: base-prop; diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_layout.slint b/internal/compiler/tests/syntax/analysis/binding_loop_layout.slint index ac184ce4b47..717fe014ed1 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_layout.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_layout.slint @@ -2,55 +2,71 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 TC := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} -// ^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// >^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} outer := VerticalLayout { -// ^error{The binding for the property 'width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} -// ^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// >error{The binding for the property 'width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// >^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} inner := HorizontalLayout { -// ^error{The binding for the property 'width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} -// ^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// >error{The binding for the property 'width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// >^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} inner_inner := VerticalLayout { width: parent.width; -// ^error{The binding for the property 'width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// > tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} Rectangle {} } } +// tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// <^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} } +// tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// <^error{The binding for the property 'layoutinfo-h' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} } +//<< tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} export Test := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} -// ^^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} VerticalLayout { // FIXME: That's an internal property, but people might understand -// ^error{The binding for the property 'min-width' is part of a binding loop (min-width -> width -> layoutinfo-h)} -// ^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (min-width -> width -> layoutinfo-h)} +// >error{The binding for the property 'min-width' is part of a binding loop (min-width -> width -> layoutinfo-h)} +// >^error{The binding for the property 'layoutinfo-h' is part of a binding loop (min-width -> width -> layoutinfo-h)} Rectangle { width: parent.min_width; -// ^error{The binding for the property 'width' is part of a binding loop (min-width -> width -> layoutinfo-h)} +// > width -> layoutinfo-h)} } } +// width -> layoutinfo-h)} +// <^error{The binding for the property 'layoutinfo-h' is part of a binding loop (min-width -> width -> layoutinfo-h)} l := HorizontalLayout { // FIXME: That's an internal property, but people might understand -// ^error{The binding for the property 'preferred-width' is part of a binding loop (l.preferred-width -> text -> l.layoutinfo-h)} -// ^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (l.preferred-width -> text -> l.layoutinfo-h)} -// ^^^error{The binding for the property 'layoutinfo-v' is part of a binding loop (l.layoutinfo-v -> l.preferred-height -> text)} -// ^^^^error{The binding for the property 'preferred-height' is part of a binding loop (l.layoutinfo-v -> l.preferred-height -> text)} -// ^^^^^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^^^warning{The binding for the property 'layout-cache' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^^^^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >error{The binding for the property 'preferred-width' is part of a binding loop (l.preferred-width -> text -> l.layoutinfo-h)} +// >^error{The binding for the property 'layoutinfo-h' is part of a binding loop (l.preferred-width -> text -> l.layoutinfo-h)} +// >^^error{The binding for the property 'layoutinfo-v' is part of a binding loop (l.layoutinfo-v -> l.preferred-height -> text)} +// >^^^error{The binding for the property 'preferred-height' is part of a binding loop (l.layoutinfo-v -> l.preferred-height -> text)} +// >^^^^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^^^warning{The binding for the property 'layout-cache' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^^^^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} Text { text: "hello \{l.preferred-width/1px}x\{l.preferred-height/1px}"; -// ^error{The binding for the property 'text' is part of a binding loop (l.preferred-width -> text -> l.layoutinfo-h)} +// > text -> l.layoutinfo-h)} wrap: word-wrap; } } +// text -> l.layoutinfo-h)} +// <^error{The binding for the property 'layoutinfo-h' is part of a binding loop (l.preferred-width -> text -> l.layoutinfo-h)} +// <^^error{The binding for the property 'layoutinfo-v' is part of a binding loop (l.layoutinfo-v -> l.preferred-height -> text)} +// <^^^error{The binding for the property 'preferred-height' is part of a binding loop (l.layoutinfo-v -> l.preferred-height -> text)} +// <^^^^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^^^warning{The binding for the property 'layout-cache' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^^^^warning{The binding for the property 'width' is part of a binding loop (root.width -> l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} tc := TC { -// ^error{The binding for the property 'preferred-width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// >error{The binding for the property 'preferred-width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} width: preferred-width; -// ^error{The binding for the property 'width' is part of a binding loop (tc.preferred-width -> tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} +// > tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} } +// tc.width -> outer.width -> inner.width -> inner-inner.width -> inner.layoutinfo-h -> outer.layoutinfo-h -> tc.layoutinfo-h)} } +//<< l.width -> l.layout-cache -> width -> l.layoutinfo-v -> l.preferred-height -> text -> l.layoutinfo-h -> root.layoutinfo-h -> root_window.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_layout2.slint b/internal/compiler/tests/syntax/analysis/binding_loop_layout2.slint index 5a49c796ea1..68d8f6d2b9c 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_layout2.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_layout2.slint @@ -2,46 +2,52 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 Wrap := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > text.wrap; VerticalLayout { -// ^error{The binding for the property 'layout-cache' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} -// ^^error{The binding for the property 'height' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// >error{The binding for the property 'layout-cache' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// >^error{The binding for the property 'height' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} HorizontalLayout { -// ^error{The binding for the property 'layout-cache' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} -// ^^error{The binding for the property 'width' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} -// ^^^error{The binding for the property 'layoutinfo-v' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// >error{The binding for the property 'layout-cache' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// >^error{The binding for the property 'width' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// >^^error{The binding for the property 'layoutinfo-v' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} text := Text { text: "Hello World"; } square := Rectangle { -// ^error{The binding for the property 'height' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// >error{The binding for the property 'height' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} width: height; -// ^error{The binding for the property 'width' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// > text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} background: violet; } +// text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} } +// text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// <^error{The binding for the property 'width' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// <^^error{The binding for the property 'layoutinfo-v' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} Rectangle {} } +// text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} +// <^error{The binding for the property 'height' is part of a binding loop (layout-cache -> text.width -> layoutinfo-v -> layout-cache -> height -> square.height -> square.width)} property test: square.width == square.height; } export Test := Window { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} -// ^^warning{The binding for the property 'layoutinfo-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^warning{The binding for the property 'layoutinfo-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} property source; GridLayout { -// ^warning{The binding for the property 'width' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^warning{The binding for the property 'layout-cache-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^warning{The binding for the property 'width' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^warning{The binding for the property 'layoutinfo-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^^warning{The binding for the property 'height' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^^^warning{The binding for the property 'layout-cache-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^^^^warning{The binding for the property 'height' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^^^^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'width' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^warning{The binding for the property 'layout-cache-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^warning{The binding for the property 'width' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^warning{The binding for the property 'layoutinfo-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^^warning{The binding for the property 'height' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^^^warning{The binding for the property 'layout-cache-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^^^^warning{The binding for the property 'height' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^^^^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} Image { @@ -49,12 +55,22 @@ export Test := Window { } Rectangle { width: height; -// ^warning{The binding for the property 'width' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// > layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} } } +// layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^warning{The binding for the property 'layout-cache-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^warning{The binding for the property 'width' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^warning{The binding for the property 'layoutinfo-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^^warning{The binding for the property 'height' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^^^warning{The binding for the property 'layout-cache-v' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^^^^warning{The binding for the property 'height' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^^^^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} w := Wrap { } callback set_wrap(); set_wrap => { w.woo = TextWrap.word-wrap; } } +//<< layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +//<^< layout-cache-h -> width -> layoutinfo-v -> root.layoutinfo-v -> height -> layout-cache-v -> height -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_layout3.slint b/internal/compiler/tests/syntax/analysis/binding_loop_layout3.slint index e6afcae8bdf..7024c3d06bd 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_layout3.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_layout3.slint @@ -2,32 +2,37 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 Compo := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} -// ^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} +// >^error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} property the_text; lay := HorizontalLayout { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} if true : Rectangle { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} VerticalLayout { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} Text { text: root.the_text; -// ^error{The binding for the property 'text' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} +// > the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} } } +// the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} } +// the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} } +// the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} } +//<< the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} export Foo := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} +// >error{The binding for the property 'preferred-width' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} the_text: self.preferred-width / 1px; -// ^error{The binding for the property 'the-text' is part of a binding loop (preferred-width -> the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} +// > the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} } +// the-text -> text -> layoutinfo-h -> layoutinfo-h -> lay.layoutinfo-h -> layoutinfo-h)} } diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_layout4.slint b/internal/compiler/tests/syntax/analysis/binding_loop_layout4.slint index 3b6fa2a786f..03536151e77 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_layout4.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_layout4.slint @@ -2,42 +2,58 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 component Foo { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} HorizontalLayout { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^^error{The binding for the property 'layout-cache' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} -// ^^^^^^error{The binding for the property 'layout-cache' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} -// ^^^^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} -// ^^^^^^^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^^error{The binding for the property 'layout-cache' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// >^^^^^error{The binding for the property 'layout-cache' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// >^^^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// >^^^^^^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} Text { text: "hello"; font_size: self.width / 2.5; -// ^error{The binding for the property 'font-size' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^error{The binding for the property 'font-size' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// > layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// > <^error{The binding for the property 'font-size' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} } } +// layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^^error{The binding for the property 'layout-cache' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// <^^^^^error{The binding for the property 'layout-cache' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// <^^^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// <^^^^^^^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} } +//<< layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +//<^< width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} component Bar { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} HorizontalLayout { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^^error{The binding for the property 'layout-cache' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^^error{The binding for the property 'layout-cache' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// >^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} Foo {} Foo {} } +// layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^^error{The binding for the property 'layout-cache' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// <^^^^error{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> font-size -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache)} } +//<< layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} export component Apps inherits Window { Bar {} -// ^error{The binding for the property 'preferred-width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} -// ^^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// > layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} +// > <^error{The binding for the property 'width' is part of a binding loop (layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> preferred-width -> width -> width -> layout-cache -> width -> width -> layout-cache -> width -> font-size)} } diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_layout_if.slint b/internal/compiler/tests/syntax/analysis/binding_loop_layout_if.slint index 96d48f1e961..89cf644d4d8 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_layout_if.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_layout_if.slint @@ -6,37 +6,49 @@ component Wrapper { height: 100%; Rectangle { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} VerticalLayout { -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} +// >error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} if root.width > 200px: Rectangle { } } +// layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} } +// layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} } component WrapperInherited inherits Rectangle { -// ^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} VerticalLayout { -// ^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} if root.width > 200px: Rectangle { } } +// width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} } +//<< width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} export component Test inherits Window { -// ^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} VerticalLayout { -// ^warning{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} HorizontalLayout { -// ^warning{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^warning{The binding for the property 'layout-cache' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^warning{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^^^^error{The binding for the property 'width' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} +// >warning{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^warning{The binding for the property 'layout-cache' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^warning{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^^^^error{The binding for the property 'width' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} WrapperInherited { } Wrapper { } -// ^error{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} +// > layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} } +// width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^warning{The binding for the property 'layout-cache' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^warning{The binding for the property 'width' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^^^^error{The binding for the property 'width' is part of a binding loop (width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layout-cache)} } -} \ No newline at end of file +// width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +} +//<< width -> layout-cache -> width -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_mappointtowindow.slint b/internal/compiler/tests/syntax/analysis/binding_loop_mappointtowindow.slint index aa6cd5722dc..44ab5a6bcd9 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_mappointtowindow.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_mappointtowindow.slint @@ -2,14 +2,15 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export App := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > 10px ? 10px : 0px; -// ^error{The binding for the property 'x' is part of a binding loop (inner.absolute-position -> x)} +// > x)} inner := Rectangle { -// ^error{The binding for the property 'absolute-position' is part of a binding loop (inner.absolute-position -> x)} +// >error{The binding for the property 'absolute-position' is part of a binding loop (inner.absolute-position -> x)} } +// x)} } } diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_self.slint b/internal/compiler/tests/syntax/analysis/binding_loop_self.slint index 34df461dd8e..7b1accce7a2 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_self.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_self.slint @@ -4,19 +4,19 @@ // From issue #737 Key := Rectangle { property pos; property num_elements; } -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > num_elements; num-elements: 4; Key { pos: 1; num_elements: num_elements; } -// ^error{The binding for the property 'num-elements' is part of a binding loop (num-elements)} +// > root.default-font-size)} +// > root.default-font-size)} } export component Test inherits Window { Text { font-size: self.font-metrics.ascent; } -// ^error{The binding for the property 'font-metrics' is part of a binding loop (font-metrics -> font-size)} -// ^^error{The binding for the property 'font-size' is part of a binding loop (font-metrics -> font-size)} +// > font-size)} +// > <^error{The binding for the property 'font-size' is part of a binding loop (font-metrics -> font-size)} t1 := Text { font-italic: t2.font-metrics.cap-height > 10px; } -// ^error{The binding for the property 'font-metrics' is part of a binding loop (t2.font-metrics -> t1.font-italic -> t1.font-metrics -> t2.font-weight)} -// ^^error{The binding for the property 'font-italic' is part of a binding loop (t2.font-metrics -> t1.font-italic -> t1.font-metrics -> t2.font-weight)} +// > t1.font-italic -> t1.font-metrics -> t2.font-weight)} +// > <^error{The binding for the property 'font-metrics' is part of a binding loop (t2.font-metrics -> t1.font-italic -> t1.font-metrics -> t2.font-weight)} t2 := Text { font-weight: t1.font-metrics.descent / 0.5px; } -// ^error{The binding for the property 'font-metrics' is part of a binding loop (t2.font-metrics -> t1.font-italic -> t1.font-metrics -> t2.font-weight)} -// ^^error{The binding for the property 'font-weight' is part of a binding loop (t2.font-metrics -> t1.font-italic -> t1.font-metrics -> t2.font-weight)} +// > t1.font-italic -> t1.font-metrics -> t2.font-weight)} +// > <^error{The binding for the property 'font-weight' is part of a binding loop (t2.font-metrics -> t1.font-italic -> t1.font-metrics -> t2.font-weight)} OkButton {} b := KoButton {} default-font-size: b.font-size; -// ^error{The binding for the property 'default-font-size' is part of a binding loop (b.font-size -> root.default-font-size)} +// > root.default-font-size)} dialog1 := Window { default-font-size: 2rem; diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_window.slint b/internal/compiler/tests/syntax/analysis/binding_loop_window.slint index d0591afa0ff..3a5153c7152 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_window.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_window.slint @@ -6,20 +6,23 @@ import { HorizontalBox, VerticalBox } from "std-widgets.slint"; export component MainWindow inherits Window { -// ^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} HorizontalBox { -// ^warning{The binding for the property 'width' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} -// ^^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'width' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} VerticalBox { width: parent.width; -// ^warning{The binding for the property 'width' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// > width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} //height: parent.height; Text { text: "Test"; } } } -} \ No newline at end of file +// width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// <^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (width -> width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +} +//<< width -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} diff --git a/internal/compiler/tests/syntax/analysis/binding_loop_window2.slint b/internal/compiler/tests/syntax/analysis/binding_loop_window2.slint index fff6aed2a64..c9cb3bca2a8 100644 --- a/internal/compiler/tests/syntax/analysis/binding_loop_window2.slint +++ b/internal/compiler/tests/syntax/analysis/binding_loop_window2.slint @@ -3,12 +3,14 @@ // Issue #3898 export component LspCrash inherits Window { -// ^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (padding-left -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'layoutinfo-h' is part of a binding loop (padding-left -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} HorizontalLayout { -// ^warning{The binding for the property 'layoutinfo-h' is part of a binding loop (padding-left -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// >warning{The binding for the property 'layoutinfo-h' is part of a binding loop (padding-left -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} padding-left: parent.width * 0.015; -// ^warning{The binding for the property 'padding-left' is part of a binding loop (padding-left -> layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} +// > layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} Rectangle {} } +// layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} } +//<< layoutinfo-h -> root.layoutinfo-h).↵This was allowed in previous version of Slint, but is deprecated and may cause panic at runtime} diff --git a/internal/compiler/tests/syntax/basic/animate.slint b/internal/compiler/tests/syntax/basic/animate.slint index ce1697062b1..a932ccd68be 100644 --- a/internal/compiler/tests/syntax/basic/animate.slint +++ b/internal/compiler/tests/syntax/basic/animate.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export SuperSimple := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > { root.x = 1phx; } } @@ -11,16 +11,16 @@ export SuperSimple := Rectangle { } TouchArea { clicked => { 12 = 1; } -// ^error{Assignment needs to be done on a property} +// > { x = "string"; } -// ^error{Cannot convert string to length} +// > { doesnotexist = 24; } -// ^error{Unknown unqualified identifier 'doesnotexist'} +// > error{The 'clip' property can only be applied to a Rectangle or a Path for now} clicked => { self.clip = false; } } +// ^error{A Dialog must have a single child element that is not StandardButton} StandardButton { kind: reset; } StandardButton { kind: cancel; col: 42; -// ^error{col used outside of a GridLayout's cell} +// > { r.dialog-button-role = DialogButtonRole.action; -// ^error{The property must be known at compile time and cannot be changed at runtime} +// > ^error{A Dialog must have a single child element that is not StandardButton} StandardButton { kind: ok; } StandardButton { } -// ^error{The `kind` property of the StandardButton in a Dialog must be set} +// > self.height; -// ^error{Duplicated property binding} +// > 12phx; -// ^error{Unknown property not-exist in Rectangle} +// > foo: 12; foo: 13; -// ^error{Duplicated property binding} +// > error{duplicated element id 'hello'} world := Rectangle { } -// ^error{duplicated element id 'world'} +// > a; animate a { easing: cubic-bezier(0.01,1.46,0.94,1.37); } property b; animate b { easing: cubic-bezier(0.01,1.46,0.94); } -// ^error{Not enough arguments} +// > c; animate c { easing: cubic-bezier(); } -// ^error{Not enough arguments} +// > d; animate d { easing: cubic-bezier(0,0,0,0,0,0); } // ^error{Too many argument for bezier curve} property e; animate e { easing: cubic-bezier(0, a, b, c); } // ^error{Arguments to cubic bezier curve must be number literal} property f; animate f { easing: cubic-bezier(0,0+0,0,0,0); } -// ^error{Arguments to cubic bezier curve must be number literal} +// > g; animate g { easing: cubic-bezier; } -// ^error{Builtin function must be called. Did you forgot the '()'?} +// > empty; property xyz; property<{ a: Empty, b: Xyz }> xxx: { b: Xyz.c-dE}; -// ^error{'c-dE' is not a member of the enum Xyz} +// > count; for x in 0..count: Rectangle { } -// ^error{Cannot access the field 'count' of float. Range expressions are not supported in Slint, but you can use an integer as a model to repeat something multiple time. Eg: `for i in count`} +// > invalid: 0..count; -// ^error{Cannot access the field 'count' of float} +// > <^error{Unknown unqualified identifier 'yellow'} } } diff --git a/internal/compiler/tests/syntax/basic/item_as_property.slint b/internal/compiler/tests/syntax/basic/item_as_property.slint index b64df0a08e9..352858b6ca3 100644 --- a/internal/compiler/tests/syntax/basic/item_as_property.slint +++ b/internal/compiler/tests/syntax/basic/item_as_property.slint @@ -2,31 +2,31 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 struct Str := { foo: Rectangle } -// ^warning{':=' to declare a struct is deprecated. Remove the ':='} -// ^^error{'Rectangle' is not a valid type} +// > r; -// ^error{'Rectangle' is not a valid type} +// > ls; -// ^error{'Rectangle' is not a valid type} +// > st; -// ^error{'Rectangle' is not a valid type} +// > Rectangle; -// ^error{'Rectangle' is not a valid type} +// > <^error{Cannot take reference of an element} } } diff --git a/internal/compiler/tests/syntax/basic/layout.slint b/internal/compiler/tests/syntax/basic/layout.slint index a90be552e7e..028f155e40b 100644 --- a/internal/compiler/tests/syntax/basic/layout.slint +++ b/internal/compiler/tests/syntax/basic/layout.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export X := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > foo: "hello"; @@ -13,7 +13,7 @@ export X := Rectangle { Row {Text {}} Text{ Row {} -// ^error{Row can only be within a GridLayout element} +// > foo: "hello"; Row { Text { text: lay.foo + parent.width; -// ^error{Element 'Row' does not have a property 'width'} +// > { self.colspan = 45; -// ^error{The property must be known at compile time and cannot be changed at runtime} +// > { let foo: string = 42phx; -// ^error{Cannot convert physical-length to string. Divide by 1phx to convert to a plain number} +// > { let foo = "hello"; let foo = "world"; -// ^error{Redeclaration of local variables is not allowed} +// > { let foo = "hello"; let foo = 1; -// ^error{Redeclaration of local variables is not allowed} +// > 0) { let foo = 1; -// ^error{Redeclaration of local variables is not allowed} +// > g1: @linear-gradient(); -// ^error{Expected angle expression} +// > g2: @linear-gradient(to left, blue, red); -// ^error{Angle expression must be an angle followed by a comma} +// > g3: @linear-gradient(0deg, blue, red); property g4: @linear-gradient(45deg, blue 45%, red red); -// ^error{Cannot convert color to float} +// > g5: @linear-gradient(128deg, blue 45%, red); property g6: @linear-gradient(90deg, blue 45%, red 88%); property g7: @linear-gradient(90deg, 42 45%, red 0.3); -// ^error{Cannot convert float to color} +// > g8: @linear-gradient(90deg, blue red green); -// ^error{Cannot convert color to float} -// ^^error{Expected comma} +// > <^error{Expected comma} property g9: @linear-gradient(0deg blue, blue, red); -// ^error{Angle expression must be an angle followed by a comma} +// > g10: @linear-gradient(90deg, blue 10% red 20%, yellow); -// ^error{Expected comma} +// > g11: @linear-gradient(20deg,); property g12: @linear-gradient(2, blue 45%, red 88%); // ^error{Cannot convert float to angle. Use an unit, or multiply by 1deg to convert explicitly} @@ -31,5 +31,5 @@ export X := Rectangle { property g15: @linear-gradient(90deg, brown o, green); // #3241 // ^error{Unknown unqualified identifier 'o'} property g16: @linear-gradient(0deg, red, green, blue); // #6819 -// ^warning{Narrowing conversion from brush to color. This can lead to unexpected behavior because the brush is a gradient} +// > { p.commands = "M 0 0 M -100 0 A 100 100 0 1 0 100 0 A 100 100 0 1 0 100 0 Z"; -// ^error{This special property can only be used to make a binding and cannot be accessed} +// > error{Path elements are not supported with `for`-`in` syntax, yet (https://github.com/slint-ui/slint/issues/754)} x: i; y: sample; } +// error{Cannot access the inside of a PopupWindow from enclosing component} input := TextInput {} } +// { p.show(); @@ -22,18 +23,19 @@ component Issue5852 { export X := PopupWindow { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} -// ^^error{PopupWindow cannot be the top level} +// >^error{PopupWindow cannot be the top level} Rectangle { // FIXME, the error should be located on property access (#4438) -// ^error{Access to property 'inner.opacity' which is inlined into a PopupWindow via @children is forbidden} +// >error{Access to property 'inner.opacity' which is inlined into a PopupWindow via @children is forbidden} popup := PopupWindow { // FIXME, the error should be located on property access (#4438) -// ^error{Cannot access the inside of a PopupWindow from enclosing component} +// >error{Cannot access the inside of a PopupWindow from enclosing component} r := Rectangle { } } +// foo; foo: 100; property bar; -// ^error{Unknown type 'NonExistent'} +// > obj; -// ^error{Unknown type 'NonExistent'} +// > array; -// ^error{Unknown type 'NonExistent'} +// > foo; -// ^error{Cannot override property 'foo'} +// > text: "property with binding initializer"; property x; // ^error{Cannot override property 'x'} property colspan; -// ^error{Cannot override property 'colspan'} +// > pressed; -// ^error{Cannot declare property 'pressed' when a callback with the same name exists} +// > color; -// ^error{Cannot override property 'color'} +// > prop; } export Test := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > g1: @radial-gradient(); -// ^error{Expected 'circle': currently, only @radial-gradient(circle, ...) are supported} +// > g2: @radial-gradient(circle at 100%, #333, #333 50%, #eee 75%, #333 75%); -// ^error{'at' in @radial-gradient is not yet supported} +// > g3: @radial_gradient(circle, blue, red); property g4: @radial_gradient(circle, blue 45%, red red); -// ^error{Cannot convert color to float} +// > g5: @radial-gradient(ellipse at top, #e66465, transparent); -// ^error{Expected 'circle': currently, only @radial-gradient(circle, ...) are supported} +// > g6: @radial-gradient(circle, blue 45%, red 88%); property g7: @radial-gradient(circle, 42 45%, red 0.3); -// ^error{Cannot convert float to color} +// > g8: @radial-gradient(90px, blue, red ,green); -// ^error{Expected 'circle': currently, only @radial-gradient(circle, ...) are supported} +// > g9: @radial-gradient(circle blue, blue, red); -// ^error{'circle' must be followed by a comma} +// > g10: @radial-gradient(circle, blue 10% red 20%, yellow); -// ^error{Expected comma} +// > g11: @radial-gradient(circle,); property g12: @radial-gradient(circle); property g13: @radial-gradient(circle, red, green, blue); // #6819 -// ^warning{Narrowing conversion from brush to color. This can lead to unexpected behavior because the brush is a gradient} +// > string; xxx => { return 42phx; -// ^error{Cannot convert physical-length to string. Divide by 1phx to convert to a plain number} +// > { if (!self.visible) { return; -// ^error{Must return a value of type 'enum EventResult'} +// > error{'rotation-origin-x' cannot be set on this element} clicked => { self.rotation-origin-x = 10px; -// ^warning{The property 'rotation-origin-x' has been deprecated. Please use 'transform-origin.x' instead} +// > { img.rotation-origin-x = 10px; -// ^warning{The property 'rotation-origin-x' has been deprecated. Please use 'transform-origin.x' instead} +// > warning{The property 'rotation-origin-x' has been deprecated. Please use 'transform-origin' instead} transform-origin: { y: self.width / 2 }; } +// { img2.rotation-origin-x = 10px; -// ^warning{The property 'rotation-origin-x' has been deprecated. Please use 'transform-origin.x' instead} +// > { debug(img3.rotation-origin-x, img3.rotation-origin-y, self.rotation-origin-x,self.rotation-origin-y); -// ^warning{The property 'rotation-origin-x' has been deprecated. Please use 'transform-origin.x' instead} -// ^^warning{The property 'rotation-origin-y' has been deprecated. Please use 'transform-origin.y' instead} -// ^^^warning{The property 'rotation-origin-x' has been deprecated. Please use 'transform-origin.x' instead} -// ^^^^warning{The property 'rotation-origin-y' has been deprecated. Please use 'transform-origin.y' instead} +// > <^warning{The property 'rotation-origin-y' has been deprecated. Please use 'transform-origin.y' instead} +// > <^^warning{The property 'rotation-origin-x' has been deprecated. Please use 'transform-origin.x' instead} +// > <^^^warning{The property 'rotation-origin-y' has been deprecated. Please use 'transform-origin.y' instead} } } diff --git a/internal/compiler/tests/syntax/basic/rotation.slint b/internal/compiler/tests/syntax/basic/rotation.slint index 4c4fb6081fe..240a51fbc0f 100644 --- a/internal/compiler/tests/syntax/basic/rotation.slint +++ b/internal/compiler/tests/syntax/basic/rotation.slint @@ -2,11 +2,11 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export Ex1 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > { i1.rotation-angle = 60deg; -// ^warning{The property 'rotation-angle' has been deprecated. Please use 'transform-rotation' instead} +// > rect . rotation-angle; -// ^error{Could not infer type of property 'rot'} -// ^^error{Element 'Rectangle' does not have a property 'rotation-angle'} +// > <^error{Could not infer type of property 'rot'} rect := Rectangle {} } @@ -83,11 +83,11 @@ export component Ex4 { export component Ex5 { property transform-origin; -// ^error{Cannot override property 'transform-origin'} +// > rotation-origin-x; -// ^error{Cannot override property 'rotation-origin-x'} +// > rotation-origin-y; } -// ^error{Cannot override property 'rotation-origin-y'} +// > { root.x += 1phx; } } @@ -11,22 +11,22 @@ export SuperSimple := Rectangle { } TouchArea { clicked => { 12 += 1; } -// ^error{Self assignment needs to be done on a property} +// > { x += "string"; } -// ^error{Cannot convert string to length} +// > { doesnotexist += 24; } -// ^error{Unknown unqualified identifier 'doesnotexist'} +// > text; clicked => { text *= 2; } -// ^error{the *= operation cannot be done on a string} +// > text; clicked => { text /= "hello"; -// ^error{the /= operation cannot be done on a string} +// > color; clicked => { color += color; } -// ^error{the += operation cannot be done on a brush} +// > color; clicked => { color *= 3; } -// ^error{the *= operation cannot be done on a brush} +// > { height /= height; } -// ^error{Cannot convert length to float. Divide by 1px to convert to a plain number} +// > { foobar() } @@ -23,7 +23,7 @@ export SubElements := Rectangle { TouchArea { clicked: 45; -// ^error{'clicked' is a callback. Use `=>` to connect} +// > ` to connect} x => {} // ^error{'x' is not a callback in TouchArea} } @@ -31,30 +31,30 @@ export SubElements := Rectangle { TouchArea { clicked => { foobar() } clicked => { foobar() } -// ^error{Duplicated callback} +// > { -// ^error{'does-not-exist' is not a callback in Rectangle} +// > { foobar() } callback_with_arg(a, b, c, d) => { } -// ^error{'callback-with-arg' only has 2 arguments, but 4 were provided} +// > pressed; callback pressed; -// ^error{Cannot declare callback 'pressed' when a property with the same name exists} +// > checked; property border; states [ @@ -15,15 +15,15 @@ export TestCase := Rectangle { color: green; border: 88; text.foo.bar: 0; -// ^error{'text.foo.bar' is not a valid property} +// > <^error{Unknown unqualified identifier 'yellow'} fox.color: yellow; -// ^error{'fox' is not a valid element id} +// > <^error{Unknown unqualified identifier 'yellow'} } ] @@ -34,11 +34,11 @@ export TestCase := Rectangle { } out pressed: { animate color, foo.x { duration: 300ms; } -// ^error{'foo' is not a valid element id} +// > <^error{Unknown unqualified identifier 'yellow'} fox.color: yellow; -// ^error{'fox' is not a valid element id} +// > <^error{Unknown unqualified identifier 'yellow'} in { animate * { duration: 88ms; } @@ -86,10 +86,10 @@ export component NewSyntax { } out { animate color, foo.x { duration: 300ms; } -// ^error{'foo' is not a valid element id} +// > <^error{Unknown unqualified identifier 'yellow'} fox.color: yellow; -// ^error{'fox' is not a valid element id} +// > <^error{Unknown unqualified identifier 'yellow'} } ] transitions [ -// ^error{'transitions' block are no longer supported. Use 'in {...}' and 'out {...}' directly in the state definition} +// >error{'transitions' block are no longer supported. Use 'in {...}' and 'out {...}' directly in the state definition} in pressed: { animate * { duration: 88ms; } animate color { duration: 88ms; } } out pressed: { animate color, foo.x { duration: 300ms; } -// ^error{'foo' is not a valid element id} +// > checked; property border; animate background { } @@ -15,12 +15,12 @@ export TestCase := Rectangle { transitions [ in does_not_exist: { -// ^error{State 'does-not-exist' does not exist} +// > toggle; @@ -21,11 +21,11 @@ export Demo := Window { transitions [ in moving: { animate y { duration: 5s; } -// ^error{The property is not changed as part of this transition} +// > toggle; @@ -18,9 +18,11 @@ export Demo := Window { states [ Hello when toggle: { t.y: 100px; -// ^error{Cannot change the property 'y' in a state because it is initialized with a two-way binding} +// >error{Cannot change the property 'y' in a state because it is initialized with a two-way binding} some_prop: "plop"; -// ^error{Cannot change the property 'some-prop' in a state because it is initialized with a two-way binding} +// ^error{Cannot change the property 'some-prop' in a state because it is initialized with a two-way binding} } +// cmds: "M 350 300 L 550 300 "; diff --git a/internal/compiler/tests/syntax/basic/tr.slint b/internal/compiler/tests/syntax/basic/tr.slint index b792c45b66a..073f12cfeeb 100644 --- a/internal/compiler/tests/syntax/basic/tr.slint +++ b/internal/compiler/tests/syntax/basic/tr.slint @@ -3,12 +3,12 @@ export component X { property t1: @tr(boo); -// ^error{Expected plain string literal} -// ^^error{Syntax error: expected ';'} +// > <^error{Syntax error: expected ';'} // ^^^error{Parse error} property t2: @tr("boo\{t1}oo"); -// ^error{Expected plain string literal} -// ^^error{Syntax error: expected ';'} +// > <^error{Syntax error: expected ';'} property t3: @tr("boo" + "foo"); // ^error{Syntax error: expected ')'} @@ -17,8 +17,8 @@ export component X { property t4: @tr("foo{}", t1); property t4: @tr("foo{}", t1 t2); -// ^error{Syntax error: expected ')'} -// ^^error{Syntax error: expected ';'} +// ><^error{Syntax error: expected ';'} property c1: @tr("boo" => ); @@ -26,8 +26,8 @@ export component X { // ^^error{Syntax error: expected ';'} property c2: @tr("boo" => "foo\{ff}"); -// ^error{Expected plain string literal} -// ^^error{Syntax error: expected ';'} +// > <^error{Syntax error: expected ';'} property e: @tr(); // ^error{Expected plain string literal} diff --git a/internal/compiler/tests/syntax/basic/tr2.slint b/internal/compiler/tests/syntax/basic/tr2.slint index 70133fa7cd6..edad7b5b3fe 100644 --- a/internal/compiler/tests/syntax/basic/tr2.slint +++ b/internal/compiler/tests/syntax/basic/tr2.slint @@ -3,39 +3,39 @@ export component X { property t1: @tr("fo{}oo", 42px); -// ^error{Cannot convert length to string. Divide by 1px to convert to a plain number} +// > t2: @tr("foo{0️⃣}bar", 45); -// ^error{Invalid '{...}' placeholder in format string. The placeholder must be a number, or braces must be escaped with '{{' and '}}'} +// > t6: @tr("foo{", 45); -// ^error{Unterminated placeholder in format string. '{' must be escaped with '{{'} +// > t7: @tr("foo{bar", 45); -// ^error{Unterminated placeholder in format string. '{' must be escaped with '{{'} +// > t8: @tr("foo{bar}bar", 45); -// ^error{Invalid '{...}' placeholder in format string. The placeholder must be a number, or braces must be escaped with '{{' and '}}'} +// > t9: @tr("foo{}bar"); -// ^error{Format string contains 1 placeholders, but only 0 extra arguments were given} +// > t10: @tr("foo{}ba{}r", 42); -// ^error{Format string contains 2 placeholders, but only 1 extra arguments were given} +// > t11: @tr("foo{65535}ba{2147483647}r"); -// ^error{Invalid '{...}' placeholder in format string. The placeholder must be a number, or braces must be escaped with '{{' and '}}'} -// ^^error{Format string contains 65536 placeholders, but only 0 extra arguments were given} +// > <^error{Format string contains 65536 placeholders, but only 0 extra arguments were given} property t12: @tr("foo{45}bar", 44); -// ^error{Format string contains 46 placeholders, but only 1 extra arguments were given} +// > t13: @tr("foo{0}ba{}r", 44, 42); -// ^error{Cannot mix positional and non-positional placeholder in format string} +// > t14: @tr("foo{}ba{1}r", 44, 42); -// ^error{Cannot mix positional and non-positional placeholder in format string} +// > t15: @tr("fooba🥸{3}🥸r", 44, 42, 45); -// ^error{Format string contains 4 placeholders, but only 3 extra arguments were given} +// > t16: @tr("foo{} {}ba{}r", 44, 42); -// ^error{Format string contains 3 placeholders, but only 2 extra arguments were given} +// > t17: @tr("fo{}o}r", 44, 42); -// ^error{Unescaped '}' in format string. Escape '}' with '}}'} +// > ctx: @tr("foo" => "fo{}or{}", 42px); -// ^error{Format string contains 2 placeholders, but only 1 extra arguments were given} -// ^^error{Cannot convert length to string. Divide by 1px to convert to a plain number} +// > <^error{Format string contains 2 placeholders, but only 1 extra arguments were given} } diff --git a/internal/compiler/tests/syntax/basic/type_declaration.slint b/internal/compiler/tests/syntax/basic/type_declaration.slint index 314faab1832..0f965e01ecb 100644 --- a/internal/compiler/tests/syntax/basic/type_declaration.slint +++ b/internal/compiler/tests/syntax/basic/type_declaration.slint @@ -2,40 +2,40 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 global MyType := { -// ^warning{':=' to declare a global is deprecated. Remove the ':='} +// > bbb : 42; property ccc; ccc: "hello"; animate bbb { duration: 100ms; } -// ^error{A global component cannot have animations} +// > <^error{Builtin function must be called. Did you forgot the '()'?} aaa <=> bbb; property eee <=> aaa; qqq: 42; -// ^error{Unknown property qqq in } +// > {} animate abcd { duration: 3ms; } changed efgh => { self.foo(); } Hallo {} -// ^error{Unknown element 'Hallo'} +// > <^error{Unknown unqualified identifier 'blue'} } } float { -// ^error{'float' cannot be used as an element} +// > {} Hallo {} -// ^error{Unknown element 'Hallo'} +// > <^error{Unknown unqualified identifier 'blue'} } NativeLineEdit { } -// ^error{Unknown element 'NativeLineEdit'. (The type exists as an internal type, but cannot be accessed in this scope)} +// > { debug("nope"); } -// ^error{A global component cannot have an 'init' callback} +// >error{A global component cannot have an 'init' callback} } +//<<< invalid; - // ^error{Unknown type 'invalid'} +// > { } changed clou => { } - // ^error{Change callback on a private property 'clou'} +// > { } - // ^error{Duplicated change callback on 'zoo'} +// > {} - // ^error{Property 'not-exist' does not exist} +// > { } - // ^error{Change callback can only be set on properties, and 'clicked' is a callback} +// > { } - // ^error{Change callback can only be set on properties, and 'hello' is a function} +// > { } - // ^error{Property 'invalid' does not exist} +// > invalid2; - // ^error{Unknown type 'invalid2'} +// > { } - // ^error{Property 'invalid2' does not exist} +// > invalid3; - // ^error{'Sub' is not a valid type} +// > { } - // ^error{Property 'invalid3' does not exist} +// > error{The @children placeholder cannot appear in a ComponentContainer} @children } +// error{ComponentContainers may not have children} Text {} } +// error{ComponentContainers may not have children} Text { } for x in 2: Rectangle {} Text { } for x in 2: Rectangle {} } +// { -// ^error{'show' is not a callback in ContextMenuArea} +// >error{'show' is not a callback in ContextMenuArea} debug("hello"); } Menu { +// entries: 45; -// ^error{Cannot re-define internal property 'entries'} +// > sub-menu: 45; -// ^error{Cannot re-define internal property 'sub-menu'} +// > activated: "me"; -// ^error{Cannot re-define internal property 'activated'} +// > xyz: "me"; } ContextMenuArea { Rectangle {} } -// ^error{ContextMenuArea should have a Menu} +// > error{Only one Menu is allowed in a ContextMenu} MenuItem { title: "hello"; } } +// { -// ^error{'sub-menu' is not a callback in ContextMenuArea} +// > {} -// ^error{'sub-menu' is not a callback in MenuItem} +// > { cb.activated({}); -// ^error{Element 'ContextMenuArea' does not have a property 'activated'} +// > sub-menu: 45; -// ^error{Cannot re-define internal property 'sub-menu'} +// > entries: 0; -// ^error{Cannot re-define internal property 'entries'} +// > error{Only one MenuBar is allowed in a Window} } +// { mb.focus(); -// ^error{Element 'MenuBar' does not have a property 'focus'} +// > {} -// ^error{'init' is not a callback in MenuBar} +// > { mb.activated({}); -// ^error{Element 'MenuBar' does not have a property 'activated'} +// > error{MenuBar cannot be in a repeated element} } +// error{The Path was already populated in the base type and it can't be re-populated again} LineTo { x: 1; y: 1; } } +// <^error{The close-on-click property only supports constants at the moment} } component D3 inherits PopupWindow { in property pp; close-policy: pp; -// ^error{The close-policy property only supports constants at the moment} +// > external; xx := PopupWindow { close-on-click: true; -// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead} +// > { xx.close-on-click = true; -// ^error{The property must be known at compile time and cannot be changed at runtime} +// > <^error{The close-on-click property only supports constants at the moment} } @@ -55,7 +55,7 @@ export component Bar { PopupWindow { close-policy: close-on-click-outside; close-on-click: true; -// ^error{close-policy and close-on-click cannot be set at the same time} +// > <^error{The close-on-click property only supports constants at the moment} } D1{} @@ -82,7 +82,7 @@ export component Bar { D1{} D2{} D3{ close-on-click: true; } -// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead} +// > error{PopupWindow cannot be the top level} if true : MyPopup2 {} -// ^error{PopupWindow cannot be directly repeated or conditional} +// > { xx.close-policy = PopupClosePolicy.close-on-click; - // ^error{The property must be known at compile time and cannot be changed at runtime} +// > f.visible; -// ^error{The property 'visible' cannot be set for Tabs inside a TabWidget} +// > error{dynamic tabs ('if' or 'for') are currently not supported} title: "hello"; } +// <^error{Unknown element 'TabWidget'. (The type exists as an internal type, but cannot be accessed in this scope)} diff --git a/internal/compiler/tests/syntax/elements/text.slint b/internal/compiler/tests/syntax/elements/text.slint index ecd11b11986..8b81a63e3c7 100644 --- a/internal/compiler/tests/syntax/elements/text.slint +++ b/internal/compiler/tests/syntax/elements/text.slint @@ -4,8 +4,8 @@ export component Foo inherits Rectangle { Text { font-metrics: 42; -// ^error{Cannot assign to output property 'font-metrics'} -// ^^error{Cannot convert float to FontMetrics} +// > <^error{Cannot convert float to FontMetrics} } diff --git a/internal/compiler/tests/syntax/elements/timer.slint b/internal/compiler/tests/syntax/elements/timer.slint index 3aeea968f4a..dc534373b28 100644 --- a/internal/compiler/tests/syntax/elements/timer.slint +++ b/internal/compiler/tests/syntax/elements/timer.slint @@ -5,20 +5,20 @@ export component Def { Timer { interval: 100ms; Rectangle {} - // ^error{Timer cannot have children elements} +// > error{A component cannot inherit from Timer} interval: 50ms; } +//<< error{Timer must have a binding set for its 'interval' property} running: false; } +// <^warning{'SomeRect' is already exported in this file; it will not be re-exported} export {} from "../../typeloader/incpath/dependency_from_incpath.slint"; -//^error{Import names are missing. Please specify which types you would like to re-export} +//> warning{Component is implicitly marked for export. This is deprecated and it should be explicitly exported} Button {} } +//<<warning{Component is implicitly marked for export. This is deprecated and it should be explicitly exported} } +//<<warning{Component is implicitly marked for export. This is deprecated and it should be explicitly exported} } +//<<warning{Global singleton is implicitly marked for export. This is deprecated and it should be explicitly exported} in-out property active; } +//<<warning{Component is neither used nor exported} } +//<< p1: 3s + 1ms; property p2: 3s + 1; // ^error{Cannot convert float to duration. Use an unit, or multiply by 1ms to convert explicitly} property p3: 3s - 1; // ^error{Cannot convert float to duration. Use an unit, or multiply by 1ms to convert explicitly} property p4: 3 / 1ms; -// ^error{Cannot convert (ms⁻¹) to int} +// > p5: 3ms * 1; property p6: 3ms * 1s; -// ^error{Cannot convert (ms²) to duration} +// > p7: "hello" * 1; -// ^error{Cannot convert string to float} +// > p8: 1 - "hello" - 1; -// ^error{Cannot convert string to float} +// > p9: 1 + "hello" + 1; property p10: "hello" + 1ms; -// ^error{Cannot convert duration to string. Divide by 1ms to convert to a plain number} +// > p11: 1ms * 1px *3px / 1deg * 3 / (30px * 1s - 3px * 1ms) * 2deg; property p12: 1ms * 3s / 3px / (2deg * 5turn) * 2s / 3phx; -// ^error{Cannot convert (ms³×phx⁻¹×px⁻¹×deg⁻²) to int} +// > bru: background + background; -// ^error{Cannot convert brush to float} -// ^^error{Cannot convert brush to float} +// > <^error{Cannot convert brush to float} } diff --git a/internal/compiler/tests/syntax/expressions/clamp.slint b/internal/compiler/tests/syntax/expressions/clamp.slint index e9702b80909..f5fff49b1af 100644 --- a/internal/compiler/tests/syntax/expressions/clamp.slint +++ b/internal/compiler/tests/syntax/expressions/clamp.slint @@ -11,28 +11,28 @@ export component SuperSimple { property ok7: clamp(42%, 42%, 42%); property a: clamp + clamp() + clamp(42.0, 41, "hello"); -// ^error{Builtin function must be called. Did you forgot the '()'?} -// ^^error{`clamp` needs three values: the `value` to clamp, the `minimum` and the `maximum`} -// ^^^error{Cannot convert string to float} +// > <^error{`clamp` needs three values: the `value` to clamp, the `minimum` and the `maximum`} +// > <^^error{Cannot convert string to float} property b: clamp(41px, 41phx, 42phx); property c: clamp("a", "b", "c"); -// ^error{Invalid argument type} +// > d: clamp(42, 42 - 1, 42 + 1) + max(1px , 2phx); -// ^error{Cannot convert float to length. Use an unit, or multiply by 1px to convert explicitly} +// > e: clamp(42.0, 23.0, 84.0, 32.0); -// ^error{`clamp` needs three values: the `value` to clamp, the `minimum` and the `maximum`} +// > f: ok1.clamp(); -// ^error{`clamp` needs three values: the `value` to clamp, the `minimum` and the `maximum`} +// > g: ok1.clamp(1,2,3); -// ^error{`clamp` needs three values: the `value` to clamp, the `minimum` and the `maximum`} +// > h: ok1.clamp; -// ^error{Member function must be called. Did you forgot the '()'?} +// > i: 42.0.clamp; -// ^error{Member function must be called. Did you forgot the '()'?} +// > zz: aa > bb == cc -// ^error{Use parentheses to disambiguate equality expression on the same level} +// > yy: aa <= bb <= cc; -// ^error{Use parentheses to disambiguate equality expression on the same level} +// > xx: aa(d); // ^error{Use parentheses to disambiguate equality expression on the same level} property ww: aa && dd && ee || cc == -// ^error{Use parentheses to disambiguate between && and ||} +// > color-cmp: Colors.red > Colors.blue; -// ^error{Values of type color cannot be compared} +// > bool-cmp: true > false; -// ^error{Values of type bool cannot be compared} +// > string-cmp: "eee" > "ddd"; out property array-cmp: [45] < [45]; -// ^error{Values of type [float] cannot be compared} +// > struct-cmp: { foo: 45 } <= { foo: 45 }; -// ^error{Values of type { foo: float,} cannot be compared} +// > c2: area.pressed ? 123 : 456; -// ^error{Cannot convert float to color} +// > c3: area.pressed ? 123 : #456; -// ^error{Cannot convert void to int} -// ^^error{Cannot convert color to float} +// > <^error{Cannot convert void to int} property c4: area.pressed ? 123ms : 123; -// ^error{Cannot convert void to int} -// ^^error{Cannot convert float to duration. Use an unit, or multiply by 1ms to convert explicitly} +// > <^error{Cannot convert void to int} property c5: true ? 123px : 0; property c6: area.pressed ? 123ms : 123; -// ^error{Cannot convert void to duration} -// ^^error{Cannot convert float to duration. Use an unit, or multiply by 1ms to convert explicitly} +// > <^error{Cannot convert void to duration} area := TouchArea { @@ -28,9 +28,9 @@ export SuperSimple := Rectangle { export Test2 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// >error{Cannot convert void to brush} if (true) { } else { blue; @@ -38,8 +38,11 @@ export Test2 := Rectangle { } x: { if (false) {0}; } -// ^error{Cannot convert void to length} +// ^error{Cannot convert void to length} y: { if (false) {0px} else { return 5px; }; } +// something: { if (true) {"hello"} else { return 5px; }; } -// ^error{Cannot convert string to length} +// >error{Cannot convert string to length} } +//<<< i1: @image-url("hello.png"); property path; property i2: @image-url(path); -// ^error{@image-url must contain a plain path as a string literal} +// > i3: @image-url("/home/\{path}.png"); -// ^error{@image-url must contain a plain path as a string literal, without any '\{}' expressions} +// > i4: @image-url("/home/" + path + ".png"); // ^error{Expected ')' or ','} property i5: @image-url(path + ".png"); -// ^error{@image-url must contain a plain path as a string literal} +// > i6: @image-url; // ^error{Syntax error: expected '('} property i7: @image-url("foo", "bar"); -// ^error{Expected 'nine-slice(...)' argument} +// > i8: @image-url("foo", xyz(abc)); -// ^error{Expected 'nine-slice(...)' argument} +// > i9: @image-url("foo", nine-slice(abc)); -// ^error{Expected number literal or ')'} +// > i10: @image-url("foo", nine-slice(1 2 3)); // ^error{Expected 1 or 2 or 4 numbers} property i11: @image-url("foo", nine-slice()); @@ -27,13 +27,13 @@ export component SuperSimple { property i12: @image-url("foo", nine-slice(1 2 3 4 5)); // ^error{Expected 1 or 2 or 4 numbers} property i13: @image-url("foo", nine-slice(1 2 foobar 4 5)); -// ^error{Expected number literal or ')'} +// > i14: @image-url("foo", nine-slice); // ^error{Syntax error: expected '('} property i15: @image-url("foo", nine-slice,); // ^error{Syntax error: expected '('} property i16: @image-url("foo", nine-slice 42 42); -// ^error{Syntax error: expected '('} +// > i17: @image-url("foo", nine-slice(1px)); // error reported later property i18: @image-url("foo", nine-slice(1%)); // error reported later property i19: @image-url("foo", nine-slice(1, 2)); diff --git a/internal/compiler/tests/syntax/expressions/image-url2.slint b/internal/compiler/tests/syntax/expressions/image-url2.slint index 582438032f7..30ca7b114c5 100644 --- a/internal/compiler/tests/syntax/expressions/image-url2.slint +++ b/internal/compiler/tests/syntax/expressions/image-url2.slint @@ -3,13 +3,13 @@ export component SuperSimple { property i17: @image-url("foo", nine-slice(1px)); - // ^error{Border widths of a nine-slice can't have units} +// > i18: @image-url("foo", nine-slice(1%)); - // ^error{Border widths of a nine-slice can't have units} +// > i22: @image-url("foo", nine-slice(123456789)); - // ^error{Number too big} +// > j01: @image-url("foo", nine-slice(1 52deg 456456456 12abc)); - // ^error{Border widths of a nine-slice can't have units} - // ^^error{Border widths of a nine-slice can't have units} - // ^^^error{Number too big} +// > <^error{Number too big} +// > <^^error{Border widths of a nine-slice can't have units} } diff --git a/internal/compiler/tests/syntax/expressions/math-macro.slint b/internal/compiler/tests/syntax/expressions/math-macro.slint index 3adee9954e8..968eb73899c 100644 --- a/internal/compiler/tests/syntax/expressions/math-macro.slint +++ b/internal/compiler/tests/syntax/expressions/math-macro.slint @@ -4,73 +4,73 @@ export component Foo { property m1: mod(4); -// ^error{Needs 2 arguments} +// > m2: mod(4, 5, 5); -// ^error{Needs 2 arguments} +// > m3: mod("455", "465"); -// ^error{Cannot convert string to float} -// ^^error{Cannot convert string to float} +// > <^error{Cannot convert string to float} property m4: mod(455, "465"); -// ^error{Cannot convert string to float} +// > m5: mod(45px, 4); // ^error{Cannot convert float to length. Use an unit, or multiply by 1px to convert explicitly} property m6: mod(45px, 4ms); -// ^error{Cannot convert duration to length} +// > m7: mod(5, 4ms); // ^error{Cannot convert float to duration. Use an unit, or multiply by 1ms to convert explicitly} property m8: (5).mod(4ms); -// ^error{Cannot convert float to duration. Use an unit, or multiply by 1ms to convert explicitly} +// > m9: 5ms.mod(4); // ^error{Cannot convert float to duration. Use an unit, or multiply by 1ms to convert explicitly} property a1: abs(); -// ^error{Needs 1 argument} +// > a2: abs(4, 5, 5); -// ^error{Needs 1 argument} +// > a3: abs(1, 2); -// ^error{Needs 1 argument} +// > a4: abs("465"); -// ^error{Cannot convert string to float} +// > a5: abs(45px); -// ^error{Cannot convert length to string. Divide by 1px to convert to a plain number} +// > a6: abs; -// ^error{Builtin function must be called. Did you forgot the '()'?} +// > a7: (-21).abs; -// ^error{Member function must be called. Did you forgot the '()'?} +// > sq1: 1.0.sqrt(1); -// ^error{The callback or function expects 0 arguments, but 1 are provided} +// > sq2: 1.0.sqrt; -// ^error{Member function must be called. Did you forgot the '()'?} +// > sign1: m1.sign; -// ^error{Member function must be called. Did you forgot the '()'?} +// > sign2: Math.sign(); -// ^error{Expected one argument} +// > sign3: sign(1,2,3); -// ^error{Expected only one argument} +// > sign4: sign(85px); -// ^error{Cannot convert length to float. Divide by 1px to convert to a plain number} +// > sign5: sign("4"); -// ^error{Cannot convert string to float} +// > sign6: sign; -// ^error{Builtin function must be called. Did you forgot the '()'?} +// > sign7: sign(4,6); -// ^error{Expected only one argument} -} \ No newline at end of file +// > a: max + max() + max(45, "hello"); -// ^error{Builtin function must be called. Did you forgot the '()'?} -// ^^error{Needs at least one argument} -// ^^^error{Invalid argument type} +// > <^error{Needs at least one argument} +// > <^^error{Invalid argument type} property b: max(41px, 41phx); property c: max("a", "b"); -// ^error{Invalid argument type} +// > d: min + min() + min(45, "hello"); -// ^error{Builtin function must be called. Did you forgot the '()'?} -// ^^error{Needs at least one argument} -// ^^^error{Invalid argument type} +// > <^error{Needs at least one argument} +// > <^^error{Invalid argument type} property e: min(41px, 41phx); property f: min("a", "b"); -// ^error{Invalid argument type} +// > g: min(42, 42, 42cm); -// ^error{Cannot convert float to length. Use an unit, or multiply by 1px to convert explicitly} -// ^^error{Cannot convert float to length. Use an unit, or multiply by 1px to convert explicitly} +// ><^error{Cannot convert float to length. Use an unit, or multiply by 1px to convert explicitly} property h: min(42, 42 + 1) + max(1px , 2phx); -// ^error{Cannot convert float to length. Use an unit, or multiply by 1px to convert explicitly} +// > warning{Expression has no effect!} if (!cond) { -// ^warning{Expression has no effect!} +// >warning{Expression has no effect!} 43 } 42 +// p1: "hello\"world"; property p2: "hello\\"; property p3: "hello\world"; -// ^error{Cannot parse string literal} +// > err_str1: + "foobar"; -// ^error{Unary '+' not supported on string} +// > err_str2: - "foobar"; -// ^error{Unary '-' not supported on string} +// > err_str3: "foo" + + "bar"; -// ^error{Unary '+' not supported on string} +// > err_str4: ! "foobar"; -// ^error{Cannot convert string to bool} +// > ok1: +1; property ok2: -1cm; property hey: "foo" + - 45; property <{x: int}> p1: - { x: 42 }; -// ^error{Unary '-' not supported on { x: float,}} +// > p2: + { x: 42 }; -// ^error{Unary '+' not supported on { x: float,}} +// > p3: ! { x: 42 }; -// ^error{Cannot convert { x: float,} to bool} +// > p4: [!42]; -// ^error{Cannot convert float to bool} +// > { (edit.focus)(); -// ^error{Member function must be called. Did you forgot the '()'?} +// > { fs.focus(0); -// ^error{The callback or function expects 0 arguments, but 1 are provided} +// > { someRect.focus(); -// ^error{focus() can only be called on focusable elements} +// > { r0.focus(); x.focus(); -// ^error{focus() can only be called on focusable elements} +// > int { return a; } // ^error{Duplicated argument name 'a'} function plop2() -> int { -// ^error{Cannot convert string to int} +// >error{Cannot convert string to int} return 45; "xxx" } +// int { return "45"; } -// ^error{Cannot convert string to int} +// > par; -// ^error{Cannot declare property 'par' when a function with the same name exists} +// > {} } -// ^error{'par' is not a callback in Abc} +// > aa.par; } -// ^error{Cannot assign to par in Abc because it does not have a valid property type} -// ^^error{Cannot bind to a function} -// ^^^error{The function 'par' is private. Annotate it with 'public' to make it accessible from other components} +// > <^error{The function 'par' is private. Annotate it with 'public' to make it accessible from other components} +// > <^^error{Cannot bind to a function} fooo => {} -// ^error{'fooo' is not a callback in Rectangle} +// > string { return a; } comp := Comp {} function bar() { foo(45, 45); -// ^error{The callback or function expects 1 arguments, but 2 are provided} +// > <^error{Cannot convert string to int} 45()()(); -// ^error{The expression is not a function} +// > foo; -// ^error{Binding to callback 'xx' must bind to another callback} +// > { f2() } c2 => { c1(); -// ^error{Call of impure callback 'c1'} +// > p1: f2(); property p2: { p1 = 42; -// ^error{Assignment in a pure context} +// > p3: { pw.show(); -// ^error{Call of impure function} +// > [int]; for xx in model() : Rectangle { -// ^error{Call of impure callback 'model'} +// > abc: xx; } } @@ -74,13 +74,13 @@ export component Foo { export component Bar { pure callback xc1 <=> f.c1; -// ^error{Purity of callbacks 'xc1' and 'f.c1' doesn't match} +// > f.c2; -// ^error{Purity of callbacks 'xc2' and 'f.c2' doesn't match} +// > { self.c1(); -// ^error{Call of impure callback 'c1'} +// > prop; callback c1; pure callback c2; @@ -103,44 +103,44 @@ export Foo_Legacy := Rectangle { pure function f3() { f2(); f1(); -// ^warning{Call of impure function 'f1'} +// > { f2() } c2 => { c1(); -// ^warning{Call of impure callback 'c1'} +// > p1: f2(); property p2: { p1 = 42; -// ^warning{Assignment in a pure context} +// > p3: { pw.show(); -// ^warning{Call of impure function} +// > f.c1; -// ^error{Purity of callbacks 'xc1' and 'f.c1' doesn't match} +// > f.c2; -// ^error{Purity of callbacks 'xc2' and 'f.c2' doesn't match} +// > { self.c1(); -// ^warning{Call of impure callback 'c1'} +// > color { blue -// ^error{Function must be called. Did you forgot the '()'?} +// >error{Function must be called. Did you forgot the '()'?} } +// abc: get_abc1(); function get_abc1() -> int { return get_abc2(); } -// ^error{The binding for the property 'get-abc1' is part of a binding loop (root.get-abc2 -> root.get-abc1)} +// > root.get-abc1)} function get_abc2() -> int { return get_abc1(); } -// ^error{The binding for the property 'get-abc2' is part of a binding loop (root.get-abc2 -> root.get-abc1)} +// > root.get-abc1)} } diff --git a/internal/compiler/tests/syntax/fuzzing/6512.slint b/internal/compiler/tests/syntax/fuzzing/6512.slint index c738ffaa438..f92065f916c 100644 --- a/internal/compiler/tests/syntax/fuzzing/6512.slint +++ b/internal/compiler/tests/syntax/fuzzing/6512.slint @@ -4,7 +4,7 @@ component T{function r@tr""| // ^error{Syntax error: expected '('} // ^^error{Syntax error: expected '{'} -// ^^^error{Syntax error: expected '('} +// ><^^error{Syntax error: expected '('} ""}}} // ^error{Syntax error: expected '%'} diff --git a/internal/compiler/tests/syntax/fuzzing/6518.slint b/internal/compiler/tests/syntax/fuzzing/6518.slint index b9fdcd64ab3..deeb1aeebeb 100644 --- a/internal/compiler/tests/syntax/fuzzing/6518.slint +++ b/internal/compiler/tests/syntax/fuzzing/6518.slint @@ -2,14 +2,14 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 Compo1:=R{property'} // ^^^error{Syntax error: expected '('} // ^^^^error{Syntax error: expected '{'} // ^^^^^error{invalid expression} // ^^^^^^error{Syntax error: expected '}'} // ^^^^^^^error{Parse error} -// ^^^^^^^^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// ><^^^^^^^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} } // ^error{Syntax error: expected ';'} diff --git a/internal/compiler/tests/syntax/fuzzing/6519.slint b/internal/compiler/tests/syntax/fuzzing/6519.slint index 68a76070b22..ddbc82022e0 100644 --- a/internal/compiler/tests/syntax/fuzzing/6519.slint +++ b/internal/compiler/tests/syntax/fuzzing/6519.slint @@ -7,11 +7,11 @@ component Button{ // ^error{Syntax error: expected ';'} export component C{ in property'} +// >'} Button { -// ^error{Syntax error: expected ';'} +// > in obal -// ^error{Syntax error: expected ';'} +// > '} +// >'} Button{ enabled <=>in; -//^error{Syntax error: expected ';'} +//> warning{Component is implicitly marked for export. This is deprecated and it should be explicitly exported} preferred-height: x; // ^error{Unknown unqualified identifier 'x'. Did you mean 'self.x'?} Image { } } +//<<t.has-focus; -// ^error{Cannot assign to output property 'has-focus'} +// > name; TouchArea{ clicked=>{debug[9]()} -// ^error{Builtin function must be called. Did you forgot the '()'?} +// > {abc[9]()} -// ^error{Function must be called. Did you forgot the '()'?} +// > {self.moved[9]()} -// ^error{Callback must be called. Did you forgot the '()'?} +// > { input2.focus(); -// ^error{Call of impure function} +// > t <=>t; text :=Text { } } export ae:=Rectangle{ -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// >t;} // ^warning{Assigning to output property 't' is deprecated} -// ^^error{Property cannot alias to itself} +// > <^error{Property cannot alias to itself} } \ No newline at end of file diff --git a/internal/compiler/tests/syntax/imports/bug_2719.slint b/internal/compiler/tests/syntax/imports/bug_2719.slint index b3cd1453e01..f54c818b477 100644 --- a/internal/compiler/tests/syntax/imports/bug_2719.slint +++ b/internal/compiler/tests/syntax/imports/bug_2719.slint @@ -4,12 +4,12 @@ import { Qq } from "../../typeloader/incpath/bug_2719_import.slint"; import { SomeRect } from "tests/typeloader/incpath/local_helper_type.slint"; -// ^warning{Loading "tests/typeloader/incpath/local_helper_type.slint" relative to the work directory is deprecated. Files should be imported relative to their import location} +// > b.foo; -// ^error{Element 'Bug' does not have a property 'foo'} -// ^^error{Could not infer type of property 't1'} +// > <^error{Could not infer type of property 't1'} out property t2 <=> b.bar; callback t3 <=> b.bar; -// ^error{Binding to callback 't3' must bind to another callback} +// > b.xxx; -// ^error{Element 'Bug' does not have a property 'xxx'} -// ^^error{Could not infer type of property 't4'} +// > <^error{Could not infer type of property 't4'} out property t5 <=> b.xyz; -// ^error{Element 'Bug' does not have a property 'xyz'} -// ^^error{Could not infer type of property 't5'} +// > <^error{Could not infer type of property 't5'} out property t6 <=> b.foo; -// ^error{Element 'Bug' does not have a property 'foo'} +// > <^error{Unknown element 'Rec12'} width: 100px; } diff --git a/internal/compiler/tests/syntax/imports/error_in_import.slint b/internal/compiler/tests/syntax/imports/error_in_import.slint index 50b67555e7b..e106942a746 100644 --- a/internal/compiler/tests/syntax/imports/error_in_import.slint +++ b/internal/compiler/tests/syntax/imports/error_in_import.slint @@ -4,12 +4,12 @@ import { X } from "../../typeloader/incpath/should_fail2.slint"; export Foo := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > b: b1; } diff --git a/internal/compiler/tests/syntax/imports/font.slint b/internal/compiler/tests/syntax/imports/font.slint index 881690e0876..9a17f776476 100644 --- a/internal/compiler/tests/syntax/imports/font.slint +++ b/internal/compiler/tests/syntax/imports/font.slint @@ -2,12 +2,12 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 import "myfont.ttf"; -// ^error{File "myfont.ttf" not found} +// > <^error{Unknown element 'Plop'} } diff --git a/internal/compiler/tests/syntax/imports/just_import.slint b/internal/compiler/tests/syntax/imports/just_import.slint index 286ad415423..595fb749c1a 100644 --- a/internal/compiler/tests/syntax/imports/just_import.slint +++ b/internal/compiler/tests/syntax/imports/just_import.slint @@ -2,5 +2,5 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 import { SomeRect } from "../../typeloader/incpath/local_helper_type.slint"; -//^warning{No component is exported. The last imported component 'SomeRect' will be used. This is deprecated} +//> condition; GridLayout { Row { if (condition): Text { -// ^error{'if' or 'for' expressions are not currently supported in grid layouts} +// >error{'if' or 'for' expressions are not currently supported in grid layouts} } +// error{'if' or 'for' expressions are not currently supported in grid layouts} } +// error{'if' or 'for' expressions are not currently supported in grid layouts} } +// error{'if' or 'for' expressions are not currently supported in grid layouts} Rectangle {} } +// { self.absolute-position.x += 45px; -// ^error{Self assignment on a output property} +// > aa: 45; property <{o:[int], c:string}> bb; property xx: aa[2]; -// ^error{int is not an indexable type} +// > yy: dontexist[2]; -// ^error{Unknown unqualified identifier 'dontexist'} +// > zz: bb.o[2].aa; property ww: bb.c[2]; -// ^error{string is not an indexable type} +// > uu: bb.o[bb.c]; -// ^error{Cannot convert string to int} +// > int; } callback plop(int) -> int <=> foo.hello; -// ^error{When declaring a callback alias, one must omit parentheses. e.g. 'callback foo <=> other.bar;'} +// > other.bar;'} callback plopsi() <=> foo.hello; -// ^error{When declaring a callback alias, one must omit parentheses. e.g. 'callback foo <=> other.bar;'} +// > other.bar;'} } diff --git a/internal/compiler/tests/syntax/lookup/callback_alias2.slint b/internal/compiler/tests/syntax/lookup/callback_alias2.slint index 8d8f97817e8..969eaae235c 100644 --- a/internal/compiler/tests/syntax/lookup/callback_alias2.slint +++ b/internal/compiler/tests/syntax/lookup/callback_alias2.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export Xxx := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > int; @@ -10,13 +10,13 @@ export Xxx := Rectangle { callback bar(int) -> int; bar <=> foo.hello; -// ^error{Unknown property bar in Rectangle} +// > dontexist; -// ^error{Binding to callback 'row-pointer-event' must bind to another callback} -// ^^error{Unknown unqualified identifier 'dontexist'} +// > <^error{Binding to callback 'row-pointer-event' must bind to another callback} row-pointer-event => {} -// ^error{Duplicated callback} +// > int; callback compute_alias <=> compute; } export Xxx := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > int; } callback colr <=> foo.background; -// ^error{Binding to callback 'colr' must bind to another callback} +// > foo.hello; -// ^error{Could not infer type of property 'propr'} +// > loop2; callback loop3 <=> loop1; -// ^error{Binding to callback 'loop3' must bind to another callback} -// ^^error{Unknown unqualified identifier 'loop1'} +// > <^error{Binding to callback 'loop3' must bind to another callback} callback loop2 <=> loop3; Sub { compute_alias(a, b, c) => { -// ^error{'compute-alias' only has 1 arguments, but 3 were provided} +// > compute_alias; diff --git a/internal/compiler/tests/syntax/lookup/callback_alias_global.slint b/internal/compiler/tests/syntax/lookup/callback_alias_global.slint index e79eb4f2fdb..467c8dc080e 100644 --- a/internal/compiler/tests/syntax/lookup/callback_alias_global.slint +++ b/internal/compiler/tests/syntax/lookup/callback_alias_global.slint @@ -7,12 +7,12 @@ export global Abc { component Wrapper { callback foo <=> Abc.foobar; -// ^warning{Aliases to global callback are deprecated. Export the global to access the global callback directly from native code} +// > { debug("hello"); } -// ^error{Can't assign a local callback handler to an alias to a global callback} +// > issue4938; -// ^error{Cannot alias to itself} +// > { root -// ^error{Callback must be called. Did you forgot the '()'?} +// >error{Callback must be called. Did you forgot the '()'?} .foobar } +// string; plop => {} -// ^error{Cannot convert void to string} +// >error{Cannot convert void to string} callback plop2() -> int; +// { return 45; "xxx" } -// ^error{Cannot convert string to int} +// >error{Cannot convert string to int} callback plop3(); +// { return 45; "xxx" } } diff --git a/internal/compiler/tests/syntax/lookup/color.slint b/internal/compiler/tests/syntax/lookup/color.slint index 907ee8fcb9c..56cae0b94a1 100644 --- a/internal/compiler/tests/syntax/lookup/color.slint +++ b/internal/compiler/tests/syntax/lookup/color.slint @@ -3,7 +3,7 @@ export X := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > a: #abq; -// ^error{Invalid color literal} +// > b: 123; -// ^error{Cannot convert float to color} +// > xxx: Colors.xxx; -// ^error{'xxx' is not a member of the namespace Colors} +// > c1: rgba(); -// ^error{This function needs 3 or 4 arguments, but 0 were provided} +// > c2: rgb(45); -// ^error{This function needs 3 or 4 arguments, but 1 were provided} +// > c3: Colors.rgb(45,45); -// ^error{This function needs 3 or 4 arguments, but 2 were provided} +// > c4: Colors.rgba(1,2,3,4,5); -// ^error{This function needs 3 or 4 arguments, but 5 were provided} +// > c5: Colors.hsv(1,2,3,4,5); -// ^error{This function needs 3 or 4 arguments, but 5 were provided} +// > foo: y; -// ^error{Cannot convert length to int. Divide by 1px to convert to a plain number} +// > bar: foo; -// ^error{Cannot convert int to duration. Use an unit, or multiply by 1ms to convert explicitly} +// > no_matching_parent: 50%; -// ^error{Automatic conversion from percentage to length is only possible for the following properties: width, height, preferred-width, preferred-height} +// > object1: { a: "123", typo: 42}; -// ^error{Cannot convert { a: string,typo: float,} to { a: string,b: int,}} +// > ccc: [{a: []}, {}, {a: ["123"]}, {a: [123]}]; // (FIXME: error location) (FIXME: duplicated) -// ^error{Cannot convert string to int} -// ^^error{Cannot convert string to int} +// > <^error{Cannot convert string to int} property arr1: []; -// ^error{Cannot convert [void] to int} +// > arr2: {a: []}; -// ^error{Cannot convert [void] to int} +// > arr3: false ? [] : 45; //(FIXME: error not ideal) -// ^error{Cannot convert void to int} -// ^^error{Cannot convert float to [void]} +// > <^error{Cannot convert void to int} property to-float: "foobar".to-float; -// ^error{Member function must be called. Did you forgot the '()'?} +// > x1: my-rect.width; property x2: my-rect.width-1px; -// ^error{Element 'Rectangle' does not have a property 'width-1px'. Use space before the '-' if you meant a subtraction} +// > x3: my_rect.border-width; property x4: my_rect.border_width-1px; -// ^error{Element 'Rectangle' does not have a property 'border_width-1px'. Use space before the '-' if you meant a subtraction} +// > obj: {a_b: "hello", d-c: "world", e-f: "!"}; property t1: -obj.xx-42; -// ^error{Cannot access the field 'xx-42'. Use space before the '-' if you meant a subtraction} +// > t2: -obj.xx.hello-world; -// ^error{Cannot access the field 'hello-world'. Use space before the '-' if you meant a subtraction} +// > t3: x-4; -// ^error{Unknown unqualified identifier 'x-4'. Use space before the '-' if you meant a subtraction} +// > t4: foo-bar; -// ^error{Unknown unqualified identifier 'foo-bar'} +// > t5: x_y; -// ^error{Unknown unqualified identifier 'x_y'} +// > t6: obj.a-bc; -// ^error{Cannot access the field 'a-bc'} +// > t7: obj.xx.obj-4; -// ^error{Cannot access the field 'obj-4'} +// > <^warning{The property 'maximum-width' has been deprecated. Please use 'max-width' instead} callback not_called; not_called() => { color = #000000; -// ^warning{The property 'color' has been deprecated. Please use 'background' instead} +// > animation2: { easing: Easing.some-curve, -// ^error{'some-curve' is not a member of the namespace Easing} +// > animation3: { easing: Easing, -// ^error{Cannot take reference to a namespace} +// > animation4: { @@ -26,6 +26,6 @@ export component Test inherits Rectangle { property animation5: { easing: Easing.cubic-bezier(0.05, 07) -// ^error{Not enough arguments} +// > ggg: pp; -// ^error{Cannot convert { a: physical-length,b: string,} to int} +// > shown: true; clicked => { shown = !shown; } } for xx in inner_for.model: inner_for := Rectangle { -// ^error{Cannot access id 'inner_for'} +// > model: [1,2,3,4]; } for xx in inner_model: Rectangle { -// ^error{Unknown unqualified identifier 'inner_model'} +// > inner_model: [1,2,3,4]; } if element_inside_if.pressed : Rectangle { -// ^error{Cannot access id 'element_inside_if'} +// > foo; } global my_lowercase := { -// ^warning{':=' to declare a global is deprecated. Remove the ':='} +// > xxx: my_lowercase.background; property yyy: my_lowercase.glob; // error because this is not the global, but the local element -// ^error{Element 'Rectangle' does not have a property 'glob'} +// > zzz: self.my_lowercase; diff --git a/internal/compiler/tests/syntax/lookup/if.slint b/internal/compiler/tests/syntax/lookup/if.slint index 0a05da7f1de..5b02eddd043 100644 --- a/internal/compiler/tests/syntax/lookup/if.slint +++ b/internal/compiler/tests/syntax/lookup/if.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export Hello := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > counter: 42; callback request-increase-value(); VerticalLayout { @@ -23,8 +23,9 @@ component Button inherits Rectangle { states [ highlight when counter > 45 : { background: red; -// ^error{Internal error: The expression for the default state currently cannot be represented: https://github.com/slint-ui/slint/issues/1461↵As a workaround, add a binding for property background} +// >error{Internal error: The expression for the default state currently cannot be represented: https://github.com/slint-ui/slint/issues/1461↵As a workaround, add a binding for property background} } +// error{'root.animate' is not a property} root.clicked: "blue"; -// ^error{'root.clicked' is not a property} +// ^error{'root.clicked' is not a property} } +// t1: { xxx: 42 }; - property t2: Type2.AAA; -// ^error{Cannot access id 'Type2'} // because in the lookup phase it was already erased + property t2: Type2.AAA; // > { debug(Type1.CCC); // This is allowed because the resolving phase has full view on the document debug(Type2.AAA); -// ^error{Cannot access id 'Type2'} +// > t1: Type1.DDD; property t2: { yyy: 42 }; property error: Type2.AAA; - // ^error{Cannot access id 'Type2'} +// > custom_prop; property color_prop; color_prop: red; @@ -10,14 +10,14 @@ Comp := Rectangle { Rectangle { x: custom_prop; y: nothing; -// ^error{Unknown unqualified identifier 'nothing'} +// > { ["hello"].length = 45; -// ^error{Assignment needs to be done on a property} +// > abc; cde := Rectangle { y: cde * 1px -// ^error{Cannot take reference of an element. Use 'abc.cde' to access the property with the same name} +// > glop_col; @@ -10,25 +10,25 @@ export Xxx := Rectangle { plop2(x, blah, hello) => { background = blah; x = 42 + hello; -// ^error{Assignment needs to be done on a property} +// > <^error{The expression is not a function} (plop)("45", #fff, 42); -// ^error{Callback must be called. Did you forgot the '()'?} +// > my_color <=> self.background; x <=> y; @@ -18,28 +18,28 @@ export X := Rectangle { border_color <=> blue; -// ^error{The expression in a two way binding must be a property reference} +// > 4px + 4px; -// ^error{The expression in a two way binding must be a property reference} +// > parent.width; height <=> x; background <=> root.x; -// ^error{The property does not have the same type as the bound property} +// > y; -// ^error{Property cannot alias to itself} +// > dd <=> dd; -// ^error{Property cannot alias to itself} +// > self.loop_on_x; -// ^error{The binding for the property 'x' is part of a binding loop (x -> loop-on-x)} +// > loop-on-x)} property loop_on_x <=> x; -// ^error{The binding for the property 'loop-on-x' is part of a binding loop (x -> loop-on-x)} +// > loop-on-x)} } property gyoyo <=> G.yoyo; diff --git a/internal/compiler/tests/syntax/lookup/two_way_binding_infer.slint b/internal/compiler/tests/syntax/lookup/two_way_binding_infer.slint index faa13c95895..0b831c51d2a 100644 --- a/internal/compiler/tests/syntax/lookup/two_way_binding_infer.slint +++ b/internal/compiler/tests/syntax/lookup/two_way_binding_infer.slint @@ -2,32 +2,32 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export X := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > infer_loop2; -// ^error{Could not infer type of property 'infer-loop'} +// > infer_loop3; -// ^error{Could not infer type of property 'infer-loop2'} +// > infer_loop; -// ^error{Could not infer type of property 'infer-loop3'} -// ^^error{Unknown unqualified identifier 'infer_loop'} +// > <^error{Could not infer type of property 'infer-loop3'} property infer_error <=> r.infer_error; -// ^error{Could not infer type of property 'infer-error'} +// > 0; -// ^error{Could not infer type of property 'infer-error'} -// ^^error{The expression in a two way binding must be a property reference} +// ^error{The expression in a two way binding must be a property reference} +// > <^error{Could not infer type of property 'infer-error'} } property auto_background <=> background; property alias_to_background <=> auto_background; -// ^error{The property does not have the same type as the bound property} +// > self.opacity; abc: "eee"; -// ^error{Duplicated property binding} +// > model; for item in model: Text { text <=> item.field; -// ^error{Two-way bindings to model data is not supported yet} +// > inout2: 42; private property priv2: inout2; out property output1: priv2; @@ -49,11 +49,11 @@ OldCompo := Rectangle { TouchArea { clicked => { pub1 = 32; -// ^error{Unknown unqualified identifier 'pub1'} +// > { out1 = 42; in1 = 55; -// ^error{Assignment on a input property} +// > inout2: 42; private property priv2: inout2; out property output1: priv2; @@ -53,21 +53,21 @@ OldCompo := Rectangle { priv2 = 78; output1 = input1; input1 = 75; -// ^error{Assignment on a input property} +// > { c1.inout2 = 32; c1.priv2 = 78; -// ^error{The property 'priv2' is private. Annotate it with 'in', 'out' or 'in-out' to make it accessible from other components} +// > background: text; -// ^error{Unknown unqualified identifier 'text'. Did you mean 'self.text'?} +// > b.pressed; // ok (but then there should be no other assignment?) in <=> b.pressed; // Error -// ^error{Cannot link to a output property} +// > b.pressed; -// ^error{Cannot link to a output property} +// > b.pressed; // makes assignment forbidden @@ -28,17 +28,17 @@ export component C1 { b:= Button { clicked => { in = !in; -// ^error{Assignment on a input property} +// > { in = !in; -// ^error{Assignment on a input property} +// > b.checked; in <=> b.checked; -// ^warning{Linking input properties to input output properties is deprecated} +// > b.checked; priv <=> b.checked; b:= Button { clicked => { in = !in; -// ^error{Assignment on a input property} +// > in; clicked => { self.enabled = !self.enabled; } -// ^error{Cannot modify a property that is linked to a read-only property} +// > inout; } Button { enabled <=> priv; } @@ -136,7 +136,7 @@ export component C6 { } Button { checked <=> in; -// ^error{Cannot link to a input property} +// > { self.checked = !self.checked; } } Button { @@ -155,31 +155,31 @@ export component C7 { self.enabled = !self.enabled; self.checked = !self.checked; self.pressed = !self.pressed; -// ^error{Assignment on a output property} +// > b1.pressed; clicked => { self.enabled = !self.enabled; } -// ^error{Cannot modify a property that is linked to a read-only property} +// > { self.enabled = !self.enabled; self.checked = !self.checked; self.pressed = !self.pressed; -// ^error{Assignment on a output property} +// > b2.pressed; } -// ^error{Cannot link to a output property} +// > { self.enabled = !self.enabled; self.checked = !self.checked; self.pressed = !self.pressed; -// ^error{Assignment on a output property} +// > { out1 = !out1; out2 = !out2; -// ^error{Cannot modify a property that is linked to a read-only property} +// > out <=> in1; in property in <=> in2; -// ^error{Cannot link to a input property} +// > inout <=> in3; -// ^error{Cannot link to a input property} +// > priv <=> in4; Button { clicked => { out = !out; -// ^error{Cannot modify a property that is linked to a read-only property} +// > out <=> inout1; in property in <=> inout2; -// ^error{Cannot link input property} +// > inout <=> inout3; property priv <=> inout4; @@ -261,7 +261,7 @@ export component C10 { inout4 = !inout4; out = !out; in = !in; -// ^error{Assignment on a input property} +// > { priv1 = !priv1; priv2 = !priv2; -// ^error{Cannot modify a property that is linked to a read-only property} +// > in1 <=> btn.pressed; -// ^error{Cannot link to a output property} +// > in2 <=> btn.checked; -// ^warning{Linking input properties to input output properties is deprecated} +// > in3 <=> btn.enabled; in property in4 <=> btn.accessible-checked; in property in5 <=> inout1; -// ^error{Cannot link input property} +// > boggus1 <=> btn.internal; -// ^error{The property 'internal' is private. Annotate it with 'in', 'out' or 'in-out' to make it accessible from other components} +// > inout1; btn := Button { clicked => { self.checked = !self.checked; -// ^error{Cannot modify a property that is linked to a read-only property} +// > priv; Button { internal <=> in; } -// ^error{Cannot assign to private property 'internal'} +// > out; } -// ^error{Cannot assign to private property 'internal'} +// > priv; } -// ^error{Cannot assign to private property 'internal'} +// > inout; } -// ^error{Cannot assign to private property 'internal'} +// > self.checked; } -// ^error{Cannot assign to private property 'internal'} +// > self.pressed; } -// ^error{Cannot assign to output property 'pressed'} +// > self.checked; } -// ^error{Cannot assign to output property 'pressed'} +// > self.enabled; } -// ^error{Cannot assign to output property 'pressed'} +// > self.accessible-checked; } -// ^error{Cannot assign to output property 'pressed'} +// > self.internal; } -// ^error{Cannot assign to output property 'pressed'} -// ^^error{The property 'internal' is private. Annotate it with 'in', 'out' or 'in-out' to make it accessible from other components} +// > <^error{The property 'internal' is private. Annotate it with 'in', 'out' or 'in-out' to make it accessible from other components} Button { pressed <=> out; } -// ^error{Cannot assign to output property 'pressed'} +// > in; } -// ^error{Cannot assign to output property 'pressed'} +// > inout; } -// ^error{Cannot assign to output property 'pressed'} +// > priv; } -// ^error{Cannot assign to output property 'pressed'} +// > b1.pressed; -// ^warning{Link to a output property is deprecated} +// > b1.pressed; in-out property inout1 <=> b1.pressed; -// ^warning{Link to a output property is deprecated} +// > p1; Button { pressed <=> p1; -// ^warning{Assigning to output property 'pressed' is deprecated} +// > { p1 = !p1; out1 = !out1; -// ^warning{Modifying a property that is linked to a read-only property is deprecated} +// > self.pressed; clicked => { self.enabled = !self.enabled; -// ^warning{Modifying a property that is linked to a read-only property is deprecated} +// > out; in property in; in-out property inout; property priv; Button { internal <=> in; } -// ^error{Cannot assign to private property 'internal'} +// > out; } -// ^error{Cannot assign to private property 'internal'} +// > priv; } -// ^error{Cannot assign to private property 'internal'} +// > inout; } -// ^error{Cannot assign to private property 'internal'} +// > self.checked; } -// ^error{Cannot assign to private property 'internal'} +// > self.pressed; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > self.checked; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > self.enabled; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > self.accessible-checked; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > self.internal; } -// ^warning{Assigning to output property 'pressed' is deprecated} -// ^^error{The property 'internal' is private. Annotate it with 'in', 'out' or 'in-out' to make it accessible from other components} +// > <^error{The property 'internal' is private. Annotate it with 'in', 'out' or 'in-out' to make it accessible from other components} Button { pressed <=> out; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > in; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > inout; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > priv; } -// ^warning{Assigning to output property 'pressed' is deprecated} +// > <^error{Syntax error: expected ':'} // ^^^error{Parse error} Foo { } } diff --git a/internal/compiler/tests/syntax/parse_error/property1.slint b/internal/compiler/tests/syntax/parse_error/property1.slint index 5972d5af2ed..417f5ecd317 100644 --- a/internal/compiler/tests/syntax/parse_error/property1.slint +++ b/internal/compiler/tests/syntax/parse_error/property1.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export TestCase := Window { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > name;`. Only two way bindings can omit the type} +// > name;`. Only two way bindings can omit the type} property bar: 45; -// ^error{Missing type. The syntax to declare a property is `property name;`. Only two way bindings can omit the type} +// > name;`. Only two way bindings can omit the type} property hello <=> ta.pressed; property <=> ta.pressed; property yo yo; -// ^error{Missing type. The syntax to declare a property is `property name;`. Only two way bindings can omit the type} -// ^^error{Syntax error: expected ';'} +// > name;`. Only two way bindings can omit the type} +// ><^error{Syntax error: expected ';'} // ^^^error{Parse error} diff --git a/internal/compiler/tests/syntax/parse_error/state1.slint b/internal/compiler/tests/syntax/parse_error/state1.slint index 2e2d0e7e2fd..5b3f3dc0697 100644 --- a/internal/compiler/tests/syntax/parse_error/state1.slint +++ b/internal/compiler/tests/syntax/parse_error/state1.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export TestCase := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > checked; property border; states [ diff --git a/internal/compiler/tests/syntax/parse_error/state2.slint b/internal/compiler/tests/syntax/parse_error/state2.slint index e9684d6033f..c2601550335 100644 --- a/internal/compiler/tests/syntax/parse_error/state2.slint +++ b/internal/compiler/tests/syntax/parse_error/state2.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export TestCase := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > ` and `<` characters. +//! The `>` and `<` indicators may also appear individually, if the diagnostic spans multiple lines. +//! A `^` character means that the diagnostic must only span that single character. +//! +//! If there are additional `^` characters: `> <^error{expected_message}` then it means the comment refers to a diagnostic two lines above, instead of one, and so on with more carets. +//! +//! If there are additional `<` characters: `> < std::io::Result { ) } +struct ExpectedDiagnostic { + start: Option, + end: Option, + level: DiagnosticLevel, + message: String, + comment_range: Range, +} + +fn extract_expected_diags(source: &str) -> Vec { + let mut expected = Vec::new(); + // Find expected errors in the file. The first caret (^) points to the expected column. The number of + // carets refers to the number of lines to go back. This is useful when one line of code produces multiple + // errors or warnings. + let re = regex::Regex::new( + r"\n *//[^\n\^<>]*((\^)|((>)?( *<)?))(\^*)(<*)(error|warning)\{([^\n]*)\}", + ) + .unwrap(); + // regex::Regex::new(r"\n *//[^\n\^<>]*(\^|>|<)(\^*)(error|warning)\{([^\n]*)\}").unwrap(); + for m in re.captures_iter(source) { + let line_begin_offset = m.get(0).unwrap().start(); + let start_column = m.get(1).unwrap().start() + - line_begin_offset + // Allow shifting columns with < + - m.get(7).map(|group| group.as_str().len()).unwrap_or_default(); + + let lines_to_source = m.get(6).map(|group| group.as_str().len()).unwrap_or_default() + 1; + let warning_or_error = m.get(8).unwrap().as_str(); + let expected_message = + m.get(9).unwrap().as_str().replace('↵', "\n").replace('📂', env!("CARGO_MANIFEST_DIR")); + let comment_range = m.get(0).unwrap().range(); + + let mut line_counter = 0; + let mut line_offset = source[..line_begin_offset].rfind('\n').unwrap_or(0); + let mut offset = loop { + line_counter += 1; + if line_counter >= lines_to_source { + break line_offset + start_column; + } + if let Some(o) = source[..line_offset].rfind('\n') { + line_offset = o; + } else { + break 1; + }; + }; + + let mut start = None; + let mut end = None; + if m.get(2).is_some() { + // ^warning{...} + start = Some(offset); + end = Some(offset); + } else { + // > + if m.get(4).is_some() { + start = Some(offset); + offset += 1; + } + // < (including spaces before) + if let Some(range_length) = m.get(5).map(|group| group.as_str().len()) { + end = Some(offset + range_length - 1); + } + } + + // Windows edge-case, if the end falls on a newline, it should span the entire + // newline character, which is two characters, not one. + if let Some(end_offset) = end { + if source.get(end_offset..=(end_offset + 1)) == Some("\r\n") { + end = Some(end_offset + 1) + }; + } + + let expected_diag_level = match warning_or_error { + "warning" => DiagnosticLevel::Warning, + "error" => DiagnosticLevel::Error, + _ => panic!("Unsupported diagnostic level {warning_or_error}"), + }; + + expected.push(ExpectedDiagnostic { + start, + end, + level: expected_diag_level, + message: expected_message, + comment_range, + }); + } + expected +} + fn process_diagnostics( compile_diagnostics: &BuildDiagnostics, path: &Path, @@ -107,7 +204,7 @@ fn process_diagnostics( let path = canonical(path); - let mut diags = compile_diagnostics + let diags = compile_diagnostics .iter() .filter(|d| { canonical( @@ -123,44 +220,14 @@ fn process_diagnostics( .filter_map(|(i, c)| if c == b'\n' { Some(i) } else { None }) .collect::>(); - let diag_copy = diags.clone(); - let mut captures = Vec::new(); + let mut expected = extract_expected_diags(source); + let captures: Vec<_> = + expected.iter().map(|expected| &expected.comment_range).cloned().collect(); // Find expected errors in the file. The first caret (^) points to the expected column. The number of // carets refers to the number of lines to go back. This is useful when one line of code produces multiple // errors or warnings. - let re = regex::Regex::new(r"\n *//[^\n\^]*(\^+)(error|warning)\{([^\n]*)\}").unwrap(); - for m in re.captures_iter(source) { - let line_begin_offset = m.get(0).unwrap().start(); - let column = m.get(1).unwrap().start() - line_begin_offset; - let lines_to_source = m.get(1).unwrap().as_str().len(); - let warning_or_error = m.get(2).unwrap().as_str(); - let expected_message = - m.get(3).unwrap().as_str().replace('↵', "\n").replace('📂', env!("CARGO_MANIFEST_DIR")); - if update { - captures.push(m.get(0).unwrap().range()); - } - - let mut line_counter = 0; - let mut line_offset = source[..line_begin_offset].rfind('\n').unwrap_or(0); - let offset = loop { - line_counter += 1; - if line_counter >= lines_to_source { - break line_offset + column; - } - if let Some(o) = source[..line_offset].rfind('\n') { - line_offset = o; - } else { - break 1; - }; - }; - - let expected_diag_level = match warning_or_error { - "warning" => DiagnosticLevel::Warning, - "error" => DiagnosticLevel::Error, - _ => panic!("Unsupported diagnostic level {warning_or_error}"), - }; - + for diag in &diags { fn compare_message(message: &str, expected_message: &str) -> bool { if message == expected_message { return true; @@ -173,41 +240,78 @@ fn process_diagnostics( false } - match diags.iter().position(|e| { - let (l, c) = e.line_column(); - let o = lines.get(l.wrapping_sub(2)).unwrap_or(&0) + c; - o == offset - && compare_message(e.message(), &expected_message) - && e.level() == expected_diag_level - }) { - Some(idx) => { - diags.remove(idx); + let (l, c) = diag.line_column(); + let diag_start = lines.get(l.wrapping_sub(2)).unwrap_or(&0) + c; + let (l, c) = diag.end_line_column(); + let diag_end = lines.get(l.wrapping_sub(2)).unwrap_or(&0) + c - 1; + + let expected_start = expected.iter().position(|expected| { + Some(diag_start) == expected.start + && compare_message(diag.message(), &expected.message) + && diag.level() == expected.level + && (expected.end.is_none() || Some(diag_end) == expected.end) + }); + let expected_end = expected.iter().position(|expected| { + Some(diag_end) == expected.end + && compare_message(diag.message(), &expected.message) + && diag.level() == expected.level + && (expected.start.is_none() || Some(diag_start) == expected.start) + }); + + let found_match = match (expected_start, expected_end) { + (Some(start), Some(end)) => { + // Found both start and end, success! + // Make sure to remove the larger index first, so the + // smaller index remains valid. + expected.remove(start.max(end)); + if start != end { + expected.remove(start.min(end)); + } + true } - None => { - success = false; - println!("{path:?}: {warning_or_error} not found at offset {offset}: {expected_message:?}"); + (Some(start), None) => { + println!("{path:?}: Could not find end of error/warning: {diag:#?}"); + expected.remove(start); + false } - } - } + (None, Some(end)) => { + println!("{path:?}: Could not find start of error/warning: {diag:#?}"); + expected.remove(end); + false + } + // TODO: Remove start/end if only one was found + (None, None) => { + println!("{path:?}: Unexpected error/warning: {diag:#?}, {diag_start}, {diag_end}",); + false + } + }; - if !diags.is_empty() { - println!("{path:?}: Unexpected errors/warnings: {diags:#?}"); + if !found_match { + success = false; - #[cfg(feature = "display-diagnostics")] - if !_silent { - let mut to_report = BuildDiagnostics::default(); - for d in diags { - to_report.push_compiler_error(d.clone()); + #[cfg(feature = "display-diagnostics")] + if !_silent { + let mut to_report = BuildDiagnostics::default(); + to_report.push_compiler_error((*diag).clone()); + to_report.print(); } - to_report.print(); } + } + for expected in expected { success = false; + println!( + "{path:?}: {level:?} not found at offset {start:?}-{end:?}: {message:?}", + level = expected.level, + start = expected.start, + end = expected.end, + message = expected.message + ); } if !success && update { let mut source = source.to_string(); - self::update(diag_copy, &mut source, lines, &captures); + self::update(&diags, &mut source, lines, &captures); std::fs::write(path, source).unwrap(); } @@ -216,7 +320,7 @@ fn process_diagnostics( /// Rewrite the source to remove the old comments and add accurate error comments fn update( - mut diags: Vec<&Diagnostic>, + diags: &[&Diagnostic], source: &mut String, mut lines: Vec, to_remove: &[std::ops::Range], @@ -230,42 +334,57 @@ fn update( } } - diags.sort_by_key(|d| { - let (l, c) = d.line_column(); - (usize::MAX - l, c) - }); - - let mut last_line = 0; - let mut last_line_adjust = 0; + let mut last_line_adjust = Vec::from_iter(std::iter::repeat_n(0, lines.len())); for d in diags { - let (l, c) = d.line_column(); - if c < 3 { - panic!("Error message cannot be on the column < 3: {d:?}") - } + let mut insert_range_at = |range: &str, l, c: usize| { + let column_adjust = if c < 3 { "<".repeat(3 - c) } else { "".to_string() }; + let byte_offset = lines[l - 1] + 1; + let to_insert = format!( + "//{indent}{range}{adjust}{column_adjust}{error_or_warning}{{{message}}}\n", + indent = " ".repeat(c.max(3) - 3), + adjust = "^".repeat(last_line_adjust[l - 1]), + error_or_warning = + if d.level() == DiagnosticLevel::Error { "error" } else { "warning" }, + message = d.message().replace('\n', "↵").replace(env!("CARGO_MANIFEST_DIR"), "📂") + ); + if byte_offset > source.len() { + source.push('\n'); + } + source.insert_str(byte_offset, &to_insert); + for line in (l - 1)..lines.len() { + lines[line] += to_insert.len(); + } + last_line_adjust[l - 1] += 1; + }; + + let (line_start, column_start) = d.line_column(); + let (line_end, column_end) = d.end_line_column(); - if last_line == l { - last_line_adjust += 1; + // The end column is exclusive, therefore use - 1 here + let range = if d.length() <= 1 { + // Single-character diagnostic, use "^" for the marker + "^".to_owned() } else { - last_line = l; - last_line_adjust = 0; - } + let end = if line_start == line_end { + // Same line, we can insert the closing "<" + " ".repeat(column_end - column_start - 2) + "<" + } else { + // End is on a different line, we'll emit it later + "".to_owned() + }; + format!(">{end}") + }; - let byte_offset = lines[l - 1] + 1; + insert_range_at(&range, line_start, column_start); - let to_insert = format!( - "//{indent}^{adjust}{error_or_warning}{{{message}}}\n", - indent = " ".repeat(c - 3), - adjust = "^".repeat(last_line_adjust), - error_or_warning = - if d.level() == DiagnosticLevel::Error { "error" } else { "warning" }, - message = d.message().replace('\n', "↵").replace(env!("CARGO_MANIFEST_DIR"), "📂") - ); - if byte_offset > source.len() { - source.push('\n'); + // Insert the closing `<` at another line if necessary + // Edge-case: If a single-character diagnostic is on a newline character (\n), its + // end_line_column is technically on a new line, but the single ^ marker is enough, so no + // closing character is needed. + if line_start != line_end && d.length() > 1 { + insert_range_at("<", line_end, column_end - 1); } - source.insert_str(byte_offset, &to_insert); - lines[l - 1] += to_insert.len(); } } @@ -371,7 +490,33 @@ export component Foo inherits Window foo { width: 10px; } assert!(process( r#" export component Foo inherits Window foo { width: 10px; } -// ^error{Syntax error: expected '{'} +// > <^error{Syntax error: expected '{'} + "# + )?); + + // also when it's shifted left by additional < + assert!(process( + r#" +export component Foo inherits Window foo { width: 10px; } +// > <<<error{Syntax error: expected '{'} +// <^error{Syntax error: expected '{'} "# )?); @@ -379,7 +524,7 @@ export component Foo inherits Window foo { width: 10px; } assert!(!process( r#" export component Foo inherits Window foo { width: 10px; } -// ^error{Syntax error: expected '{'} +// > <^^error{Syntax error: expected '{'} "# )?); // Even on windows, it should work assert!(process( - "\r\nexport component Foo inherits Window foo { width: 10px; }\r\n// ^error{Syntax error: expected '{'}\r\n" + "\r\n\ +export component Foo inherits Window foo { width: 10px; }\r\n\ +// > xx.foo; diff --git a/internal/compiler/tests/typeloader/incpath/should_fail.slint b/internal/compiler/tests/typeloader/incpath/should_fail.slint index 7d7a8c22d8e..1bdb78843f4 100644 --- a/internal/compiler/tests/typeloader/incpath/should_fail.slint +++ b/internal/compiler/tests/typeloader/incpath/should_fail.slint @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export X := SomeRect { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} -// ^^error{Unknown element 'SomeRect'} +// > <^error{Unknown element 'SomeRect'} foo: 42; } diff --git a/internal/compiler/tests/typeloader/incpath/should_fail2.slint b/internal/compiler/tests/typeloader/incpath/should_fail2.slint index bcd010479e4..7f028e6f5b5 100644 --- a/internal/compiler/tests/typeloader/incpath/should_fail2.slint +++ b/internal/compiler/tests/typeloader/incpath/should_fail2.slint @@ -2,9 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export X := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > hello: max; -// ^error{Builtin function must be called. Did you forgot the '()'?} +// > a1: a2; property a2: a1; } export Z := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > b1: b2; -// ^error{The binding for the property 'b1' is part of a binding loop (b2 -> b1)} +// > b1)} property b2: b1; -// ^error{The binding for the property 'b2' is part of a binding loop (b2 -> b1)} +// > b1)} } diff --git a/internal/compiler/tests/typeloader/recursive_import1.slint b/internal/compiler/tests/typeloader/recursive_import1.slint index a370481024f..f3e075fa77f 100644 --- a/internal/compiler/tests/typeloader/recursive_import1.slint +++ b/internal/compiler/tests/typeloader/recursive_import1.slint @@ -4,11 +4,11 @@ import { Rec2 } from "./recursive_import2.slint"; export Rec1 := Rectangle { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > Hello: 42; } export Rect12 := Rec2 { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > World: 43; } diff --git a/internal/compiler/tests/typeloader/recursive_import2.slint b/internal/compiler/tests/typeloader/recursive_import2.slint index db5c70e0b19..7f573aeb771 100644 --- a/internal/compiler/tests/typeloader/recursive_import2.slint +++ b/internal/compiler/tests/typeloader/recursive_import2.slint @@ -2,14 +2,14 @@ // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 import { Rec1 } from "./recursive_import1.slint"; -// ^error{Recursive import of "📂/tests/typeloader/recursive_import1.slint"} +// > Foo: 44; } export Rect21 := Rec1 { -// ^warning{':=' to declare a component is deprecated. The new syntax declare components with 'component MyComponent {'. Read the documentation for more info} +// > Bar: 45; } diff --git a/tools/lsp/util.rs b/tools/lsp/util.rs index a8d45473ed3..d00ccab556c 100644 --- a/tools/lsp/util.rs +++ b/tools/lsp/util.rs @@ -371,7 +371,7 @@ fn lookup_expression_context(mut n: SyntaxNode) -> Option pub fn to_lsp_diag(d: &i_slint_compiler::diagnostics::Diagnostic) -> lsp_types::Diagnostic { lsp_types::Diagnostic::new( - to_range(d.line_column()), + to_range(d.line_column(), d.end_line_column()), Some(to_lsp_diag_level(d.level())), None, None, @@ -381,12 +381,16 @@ pub fn to_lsp_diag(d: &i_slint_compiler::diagnostics::Diagnostic) -> lsp_types:: ) } -fn to_range(span: (usize, usize)) -> lsp_types::Range { - let pos = lsp_types::Position::new( - (span.0 as u32).saturating_sub(1), - (span.1 as u32).saturating_sub(1), +fn to_range(start: (usize, usize), end: (usize, usize)) -> lsp_types::Range { + let start = lsp_types::Position::new( + (start.0 as u32).saturating_sub(1), + (start.1 as u32).saturating_sub(1), ); - lsp_types::Range::new(pos, pos) + let end = lsp_types::Position::new( + (end.0 as u32).saturating_sub(1), + (end.1 as u32).saturating_sub(1), + ); + lsp_types::Range::new(start, end) } fn to_lsp_diag_level(level: DiagnosticLevel) -> lsp_types::DiagnosticSeverity {