mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Implement component name completion in html! for IntelliJ Rust plugin (#2972)
This commit is contained in:
parent
7558cd2637
commit
c7b7e45e4c
@ -6,6 +6,7 @@ use syn::spanned::Spanned;
|
||||
use syn::{Token, Type};
|
||||
|
||||
use super::{HtmlChildrenTree, TagTokens};
|
||||
use crate::is_ide_completion;
|
||||
use crate::props::ComponentProps;
|
||||
|
||||
pub struct HtmlComponent {
|
||||
@ -25,13 +26,16 @@ impl Parse for HtmlComponent {
|
||||
};
|
||||
|
||||
if trying_to_close() {
|
||||
return match input.parse::<HtmlComponentClose>() {
|
||||
Ok(close) => Err(syn::Error::new_spanned(
|
||||
close.to_spanned(),
|
||||
"this closing tag has no corresponding opening tag",
|
||||
)),
|
||||
Err(err) => Err(err),
|
||||
};
|
||||
let close = input.parse::<HtmlComponentClose>();
|
||||
if !is_ide_completion() {
|
||||
return match close {
|
||||
Ok(close) => Err(syn::Error::new_spanned(
|
||||
close.to_spanned(),
|
||||
"this closing tag has no corresponding opening tag",
|
||||
)),
|
||||
Err(err) => Err(err),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let open = input.parse::<HtmlComponentOpen>()?;
|
||||
@ -48,6 +52,9 @@ impl Parse for HtmlComponent {
|
||||
let mut children = HtmlChildrenTree::new();
|
||||
let close = loop {
|
||||
if input.is_empty() {
|
||||
if is_ide_completion() {
|
||||
break None;
|
||||
}
|
||||
return Err(syn::Error::new_spanned(
|
||||
open.to_spanned(),
|
||||
"this opening tag has no corresponding closing tag",
|
||||
@ -62,7 +69,7 @@ impl Parse for HtmlComponent {
|
||||
}
|
||||
|
||||
let fork = input.fork();
|
||||
break TagTokens::parse_end_content(&fork, |i_fork, tag| {
|
||||
let close = TagTokens::parse_end_content(&fork, |i_fork, tag| {
|
||||
let ty = i_fork.parse().map_err(|e| {
|
||||
syn::Error::new(
|
||||
e.span(),
|
||||
@ -76,7 +83,7 @@ impl Parse for HtmlComponent {
|
||||
)
|
||||
})?;
|
||||
|
||||
if ty != open.ty {
|
||||
if ty != open.ty && !is_ide_completion() {
|
||||
let open_ty = &open.ty;
|
||||
Err(syn::Error::new_spanned(
|
||||
quote!(#open_ty #ty),
|
||||
@ -92,6 +99,7 @@ impl Parse for HtmlComponent {
|
||||
Ok(close)
|
||||
}
|
||||
})?;
|
||||
break Some(close);
|
||||
}
|
||||
children.parse_child(input)?;
|
||||
};
|
||||
@ -109,7 +117,7 @@ impl Parse for HtmlComponent {
|
||||
ty: open.ty,
|
||||
props: open.props,
|
||||
children,
|
||||
close: Some(close),
|
||||
close,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ use syn::{Block, Expr, Ident, Lit, LitStr, Token};
|
||||
use super::{HtmlChildrenTree, HtmlDashedName, TagTokens};
|
||||
use crate::props::{ClassesForm, ElementProps, Prop, PropDirective};
|
||||
use crate::stringify::{Stringify, Value};
|
||||
use crate::{non_capitalized_ascii, Peek, PeekValue};
|
||||
use crate::{is_ide_completion, non_capitalized_ascii, Peek, PeekValue};
|
||||
|
||||
pub struct HtmlElement {
|
||||
pub name: TagName,
|
||||
@ -72,6 +72,9 @@ impl Parse for HtmlElement {
|
||||
let mut children = HtmlChildrenTree::new();
|
||||
loop {
|
||||
if input.is_empty() {
|
||||
if is_ide_completion() {
|
||||
break;
|
||||
}
|
||||
return Err(syn::Error::new_spanned(
|
||||
open.to_spanned(),
|
||||
"this opening tag has no corresponding closing tag",
|
||||
@ -86,7 +89,9 @@ impl Parse for HtmlElement {
|
||||
children.parse_child(input)?;
|
||||
}
|
||||
|
||||
input.parse::<HtmlElementClose>()?;
|
||||
if !input.is_empty() || !is_ide_completion() {
|
||||
input.parse::<HtmlElementClose>()?;
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
name: open.name,
|
||||
|
||||
@ -6,7 +6,7 @@ use syn::parse::{Parse, ParseStream};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{braced, token, Token};
|
||||
|
||||
use crate::PeekValue;
|
||||
use crate::{is_ide_completion, PeekValue};
|
||||
|
||||
mod html_block;
|
||||
mod html_component;
|
||||
@ -101,6 +101,7 @@ impl HtmlTree {
|
||||
Some(HtmlType::List)
|
||||
} else if ident_str.chars().next().unwrap().is_ascii_uppercase()
|
||||
|| input.peek(Token![::])
|
||||
|| is_ide_completion() && ident_str.chars().any(|c| c.is_ascii_uppercase())
|
||||
{
|
||||
Some(HtmlType::Component)
|
||||
} else {
|
||||
|
||||
@ -98,6 +98,13 @@ fn join_errors(mut it: impl Iterator<Item = syn::Error>) -> syn::Result<()> {
|
||||
})
|
||||
}
|
||||
|
||||
fn is_ide_completion() -> bool {
|
||||
match std::env::var_os("RUST_IDE_PROC_MACRO_COMPLETION_DUMMY_IDENTIFIER") {
|
||||
None => false,
|
||||
Some(dummy_identifier) => !dummy_identifier.is_empty(),
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Properties, attributes(prop_or, prop_or_else, prop_or_default))]
|
||||
pub fn derive_props(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DerivePropsInput);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user