mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11:16 +00:00
Put what is the FileDiagnostics into the SourceFile so the SourceFile has the content
This commit is contained in:
parent
7c48bcdd4c
commit
968dfaae87
8 changed files with 70 additions and 70 deletions
|
@ -328,8 +328,7 @@ pub fn sixtyfps(stream: TokenStream) -> TokenStream {
|
|||
let source_file = if let Some(cargo_manifest) = std::env::var_os("CARGO_MANIFEST_DIR") {
|
||||
let mut path: std::path::PathBuf = cargo_manifest.into();
|
||||
path.push("Cargo.toml");
|
||||
diag.current_path = std::rc::Rc::new(path);
|
||||
Some(diag.current_path.clone())
|
||||
Some(diagnostics::SourceFileInner::from_path(path))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -371,7 +370,7 @@ fn report_diagnostics(
|
|||
let mut result = TokenStream::new();
|
||||
let mut needs_error = diag.has_error();
|
||||
for mut file_diag in diag.into_iter() {
|
||||
if file_diag.source.is_none() {
|
||||
if file_diag.current_path.path() == std::path::PathBuf::default() {
|
||||
file_diag.map_offsets_to_span(span_map);
|
||||
needs_error &= !file_diag.has_error();
|
||||
result.extend(TokenStream::from(file_diag.into_token_stream()))
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
Please contact info@sixtyfps.io for more information.
|
||||
LICENSE END */
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -65,7 +65,32 @@ pub trait Spanned {
|
|||
}
|
||||
}
|
||||
|
||||
pub type SourceFile = Rc<PathBuf>;
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SourceFileInner {
|
||||
path: PathBuf,
|
||||
|
||||
/// Complete source code of the path, used to map from offset to line number
|
||||
source: Option<String>,
|
||||
|
||||
/// The offset of each linebreak
|
||||
line_offsets: once_cell::unsync::OnceCell<Vec<usize>>,
|
||||
}
|
||||
|
||||
impl SourceFileInner {
|
||||
pub fn new(path: PathBuf, source: String) -> Self {
|
||||
Self { path, source: Some(source), line_offsets: Default::default() }
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Path {
|
||||
&self.path
|
||||
}
|
||||
|
||||
pub fn from_path(path: PathBuf) -> Rc<Self> {
|
||||
Rc::new(Self { path, ..Default::default() })
|
||||
}
|
||||
}
|
||||
|
||||
pub type SourceFile = Rc<SourceFileInner>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SourceLocation {
|
||||
|
@ -179,11 +204,6 @@ pub struct FileDiagnostics {
|
|||
pub inner: Vec<Diagnostic>,
|
||||
/// file path
|
||||
pub current_path: SourceFile,
|
||||
/// Complete source code of the path, used to map from offset to line number
|
||||
pub source: Option<String>,
|
||||
|
||||
/// The offset of each linebreak
|
||||
pub line_offsets: once_cell::unsync::OnceCell<Vec<usize>>,
|
||||
}
|
||||
|
||||
impl IntoIterator for FileDiagnostics {
|
||||
|
@ -251,10 +271,10 @@ impl FileDiagnostics {
|
|||
}
|
||||
|
||||
let mut codemap = codemap::CodeMap::new();
|
||||
let internal_errors = self.source.is_none();
|
||||
let internal_errors = self.current_path.source.is_none();
|
||||
let file = codemap.add_file(
|
||||
self.current_path.to_string_lossy().to_string(),
|
||||
self.source.unwrap_or_default(),
|
||||
self.current_path.path.to_string_lossy().to_string(),
|
||||
self.current_path.source.clone().unwrap_or_default(),
|
||||
);
|
||||
let file_span = file.span;
|
||||
|
||||
|
@ -342,17 +362,13 @@ impl FileDiagnostics {
|
|||
}
|
||||
|
||||
pub fn new_from_error(path: std::path::PathBuf, err: std::io::Error) -> Self {
|
||||
Self {
|
||||
inner: vec![err.into()],
|
||||
current_path: Rc::new(path),
|
||||
source: None,
|
||||
line_offsets: Default::default(),
|
||||
}
|
||||
Self { inner: vec![err.into()], current_path: SourceFileInner::from_path(path) }
|
||||
}
|
||||
|
||||
fn line_offsets(&self) -> &[usize] {
|
||||
self.line_offsets.get_or_init(|| {
|
||||
self.source
|
||||
self.current_path.line_offsets.get_or_init(|| {
|
||||
self.current_path
|
||||
.source
|
||||
.as_ref()
|
||||
.map(|s| {
|
||||
s.bytes()
|
||||
|
@ -403,34 +419,33 @@ impl quote::ToTokens for FileDiagnostics {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct BuildDiagnostics {
|
||||
per_input_file_diagnostics: HashMap<SourceFile, FileDiagnostics>,
|
||||
per_input_file_diagnostics: HashMap<PathBuf, FileDiagnostics>,
|
||||
internal_errors: Option<FileDiagnostics>,
|
||||
}
|
||||
|
||||
impl BuildDiagnostics {
|
||||
pub fn add(&mut self, diagnostics: FileDiagnostics) {
|
||||
match self.per_input_file_diagnostics.get_mut(&diagnostics.current_path) {
|
||||
match self.per_input_file_diagnostics.get_mut(&diagnostics.current_path.path) {
|
||||
Some(existing_diags) => existing_diags.inner.extend(diagnostics.inner),
|
||||
None => {
|
||||
self.per_input_file_diagnostics
|
||||
.insert(diagnostics.current_path.clone(), diagnostics);
|
||||
.insert(diagnostics.current_path.path.clone(), diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn file_diagnostics(&mut self, source_file: &Rc<PathBuf>) -> &mut FileDiagnostics {
|
||||
self.per_input_file_diagnostics.entry(source_file.clone()).or_insert_with(|| {
|
||||
FileDiagnostics { current_path: source_file.clone(), ..Default::default() }
|
||||
fn file_diagnostics(&mut self, path: &Path) -> &mut FileDiagnostics {
|
||||
self.per_input_file_diagnostics.entry(path.into()).or_insert_with(|| FileDiagnostics {
|
||||
current_path: Rc::new(SourceFileInner { path: path.into(), ..Default::default() }),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn push_diagnostic(&mut self, message: String, source: &dyn Spanned, level: Level) {
|
||||
match source.source_file() {
|
||||
Some(source_file) => self.file_diagnostics(source_file).push_diagnostic_with_span(
|
||||
message,
|
||||
source.span(),
|
||||
level,
|
||||
),
|
||||
Some(source_file) => self
|
||||
.file_diagnostics(source_file.path())
|
||||
.push_diagnostic_with_span(message, source.span(), level),
|
||||
None => self.push_internal_error(
|
||||
CompilerDiagnostic { message, span: source.span(), level }.into(),
|
||||
),
|
||||
|
@ -444,7 +459,10 @@ impl BuildDiagnostics {
|
|||
pub fn push_internal_error(&mut self, err: Diagnostic) {
|
||||
self.internal_errors
|
||||
.get_or_insert_with(|| FileDiagnostics {
|
||||
current_path: Rc::new("[internal error]".into()),
|
||||
current_path: Rc::new(SourceFileInner {
|
||||
path: "[internal error]".into(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
})
|
||||
.inner
|
||||
|
@ -458,7 +476,7 @@ impl BuildDiagnostics {
|
|||
source: &impl Spanned,
|
||||
) {
|
||||
self.file_diagnostics(
|
||||
source.source_file().expect("deprecations cannot be created as internal errors"),
|
||||
source.source_file().expect("deprecations cannot be created as internal errors").path(),
|
||||
)
|
||||
.push_property_deprecation_warning(old_property, new_property, source);
|
||||
}
|
||||
|
@ -488,7 +506,7 @@ impl BuildDiagnostics {
|
|||
.flat_map(|diag| {
|
||||
diag.to_string_vec()
|
||||
.iter()
|
||||
.map(|err| format!("{}: {}", diag.current_path.to_string_lossy(), err))
|
||||
.map(|err| format!("{}: {}", diag.current_path.path().to_string_lossy(), err))
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect()
|
||||
|
|
|
@ -297,7 +297,7 @@ impl Spanned for Element {
|
|||
self.node.as_ref().map(|n| n.span()).unwrap_or_default()
|
||||
}
|
||||
|
||||
fn source_file(&self) -> Option<&Rc<std::path::PathBuf>> {
|
||||
fn source_file(&self) -> Option<&crate::diagnostics::SourceFile> {
|
||||
self.node.as_ref().map(|n| n.0.source_file.as_ref()).flatten()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -521,10 +521,8 @@ impl From<Vec<Token>> for DefaultParser {
|
|||
|
||||
impl DefaultParser {
|
||||
/// Constructor that create a parser from the source code
|
||||
pub fn new(source: String) -> Self {
|
||||
let mut parser = Self::from(crate::lexer::lex(&source));
|
||||
parser.diags.source = Some(source);
|
||||
parser
|
||||
pub fn new(source: &str) -> Self {
|
||||
Self::from(crate::lexer::lex(&source))
|
||||
}
|
||||
|
||||
fn current_token(&self) -> Token {
|
||||
|
@ -811,10 +809,11 @@ pub fn parse(
|
|||
source: String,
|
||||
path: Option<&std::path::Path>,
|
||||
) -> (SyntaxNodeWithSourceFile, FileDiagnostics) {
|
||||
let mut p = DefaultParser::new(source);
|
||||
let mut p = DefaultParser::new(&source);
|
||||
document::parse_document(&mut p);
|
||||
let source_file = if let Some(path) = path {
|
||||
p.diags.current_path = std::rc::Rc::new(path.to_path_buf());
|
||||
p.diags.current_path =
|
||||
std::rc::Rc::new(crate::diagnostics::SourceFileInner::new(path.to_path_buf(), source));
|
||||
Some(p.diags.current_path.clone())
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -411,10 +411,7 @@ impl Expression {
|
|||
ctx.type_loader
|
||||
.and_then(|loader| {
|
||||
loader
|
||||
.import_file(
|
||||
node.source_file.as_ref().map(|path_rc| path_rc.as_path()),
|
||||
&s,
|
||||
)
|
||||
.import_file(node.source_file.as_ref().map(|sf| sf.path()), &s)
|
||||
.map(|resolved_file| resolved_file.path)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
|
|
|
@ -158,10 +158,10 @@ fn process_file_source(
|
|||
let mut success = true;
|
||||
|
||||
for diagnostics in compile_diagnostics.into_iter() {
|
||||
let source = if *diagnostics.current_path == path {
|
||||
let source = if diagnostics.current_path.path() == path {
|
||||
source.clone()
|
||||
} else {
|
||||
std::fs::read_to_string(diagnostics.current_path.as_ref())?
|
||||
std::fs::read_to_string(diagnostics.current_path.path())?
|
||||
};
|
||||
success &= process_diagnostics(diagnostics, source, silent)?;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use std::io::Read;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::diagnostics::{BuildDiagnostics, CompilerDiagnostic, FileDiagnostics, SourceFile};
|
||||
use crate::diagnostics::{BuildDiagnostics, CompilerDiagnostic, FileDiagnostics};
|
||||
use crate::object_tree::{self, Document};
|
||||
use crate::parser::{syntax_nodes, SyntaxKind, SyntaxTokenWithSourceFile};
|
||||
use crate::typeregister::TypeRegister;
|
||||
|
@ -234,13 +234,7 @@ impl<'a> TypeLoader<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
self.load_file(
|
||||
&path_canon,
|
||||
SourceFile::new(path.to_owned()),
|
||||
source_code,
|
||||
build_diagnostics,
|
||||
)
|
||||
.await;
|
||||
self.load_file(&path_canon, path, source_code, build_diagnostics).await;
|
||||
let _ok = self.all_documents.currently_loading.remove(path_canon.as_path());
|
||||
assert!(_ok);
|
||||
Some(path_canon)
|
||||
|
@ -252,15 +246,13 @@ impl<'a> TypeLoader<'a> {
|
|||
pub async fn load_file(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
source_path: SourceFile,
|
||||
source_path: &Path,
|
||||
source_code: String,
|
||||
build_diagnostics: &mut BuildDiagnostics,
|
||||
) {
|
||||
let (dependency_doc, mut dependency_diagnostics) =
|
||||
crate::parser::parse(source_code, Some(&source_path));
|
||||
|
||||
dependency_diagnostics.current_path = source_path;
|
||||
|
||||
if dependency_diagnostics.has_error() {
|
||||
build_diagnostics.add(dependency_diagnostics);
|
||||
let mut d = Document::default();
|
||||
|
@ -401,7 +393,7 @@ impl<'a> TypeLoader<'a> {
|
|||
doc: &syntax_nodes::Document,
|
||||
doc_diagnostics: &mut FileDiagnostics,
|
||||
) -> impl Iterator<Item = ImportedTypes> {
|
||||
let referencing_file = doc.source_file.as_ref().unwrap().clone();
|
||||
let referencing_file = doc.source_file.as_ref().unwrap().path().clone();
|
||||
|
||||
let mut dependencies = DependenciesByFile::new();
|
||||
|
||||
|
|
|
@ -194,22 +194,17 @@ fn reload_document(
|
|||
let path = Path::new(uri.path());
|
||||
let path_canon = path.canonicalize().unwrap_or_else(|_| path.to_owned());
|
||||
let mut diag = BuildDiagnostics::default();
|
||||
spin_on::spin_on(document_cache.documents.load_file(
|
||||
&path_canon,
|
||||
sixtyfps_compilerlib::diagnostics::SourceFile::new(path.to_owned()),
|
||||
content,
|
||||
&mut diag,
|
||||
));
|
||||
spin_on::spin_on(document_cache.documents.load_file(&path_canon, path, content, &mut diag));
|
||||
|
||||
for file_diag in diag.into_iter() {
|
||||
if file_diag.current_path.is_relative() {
|
||||
if file_diag.current_path.path().is_relative() {
|
||||
continue;
|
||||
}
|
||||
let diagnostics = file_diag.inner.iter().map(|d| to_lsp_diag(d, &file_diag)).collect();
|
||||
connection.sender.send(Message::Notification(lsp_server::Notification::new(
|
||||
"textDocument/publishDiagnostics".into(),
|
||||
PublishDiagnosticsParams {
|
||||
uri: Url::from_file_path(file_diag.current_path.as_path()).unwrap(),
|
||||
uri: Url::from_file_path(file_diag.current_path.path()).unwrap(),
|
||||
diagnostics,
|
||||
version: None,
|
||||
},
|
||||
|
@ -272,7 +267,7 @@ fn goto_definition(
|
|||
sixtyfps_compilerlib::object_tree::QualifiedTypeName::from_node(token.into());
|
||||
match parent.kind() {
|
||||
SyntaxKind::Element => {
|
||||
let doc = document_cache.documents.get_document(source_file.as_path())?;
|
||||
let doc = document_cache.documents.get_document(source_file.path())?;
|
||||
match doc.local_registry.lookup_qualified(&qual.members) {
|
||||
sixtyfps_compilerlib::langtype::Type::Component(c) => {
|
||||
goto_node(document_cache, &c.root_element.borrow().node.as_ref()?.0)
|
||||
|
@ -291,7 +286,7 @@ fn goto_node(
|
|||
document_cache: &mut DocumentCache,
|
||||
node: &SyntaxNodeWithSourceFile,
|
||||
) -> Option<GotoDefinitionResponse> {
|
||||
let path = node.source_file.as_ref()?.as_path();
|
||||
let path = node.source_file.as_ref()?.path();
|
||||
let target_uri = Url::from_file_path(path).ok()?;
|
||||
let newline_offsets = match document_cache.newline_offsets.entry(target_uri.clone()) {
|
||||
std::collections::hash_map::Entry::Occupied(e) => e.into_mut(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue