#![feature(const_fn)]
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]
#![feature(specialization)]
#![feature(try_blocks)]
#![allow(dead_code)]
use crate::lexer::token::LexToken;
use crate::macros::EntityMacroDefinition;
use crate::syntax::entity::ParsedEntity;
use lark_collections::{FxIndexMap, Seq};
use lark_debug_derive::DebugWith;
use lark_entity::Entity;
use lark_entity::EntityData;
use lark_entity::EntityTables;
use lark_entity::MemberKind;
use lark_error::Diagnostic;
use lark_error::ErrorReported;
use lark_error::WithError;
use lark_hir as hir;
use lark_intern::Intern;
use lark_span::ByteIndex;
use lark_span::FileName;
use lark_span::IntoFileName;
use lark_span::Location;
use lark_span::Span;
use lark_span::Spanned;
use lark_string::GlobalIdentifier;
use lark_string::GlobalIdentifierTables;
use lark_string::Text;
use lark_ty as ty;
use lark_ty::declaration::Declaration;
use lark_ty::declaration::DeclarationTables;
use std::sync::Arc;
pub mod current_file;
mod ir;
mod lexer;
pub mod macros;
mod parser;
mod query_definitions;
mod scope;
pub mod syntax;
mod type_conversion;
pub use self::ir::ParsedFile;
salsa::query_group! {
pub trait ParserDatabase: AsRef<GlobalIdentifierTables>
+ AsRef<EntityTables>
+ AsRef<DeclarationTables>
+ salsa::Database
{
fn file_names() -> Seq<FileName> {
type FileNamesQuery;
storage input;
}
fn file_text(id: FileName) -> Text {
type FileTextQuery;
storage input;
}
fn entity_span(entity: Entity) -> Span<FileName> {
type EntitySpanQuery;
use fn query_definitions::entity_span;
}
fn characteristic_entity_span(entity: Entity) -> Span<FileName> {
type CharacteristicEntitySpanQuery;
use fn query_definitions::characteristic_entity_span;
}
fn line_offsets(id: FileName) -> Seq<usize> {
type LineOffsetsQuery;
use fn query_definitions::line_offsets;
}
fn location(id: FileName, index: ByteIndex) -> Location {
type LocationQuery;
use fn query_definitions::location;
}
fn byte_index(id: FileName, line: u64, column: u64) -> ByteIndex {
type ByteIndexQuery;
use fn query_definitions::byte_index;
}
fn file_tokens(id: FileName) -> WithError<Seq<Spanned<LexToken, FileName>>> {
type FileTokensQuery;
use fn query_definitions::file_tokens;
}
fn parsed_file(id: FileName) -> WithError<ParsedFile> {
type ParsedFileQuery;
use fn query_definitions::parsed_file;
}
fn child_parsed_entities(entity: Entity) -> WithError<Seq<ParsedEntity>> {
type ChildParsedEntitiesQuery;
use fn query_definitions::child_parsed_entities;
}
fn parsed_entity(entity: Entity) -> ParsedEntity {
type ParsedEntityQuery;
use fn query_definitions::parsed_entity;
}
fn child_entities(entity: Entity) -> Seq<Entity> {
type ChildEntitiesQuery;
use fn query_definitions::child_entities;
}
fn descendant_entities(entity: Entity) -> Seq<Entity> {
type DescendantEntitiesQuery;
use fn query_definitions::descendant_entities;
}
fn fn_body(key: Entity) -> WithError<Arc<hir::FnBody>> {
type FnBodyQuery;
use fn query_definitions::fn_body;
}
fn hover_targets(file: FileName, index: ByteIndex) -> Seq<HoverTarget> {
type HoverTargetsQuery;
use fn query_definitions::hover_targets;
}
fn members(key: Entity) -> Result<Seq<hir::Member>, ErrorReported> {
type MembersQuery;
use fn query_definitions::members;
}
fn member_entity(entity: Entity, kind: MemberKind, id: GlobalIdentifier) -> Option<Entity> {
type MemberEntityQuery;
use fn query_definitions::member_entity;
}
fn ty(key: Entity) -> WithError<ty::Ty<Declaration>> {
type TyQuery;
use fn type_conversion::ty;
}
fn signature(key: Entity) -> WithError<Result<ty::Signature<Declaration>, ErrorReported>> {
type SignatureQuery;
use fn type_conversion::signature;
}
fn generic_declarations(key: Entity) -> WithError<Result<Arc<ty::GenericDeclarations>, ErrorReported>> {
type GenericDeclarationsQuery;
use fn type_conversion::generic_declarations;
}
fn resolve_name(scope: Entity, name: GlobalIdentifier) -> Option<Entity> {
type ResolveNameQuery;
use fn scope::resolve_name;
}
}
}
#[derive(Clone, Debug, DebugWith, PartialEq, Eq)]
pub struct HoverTarget {
pub span: Span<FileName>,
pub kind: HoverTargetKind,
}
#[derive(Clone, Debug, DebugWith, PartialEq, Eq)]
pub enum HoverTargetKind {
Entity(Entity),
MetaIndex(Entity, hir::MetaIndex),
}
pub trait ParserDatabaseExt: ParserDatabase {
fn init_parser_db(&mut self) {
self.query_mut(FileNamesQuery).set((), Default::default());
}
fn add_file(&mut self, path: impl IntoFileName, contents: impl Into<Text>) {
let file_name = path.into_file_name(self);
let mut file_names = self.file_names();
file_names.extend(Some(file_name));
self.query_mut(FileNamesQuery).set((), file_names);
self.query_mut(FileTextQuery)
.set(file_name, contents.into());
}
fn top_level_entities_in_file(&self, file: impl IntoFileName) -> Seq<Entity> {
let file = file.into_file_name(self);
let file_entity = EntityData::InputFile { file }.intern(self);
self.child_entities(file_entity)
}
}
fn diagnostic(message: impl Into<String>, span: Span<FileName>) -> Diagnostic {
Diagnostic::new(message.into(), span)
}
fn macro_definitions(
db: &dyn AsRef<GlobalIdentifierTables>,
_entity: Entity,
) -> FxIndexMap<GlobalIdentifier, Arc<dyn EntityMacroDefinition>> {
macro_rules! declare_macro {
(
db($db:expr),
macros($($name:expr => $macro_definition:ty,)*),
) => {
{
let mut map: FxIndexMap<GlobalIdentifier, Arc<dyn EntityMacroDefinition>> = FxIndexMap::default();
$(
let name = $name.intern($db);
map.insert(name, std::sync::Arc::new(<$macro_definition>::default()));
)*
map
}
}
}
declare_macro!(
db(db),
macros(
"struct" => macros::struct_declaration::StructDeclaration,
"def" => macros::function_declaration::FunctionDeclaration,
),
)
}