Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions uvls/src/core/ast.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::core::*;
use check::ErrorInfo;
use hashbrown::HashMap;
use itertools::Itertools;
use ropey::Rope;
use semantic::FileID;
use std::hash::Hash;
Expand All @@ -10,11 +11,11 @@ use tower_lsp::lsp_types::Url;
use tree_sitter::Tree;
use ustr::Ustr;
use util::lsp_range;
pub mod collapse;
mod def;
pub mod graph;
mod transform;
mod visitor;
pub mod graph;
pub mod collapse;
pub use def::*;
pub use visitor::*;
//Easy to work with AST parsing and util.
Expand Down Expand Up @@ -177,6 +178,12 @@ impl Ast {
fn all_features(&self) -> impl Iterator<Item = Symbol> {
(0..self.features.len()).map(Symbol::Feature)
}
fn get_feature(&self, index: usize) -> Option<&Feature> {
self.features.get(index)
}
fn get_attribute(&self, index: usize) -> Option<&Attribute> {
self.attributes.get(index)
}
fn all_attributes(&self) -> impl Iterator<Item = Symbol> {
(0..self.attributes.len()).map(Symbol::Attribute)
}
Expand Down Expand Up @@ -243,6 +250,12 @@ impl AstDocument {
pub fn all_features(&self) -> impl Iterator<Item = Symbol> {
self.ast.all_features()
}
pub fn get_feature(&self, index: usize) -> Option<&Feature> {
self.ast.get_feature(index)
}
pub fn get_attribute(&self, index: usize) -> Option<&Attribute> {
self.ast.get_attribute(index)
}
pub fn all_attributes(&self) -> impl Iterator<Item = Symbol> {
self.ast.all_attributes()
}
Expand Down Expand Up @@ -394,6 +407,26 @@ impl AstDocument {
})
})
}
// returns all Symbols with same name, used for cardinality resolving
pub fn get_all_entities(&self, path: &[Ustr]) -> Vec<Symbol> {
let ustr_path = Ustr::from(path.iter().map(|s| s.to_string()).join(".").as_str());
let mut res = vec![];
for i in 0..self.ast.features.len() {
if ustr_path == self.get_feature(i).unwrap().name.name {
res.push(Symbol::Feature(i));
}
}
let mut path: Vec<Ustr> = path.iter().cloned().collect();
if let Some(name) = path.pop() {
let features = self.get_all_entities(&path);
for i in features {
if let Some(sym) = self.ast.index.get(&(i, name, SymbolKind::Attribute)) {
res.push(*sym);
}
}
}
res
}
//prefix of sym from root
pub fn prefix(&self, mut sym: Symbol) -> Vec<Ustr> {
if matches!(sym, Symbol::Import(..)) {
Expand Down
8 changes: 5 additions & 3 deletions uvls/src/core/ast/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub enum Type {
Bool,
Void,
Namespace,
Object,
}

#[derive(Clone, Debug)]
Expand All @@ -67,10 +68,8 @@ pub enum GroupMode {
}
#[derive(Clone, Debug)]
pub enum Cardinality {
From(usize),
Range(usize, usize),
Max(usize),
Any,
Fixed,
}
#[derive(Clone, Debug)]
pub enum LanguageLevelMajor {
Expand Down Expand Up @@ -112,6 +111,8 @@ pub struct Feature {
pub name: SymbolSpan,
pub cardinality: Option<Cardinality>,
pub ty: Type,
pub duplicate: bool,
pub first_cardinality_child: bool, // used to fix same name problem
}
#[derive(Clone, Debug)]
pub struct Import {
Expand All @@ -136,6 +137,7 @@ pub struct Attribute {
pub name: SymbolSpan,
pub value: ValueDecl,
pub depth: u32,
pub duplicate: bool,
}
#[derive(Clone, Debug)]
pub struct Keyword {
Expand Down
38 changes: 19 additions & 19 deletions uvls/src/core/ast/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ fn opt_int(node: Node, state: &mut VisitorGraph) -> Option<usize> {
None
}
}
// returns cardinality for Node
fn opt_cardinality(node: Node, state: &mut VisitorGraph) -> Option<Cardinality> {
let begin = node.child_by_field_name("begin");
let end = node.child_by_field_name("end");
Expand All @@ -297,9 +298,8 @@ fn opt_cardinality(node: Node, state: &mut VisitorGraph) -> Option<Cardinality>
opt_int(begin, state)?,
opt_int(end.unwrap(), state)?,
)),
(Some(begin), Some("*")) => Some(Cardinality::From(opt_int(begin, state)?)),
(None, Some("int")) => Some(Cardinality::Max(opt_int(end.unwrap(), state)?)),
(_, _) => Some(Cardinality::Any),
(None, Some("int")) => Some(Cardinality::Range(0, opt_int(end.unwrap(), state)?)),
(_, _) => Some(Cardinality::Range(0, 1)),
}
}

Expand Down Expand Up @@ -451,7 +451,7 @@ fn opt_equation(node: Node) -> Option<EquationOP> {
_ => None,
}
}
fn visit_constraint(graph: &mut VisitorGraph, _: GraphNode) {
fn visit_constraint(graph: &mut VisitorGraph, _: GraphNode,_ :&bool) {
graph.add_constraint(graph.node().byte_range());
}
fn opt_bool(graph: &mut VisitorGraph) -> bool {
Expand Down Expand Up @@ -500,34 +500,34 @@ fn opt_value(graph: &mut VisitorGraph) -> Value {
}
}

fn visit_attribute_value(graph: &mut VisitorGraph, _: GraphNode) {
fn visit_attribute_value(graph: &mut VisitorGraph, _: GraphNode, _:&bool) {
graph.goto_field("name");
let _ = opt_name(graph).unwrap();
}
fn visit_constraint_list(graph: &mut VisitorGraph, parent: GraphNode) {
fn visit_constraint_list(graph: &mut VisitorGraph, parent: GraphNode, _:&bool) {
loop {
if graph.kind() == "constraint" {
visit_children_arg(graph, parent.clone(), visit_constraint);
visit_children_arg(graph, parent.clone(), &false,visit_constraint);
}
if !graph.goto_next_sibling() {
break;
}
}
}
fn visit_attributes(graph: &mut VisitorGraph, parent: &GraphNode) {
fn visit_attributes(graph: &mut VisitorGraph, parent: &GraphNode,_:&bool) {
loop {
match graph.kind() {
"attribute_constraints" => {
visit_children_arg(graph, parent.clone(), visit_constraint_list);
visit_children_arg(graph, parent.clone(),&false, visit_constraint_list);
}
"attribute_constraint" => {
visit_children(graph, |state| {
debug_assert!(state.goto_kind("constraint"));
visit_children_arg(state, parent.clone(), visit_constraint);
visit_children_arg(state, parent.clone(), &false, visit_constraint);
});
}
"attribute_value" => {
visit_children_arg(graph, parent.clone(), visit_attribute_value);
visit_children_arg(graph, parent.clone(),&false, visit_attribute_value);
}
_ => {}
}
Expand Down Expand Up @@ -557,10 +557,10 @@ fn visit_feature(graph: &mut VisitorGraph, parent: &mut GraphNode, name: SymbolS
loop {
match graph.cursor().node().kind() {
"attributes" => {
visit_children_arg(graph, &feature, visit_attributes);
visit_children_arg(graph, &feature, &false,visit_attributes);
}
"blk" => {
visit_children_arg(graph, &mut feature, visit_blk_decl);
visit_children_arg(graph, &mut feature, &false,visit_blk_decl);
}
_ => {}
}
Expand All @@ -586,14 +586,14 @@ fn visit_group(graph: &mut VisitorGraph, mut parent: &mut GraphNode, mode: Group
parent.group_mode = Some(mode);
loop {
if graph.kind() == "blk" {
visit_children_arg(graph, &mut *parent, visit_blk_decl);
visit_children_arg(graph, &mut *parent, &false, visit_blk_decl);
}
if !graph.goto_next_sibling() {
break;
}
}
}
fn visit_blk_decl(graph: &mut VisitorGraph, parent: &mut GraphNode) {
fn visit_blk_decl(graph: &mut VisitorGraph, parent: &mut GraphNode,_:&bool) {
graph.goto_field("header");
match graph.kind() {
"name" => {
Expand Down Expand Up @@ -633,7 +633,7 @@ fn visit_blk_decl(graph: &mut VisitorGraph, parent: &mut GraphNode) {
visit_group(graph, parent, mode);
}
"cardinality" => {
let card = opt_cardinality(graph.node(), graph).unwrap_or(Cardinality::Any);
let card = opt_cardinality(graph.node(), graph).unwrap_or(Cardinality::Fixed);
visit_group(graph, parent, GroupMode::Cardinality(card));
}
_ => { }
Expand All @@ -643,7 +643,7 @@ fn visit_features(graph: &mut VisitorGraph) {
let mut root: GraphNode = GraphNode::root(graph.root_name.clone());
loop {
if graph.kind() == "blk" {
visit_children_arg(graph, &mut root, visit_blk_decl);
visit_children_arg(graph, &mut root,&false, visit_blk_decl);
}
if !graph.goto_next_sibling() {
break;
Expand All @@ -653,8 +653,8 @@ fn visit_features(graph: &mut VisitorGraph) {
fn visit_constraint_decl(graph: &mut VisitorGraph) {
loop {
match graph.kind() {
"constraint" | "ref" => visit_children_arg(graph, GraphNode::root(None), visit_constraint),
"name" => visit_constraint(graph, GraphNode::root(None)),
"constraint" | "ref" => visit_children_arg(graph, GraphNode::root(None), &false,visit_constraint),
"name" => visit_constraint(graph, GraphNode::root(None),&false),
_ => {}
}
if !graph.goto_next_sibling() {
Expand Down
Loading