fork of https://github.com/tree-sitter/tree-sitter-graph

Merge pull request #13 from tree-sitter/no-context

Remove Context object and DisplayFromFoo traits

authored by Hendrik van Antwerpen and committed by GitHub cbf1a2b7 6452b576

+107 -142
src/ast.rs
··· 13 13 use tree_sitter::Language; 14 14 use tree_sitter::Query; 15 15 16 - use crate::Context; 17 - use crate::DisplayWithContext; 18 16 use crate::Identifier; 19 17 use crate::Location; 20 18 ··· 73 71 ForIn(ForIn), 74 72 } 75 73 76 - impl DisplayWithContext for Statement { 77 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 74 + impl std::fmt::Display for Statement { 75 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 78 76 match self { 79 - Statement::DeclareImmutable(stmt) => stmt.fmt(f, ctx), 80 - Statement::DeclareMutable(stmt) => stmt.fmt(f, ctx), 81 - Statement::Assign(stmt) => stmt.fmt(f, ctx), 82 - Statement::CreateGraphNode(stmt) => stmt.fmt(f, ctx), 83 - Statement::AddGraphNodeAttribute(stmt) => stmt.fmt(f, ctx), 84 - Statement::CreateEdge(stmt) => stmt.fmt(f, ctx), 85 - Statement::AddEdgeAttribute(stmt) => stmt.fmt(f, ctx), 86 - Statement::Scan(stmt) => stmt.fmt(f, ctx), 87 - Statement::Print(stmt) => stmt.fmt(f, ctx), 88 - Statement::If(stmt) => stmt.fmt(f, ctx), 89 - Statement::ForIn(stmt) => stmt.fmt(f, ctx), 77 + Self::DeclareImmutable(stmt) => stmt.fmt(f), 78 + Self::DeclareMutable(stmt) => stmt.fmt(f), 79 + Self::Assign(stmt) => stmt.fmt(f), 80 + Self::CreateGraphNode(stmt) => stmt.fmt(f), 81 + Self::AddGraphNodeAttribute(stmt) => stmt.fmt(f), 82 + Self::CreateEdge(stmt) => stmt.fmt(f), 83 + Self::AddEdgeAttribute(stmt) => stmt.fmt(f), 84 + Self::Scan(stmt) => stmt.fmt(f), 85 + Self::Print(stmt) => stmt.fmt(f), 86 + Self::If(stmt) => stmt.fmt(f), 87 + Self::ForIn(stmt) => stmt.fmt(f), 90 88 } 91 89 } 92 90 } ··· 106 104 } 107 105 } 108 106 109 - impl DisplayWithContext for AddEdgeAttribute { 110 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 111 - write!( 112 - f, 113 - "attr ({} -> {})", 114 - self.source.display_with(ctx), 115 - self.sink.display_with(ctx), 116 - )?; 107 + impl std::fmt::Display for AddEdgeAttribute { 108 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 109 + write!(f, "attr ({} -> {})", self.source, self.sink)?; 117 110 for attr in &self.attributes { 118 - write!(f, " {}", attr.display_with(ctx))?; 111 + write!(f, " {}", attr)?; 119 112 } 120 113 write!(f, " at {}", self.location) 121 114 } ··· 135 128 } 136 129 } 137 130 138 - impl DisplayWithContext for AddGraphNodeAttribute { 139 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 140 - write!(f, "attr ({})", self.node.display_with(ctx),)?; 131 + impl std::fmt::Display for AddGraphNodeAttribute { 132 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 133 + write!(f, "attr ({})", self.node)?; 141 134 for attr in &self.attributes { 142 - write!(f, " {}", attr.display_with(ctx),)?; 135 + write!(f, " {}", attr)?; 143 136 } 144 137 write!(f, " at {}", self.location) 145 138 } ··· 159 152 } 160 153 } 161 154 162 - impl DisplayWithContext for Assign { 163 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 155 + impl std::fmt::Display for Assign { 156 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 164 157 write!( 165 158 f, 166 159 "set {} = {} at {}", 167 - self.variable.display_with(ctx), 168 - self.value.display_with(ctx), 169 - self.location, 160 + self.variable, self.value, self.location, 170 161 ) 171 162 } 172 163 } ··· 178 169 pub value: Expression, 179 170 } 180 171 181 - impl DisplayWithContext for Attribute { 182 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 183 - write!( 184 - f, 185 - "{} = {}", 186 - self.name.display_with(ctx), 187 - self.value.display_with(ctx), 188 - ) 172 + impl std::fmt::Display for Attribute { 173 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 174 + write!(f, "{} = {}", self.name, self.value) 189 175 } 190 176 } 191 177 ··· 203 189 } 204 190 } 205 191 206 - impl DisplayWithContext for CreateEdge { 207 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 192 + impl std::fmt::Display for CreateEdge { 193 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 208 194 write!( 209 195 f, 210 196 "edge {} -> {} at {}", 211 - self.source.display_with(ctx), 212 - self.sink.display_with(ctx), 213 - self.location, 197 + self.source, self.sink, self.location, 214 198 ) 215 199 } 216 200 } ··· 228 212 } 229 213 } 230 214 231 - impl DisplayWithContext for CreateGraphNode { 232 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 233 - write!( 234 - f, 235 - "node {} at {}", 236 - self.node.display_with(ctx), 237 - self.location 238 - ) 215 + impl std::fmt::Display for CreateGraphNode { 216 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 217 + write!(f, "node {} at {}", self.node, self.location) 239 218 } 240 219 } 241 220 ··· 253 232 } 254 233 } 255 234 256 - impl DisplayWithContext for DeclareImmutable { 257 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 235 + impl std::fmt::Display for DeclareImmutable { 236 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 258 237 write!( 259 238 f, 260 239 "let {} = {} at {}", 261 - self.variable.display_with(ctx), 262 - self.value.display_with(ctx), 263 - self.location, 240 + self.variable, self.value, self.location, 264 241 ) 265 242 } 266 243 } ··· 279 256 } 280 257 } 281 258 282 - impl DisplayWithContext for DeclareMutable { 283 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 259 + impl std::fmt::Display for DeclareMutable { 260 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 284 261 write!( 285 262 f, 286 263 "var {} = {} at {}", 287 - self.variable.display_with(ctx), 288 - self.value.display_with(ctx), 289 - self.location, 264 + self.variable, self.value, self.location, 290 265 ) 291 266 } 292 267 } ··· 304 279 } 305 280 } 306 281 307 - impl DisplayWithContext for Print { 308 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 282 + impl std::fmt::Display for Print { 283 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 309 284 write!(f, "print")?; 310 285 for val in &self.values { 311 - write!(f, " {},", val.display_with(ctx),)?; 286 + write!(f, " {},", val)?; 312 287 } 313 288 write!(f, " at {}", self.location) 314 289 } ··· 328 303 } 329 304 } 330 305 331 - impl DisplayWithContext for Scan { 332 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 333 - write!( 334 - f, 335 - "scan {} {{ ... }} at {}", 336 - self.value.display_with(ctx), 337 - self.location 338 - ) 306 + impl std::fmt::Display for Scan { 307 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 308 + write!(f, "scan {} {{ ... }} at {}", self.value, self.location) 339 309 } 340 310 } 341 311 ··· 355 325 } 356 326 } 357 327 358 - impl DisplayWithContext for ScanArm { 359 - fn fmt(&self, f: &mut fmt::Formatter, _ctx: &Context) -> fmt::Result { 328 + impl std::fmt::Display for ScanArm { 329 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 360 330 write!(f, "{:?} {{ ... }}", self.regex.as_str()) 361 331 } 362 332 } ··· 374 344 } 375 345 } 376 346 377 - impl DisplayWithContext for If { 378 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 347 + impl std::fmt::Display for If { 348 + fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { 379 349 let mut first = true; 380 350 for arm in &self.arms { 381 351 if first { 382 352 first = false; 383 - write!(f, "if {} {{ ... }}", arm.conditions.display_with(ctx))?; 353 + write!(f, "if {} {{ ... }}", DisplayConditions(&arm.conditions))?; 384 354 } else { 385 355 if !arm.conditions.is_empty() { 386 - write!(f, " elif {} {{ ... }}", arm.conditions.display_with(ctx))?; 356 + write!(f, " elif {} {{ ... }}", DisplayConditions(&arm.conditions))?; 387 357 } else { 388 358 write!(f, " else {{ ... }}")?; 389 359 } ··· 401 371 pub location: Location, 402 372 } 403 373 374 + struct DisplayConditions<'a>(&'a Vec<Condition>); 375 + 404 376 #[derive(Debug, PartialEq, Eq)] 405 377 pub enum Condition { 406 378 Some { ··· 417 389 }, 418 390 } 419 391 420 - impl DisplayWithContext for Vec<Condition> { 421 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 392 + impl std::fmt::Display for DisplayConditions<'_> { 393 + fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { 422 394 let mut first = true; 423 - for condition in self.iter() { 395 + for condition in self.0.iter() { 424 396 if first { 425 397 first = false; 426 - write!(f, "{}", condition.display_with(ctx))?; 398 + write!(f, "{}", condition)?; 427 399 } else { 428 - write!(f, ", {}", condition.display_with(ctx))?; 400 + write!(f, ", {}", condition)?; 429 401 } 430 402 } 431 403 Ok(()) 432 404 } 433 405 } 434 406 435 - impl DisplayWithContext for Condition { 436 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 407 + impl std::fmt::Display for Condition { 408 + fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { 437 409 match self { 438 410 Condition::Some { value, .. } => { 439 - write!(f, "some {}", value.display_with(ctx)) 411 + write!(f, "some {}", value) 440 412 } 441 413 Condition::None { value, .. } => { 442 - write!(f, "none {}", value.display_with(ctx)) 414 + write!(f, "none {}", value) 443 415 } 444 416 Condition::Bool { value, .. } => { 445 - write!(f, "{}", value.display_with(ctx)) 417 + write!(f, "{}", value) 446 418 } 447 419 } 448 420 } ··· 463 435 } 464 436 } 465 437 466 - impl DisplayWithContext for ForIn { 467 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 438 + impl std::fmt::Display for ForIn { 439 + fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { 468 440 write!( 469 441 f, 470 442 "for {} in {} {{ ... }} at {}", 471 - self.variable.display_with(ctx), 472 - self.value.display_with(ctx), 473 - self.location, 443 + self.variable, self.value, self.location, 474 444 ) 475 445 } 476 446 } ··· 482 452 Unscoped(UnscopedVariable), 483 453 } 484 454 485 - impl DisplayWithContext for Variable { 486 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 455 + impl std::fmt::Display for Variable { 456 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 487 457 match self { 488 - Variable::Scoped(variable) => variable.fmt(f, ctx), 489 - Variable::Unscoped(variable) => variable.fmt(f, ctx), 458 + Variable::Scoped(variable) => variable.fmt(f), 459 + Variable::Unscoped(variable) => variable.fmt(f), 490 460 } 491 461 } 492 462 } ··· 505 475 } 506 476 } 507 477 508 - impl DisplayWithContext for ScopedVariable { 509 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 510 - write!( 511 - f, 512 - "{}.{}", 513 - self.scope.display_with(ctx), 514 - self.name.display_with(ctx), 515 - ) 478 + impl std::fmt::Display for ScopedVariable { 479 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 480 + write!(f, "{}.{}", self.scope, self.name) 516 481 } 517 482 } 518 483 ··· 529 494 } 530 495 } 531 496 532 - impl DisplayWithContext for UnscopedVariable { 533 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 534 - write!(f, "{}", self.name.display_with(ctx)) 497 + impl std::fmt::Display for UnscopedVariable { 498 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 499 + write!(f, "{}", self.name) 535 500 } 536 501 } 537 502 ··· 558 523 RegexCapture(RegexCapture), 559 524 } 560 525 561 - impl DisplayWithContext for Expression { 562 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 526 + impl std::fmt::Display for Expression { 527 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 563 528 match self { 564 529 Expression::FalseLiteral => write!(f, "false"), 565 530 Expression::NullLiteral => write!(f, "#null"), 566 531 Expression::TrueLiteral => write!(f, "true"), 567 - Expression::IntegerConstant(expr) => expr.fmt(f, ctx), 568 - Expression::StringConstant(expr) => expr.fmt(f, ctx), 569 - Expression::List(expr) => expr.fmt(f, ctx), 570 - Expression::Set(expr) => expr.fmt(f, ctx), 571 - Expression::Capture(expr) => expr.fmt(f, ctx), 572 - Expression::Variable(expr) => expr.fmt(f, ctx), 573 - Expression::Call(expr) => expr.fmt(f, ctx), 574 - Expression::RegexCapture(expr) => expr.fmt(f, ctx), 532 + Expression::IntegerConstant(expr) => expr.fmt(f), 533 + Expression::StringConstant(expr) => expr.fmt(f), 534 + Expression::List(expr) => expr.fmt(f), 535 + Expression::Set(expr) => expr.fmt(f), 536 + Expression::Capture(expr) => expr.fmt(f), 537 + Expression::Variable(expr) => expr.fmt(f), 538 + Expression::Call(expr) => expr.fmt(f), 539 + Expression::RegexCapture(expr) => expr.fmt(f), 575 540 } 576 541 } 577 542 } ··· 589 554 } 590 555 } 591 556 592 - impl DisplayWithContext for Call { 593 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 594 - write!(f, "({}", self.function.display_with(ctx))?; 557 + impl std::fmt::Display for Call { 558 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 559 + write!(f, "({}", self.function)?; 595 560 for arg in &self.parameters { 596 - write!(f, " {}", arg.display_with(ctx))?; 561 + write!(f, " {}", arg)?; 597 562 } 598 563 write!(f, ")") 599 564 } ··· 619 584 } 620 585 } 621 586 622 - impl DisplayWithContext for Capture { 623 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 624 - write!(f, "@{}", self.name.display_with(ctx)) 587 + impl std::fmt::Display for Capture { 588 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 589 + write!(f, "@{}", self.name) 625 590 } 626 591 } 627 592 ··· 637 602 } 638 603 } 639 604 640 - impl DisplayWithContext for IntegerConstant { 641 - fn fmt(&self, f: &mut fmt::Formatter, _ctx: &Context) -> fmt::Result { 605 + impl std::fmt::Display for IntegerConstant { 606 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 642 607 write!(f, "{}", self.value) 643 608 } 644 609 } ··· 655 620 } 656 621 } 657 622 658 - impl DisplayWithContext for ListComprehension { 659 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 623 + impl std::fmt::Display for ListComprehension { 624 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 660 625 write!(f, "[")?; 661 626 let mut first = true; 662 627 for elem in &self.elements { 663 628 if first { 664 - write!(f, "{}", elem.display_with(ctx))?; 629 + write!(f, "{}", elem)?; 665 630 first = false; 666 631 } else { 667 - write!(f, ", {}", elem.display_with(ctx))?; 632 + write!(f, ", {}", elem)?; 668 633 } 669 634 } 670 635 write!(f, "]") ··· 683 648 } 684 649 } 685 650 686 - impl DisplayWithContext for RegexCapture { 687 - fn fmt(&self, f: &mut fmt::Formatter, _ctx: &Context) -> fmt::Result { 651 + impl std::fmt::Display for RegexCapture { 652 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 688 653 write!(f, "${}", self.match_index) 689 654 } 690 655 } ··· 701 666 } 702 667 } 703 668 704 - impl DisplayWithContext for SetComprehension { 705 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 669 + impl std::fmt::Display for SetComprehension { 670 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 706 671 write!(f, "{{")?; 707 672 let mut first = true; 708 673 for elem in &self.elements { 709 674 if first { 710 - write!(f, "{}", elem.display_with(ctx))?; 675 + write!(f, "{}", elem)?; 711 676 first = false; 712 677 } else { 713 - write!(f, ", {}", elem.display_with(ctx))?; 678 + write!(f, ", {}", elem)?; 714 679 } 715 680 } 716 681 write!(f, "}}") ··· 729 694 } 730 695 } 731 696 732 - impl DisplayWithContext for StringConstant { 733 - fn fmt(&self, f: &mut fmt::Formatter, _ctx: &Context) -> fmt::Result { 697 + impl std::fmt::Display for StringConstant { 698 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 734 699 write!(f, "{:?}", self.value) 735 700 } 736 701 }
+8 -10
src/bin/tree-sitter-graph/main.rs
··· 16 16 use tree_sitter_config::Config; 17 17 use tree_sitter_graph::ast::File; 18 18 use tree_sitter_graph::functions::Functions; 19 - use tree_sitter_graph::Context; 20 19 use tree_sitter_graph::Variables; 21 20 use tree_sitter_loader::Loader; 22 21 ··· 68 67 let tree = parser 69 68 .parse(&source, None) 70 69 .ok_or_else(|| anyhow!("Could not parse {}", source_path.display()))?; 71 - let mut ctx = Context::new(); 72 - let file = File::from_str(language, &mut ctx, &tsg) 73 - .with_context(|| anyhow!("Error parsing TSG file {}", tsg_path.display()))?; 74 - let mut functions = Functions::stdlib(&mut ctx); 70 + let file = File::from_str(language, &tsg) 71 + .with_context(|| format!("Error parsing TSG file {}", tsg_path.display()))?; 72 + let mut functions = Functions::stdlib(); 75 73 let globals = Variables::new(); 76 74 let graph = if lazy { 77 - file.execute_lazy(&mut ctx, &tree, &source, &mut functions, &globals) 75 + file.execute_lazy(&tree, &source, &mut functions, &globals) 78 76 } else { 79 - file.execute(&mut ctx, &tree, &source, &mut functions, &globals) 77 + file.execute(&tree, &source, &mut functions, &globals) 80 78 } 81 - .with_context(|| anyhow!("Could not execute TSG file {}", tsg_path.display()))?; 79 + .with_context(|| format!("Could not execute TSG file {}", tsg_path.display()))?; 82 80 let json = matches.is_present("json"); 83 81 if json { 84 - graph.display_json(&ctx); 82 + graph.display_json(); 85 83 } else if !quiet { 86 - print!("{}", graph.display_with(&ctx)); 84 + print!("{}", graph.pretty_print()); 87 85 } 88 86 Ok(()) 89 87 }
+11 -23
src/checker.rs
··· 18 18 use crate::variables::VariableError; 19 19 use crate::variables::VariableMap; 20 20 use crate::variables::Variables; 21 - use crate::Context; 22 - use crate::DisplayWithContext as _; 23 21 use crate::Location; 24 22 25 23 #[derive(Debug, Error)] ··· 40 38 41 39 /// Checker context 42 40 struct CheckContext<'a> { 43 - ctx: &'a Context, 44 41 locals: &'a mut dyn Variables<ExpressionResult>, 45 42 file_query: &'a Query, 46 43 stanza_index: usize, ··· 51 48 // File 52 49 53 50 impl ast::File { 54 - pub fn check(&mut self, ctx: &Context) -> Result<(), CheckError> { 51 + pub fn check(&mut self) -> Result<(), CheckError> { 55 52 let file_query = self.query.as_ref().unwrap(); 56 53 for (index, stanza) in self.stanzas.iter_mut().enumerate() { 57 - stanza.check(ctx, file_query, index)?; 54 + stanza.check(file_query, index)?; 58 55 } 59 56 Ok(()) 60 57 } ··· 64 61 // Stanza 65 62 66 63 impl ast::Stanza { 67 - fn check( 68 - &mut self, 69 - ctx: &Context, 70 - file_query: &Query, 71 - stanza_index: usize, 72 - ) -> Result<(), CheckError> { 64 + fn check(&mut self, file_query: &Query, stanza_index: usize) -> Result<(), CheckError> { 73 65 let mut locals = VariableMap::new(); 74 66 let mut ctx = CheckContext { 75 - ctx, 76 67 locals: &mut locals, 77 68 file_query, 78 69 stanza_index, ··· 197 188 198 189 let mut arm_locals = VariableMap::new_child(ctx.locals); 199 190 let mut arm_ctx = CheckContext { 200 - ctx: ctx.ctx, 201 191 locals: &mut arm_locals, 202 192 file_query: ctx.file_query, 203 193 stanza_index: ctx.stanza_index, ··· 230 220 231 221 let mut arm_locals = VariableMap::new_child(ctx.locals); 232 222 let mut arm_ctx = CheckContext { 233 - ctx: ctx.ctx, 234 223 locals: &mut arm_locals, 235 224 file_query: ctx.file_query, 236 225 stanza_index: ctx.stanza_index, ··· 280 269 281 270 let mut loop_locals = VariableMap::new_child(ctx.locals); 282 271 let mut loop_ctx = CheckContext { 283 - ctx: ctx.ctx, 284 272 locals: &mut loop_locals, 285 273 file_query: ctx.file_query, 286 274 stanza_index: ctx.stanza_index, ··· 380 368 381 369 impl ast::Capture { 382 370 fn check(&mut self, ctx: &mut CheckContext) -> Result<ExpressionResult, CheckError> { 383 - let name = ctx.ctx.resolve(self.name); 371 + let name = self.name.to_string(); 384 372 self.stanza_capture_index = ctx 385 373 .stanza_query 386 - .capture_index_for_name(name) 387 - .ok_or_else(|| CheckError::UndefinedSyntaxCapture(name.to_string(), self.location))? 374 + .capture_index_for_name(&name) 375 + .ok_or_else(|| CheckError::UndefinedSyntaxCapture(name.clone(), self.location))? 388 376 as usize; 389 - self.file_capture_index = ctx.file_query.capture_index_for_name(name).unwrap() as usize; 377 + self.file_capture_index = ctx.file_query.capture_index_for_name(&name).unwrap() as usize; 390 378 self.quantifier = 391 379 ctx.file_query.capture_quantifiers(ctx.stanza_index)[self.file_capture_index]; 392 380 Ok(ExpressionResult { ··· 470 458 value.is_local = false; 471 459 } 472 460 ctx.locals 473 - .add(self.name, value, mutable) 474 - .map_err(|e| CheckError::Variable(e, format!("{}", self.name.display_with(ctx.ctx)))) 461 + .add(self.name.clone(), value, mutable) 462 + .map_err(|e| CheckError::Variable(e, format!("{}", self.name))) 475 463 } 476 464 477 465 fn check_set( ··· 486 474 // assignments, and can assume non-local to be sound. 487 475 value.is_local = false; 488 476 ctx.locals 489 - .set(self.name, value) 490 - .map_err(|e| CheckError::Variable(e, format!("{}", self.name.display_with(ctx.ctx)))) 477 + .set(self.name.clone(), value) 478 + .map_err(|e| CheckError::Variable(e, format!("{}", self.name))) 491 479 } 492 480 493 481 fn check_get(&mut self, ctx: &mut CheckContext) -> Result<ExpressionResult, CheckError> {
+48 -90
src/execution.rs
··· 40 40 use crate::ast::UnscopedVariable; 41 41 use crate::ast::Variable; 42 42 use crate::functions::Functions; 43 - use crate::graph::DisplayWithGraph; 44 43 use crate::graph::Graph; 45 - use crate::graph::GraphNodeRef; 46 44 use crate::graph::SyntaxNodeRef; 47 45 use crate::graph::Value; 48 46 pub use crate::variables::Globals; 49 47 use crate::variables::VariableMap; 50 48 use crate::variables::Variables; 51 - use crate::Context; 52 - use crate::DisplayWithContext; 53 49 54 50 impl File { 55 51 /// Executes this graph DSL file against a source file. You must provide the parsed syntax ··· 57 53 /// provide the set of functions and global variables that are available during execution. 58 54 pub fn execute<'tree>( 59 55 &self, 60 - ctx: &Context, 61 56 tree: &'tree Tree, 62 57 source: &'tree str, 63 58 functions: &mut Functions, 64 59 globals: &Globals, 65 60 ) -> Result<Graph<'tree>, ExecutionError> { 66 61 let mut graph = Graph::new(); 67 - self.execute_into(ctx, &mut graph, tree, source, functions, globals)?; 62 + self.execute_into(&mut graph, tree, source, functions, globals)?; 68 63 Ok(graph) 69 64 } 70 65 ··· 75 70 /// “pre-seed” the graph with some predefined nodes and/or edges before executing the DSL file. 76 71 pub fn execute_into<'tree>( 77 72 &self, 78 - ctx: &Context, 79 73 graph: &mut Graph<'tree>, 80 74 tree: &'tree Tree, 81 75 source: &'tree str, ··· 92 86 let mut cursor = QueryCursor::new(); 93 87 for stanza in &self.stanzas { 94 88 stanza.execute( 95 - ctx, 96 89 tree, 97 90 source, 98 91 graph, ··· 177 170 } 178 171 179 172 struct ExecutionContext<'a, 'g, 's, 'tree> { 180 - ctx: &'a Context, 181 173 source: &'tree str, 182 174 graph: &'a mut Graph<'tree>, 183 175 functions: &'a mut Functions, ··· 208 200 impl Stanza { 209 201 fn execute<'l, 's, 'tree>( 210 202 &self, 211 - ctx: &Context, 212 203 tree: &'tree Tree, 213 204 source: &'tree str, 214 205 graph: &mut Graph<'tree>, ··· 224 215 for mat in matches { 225 216 locals.clear(); 226 217 let mut exec = ExecutionContext { 227 - ctx, 228 218 source, 229 219 graph, 230 220 functions, ··· 238 228 for statement in &self.statements { 239 229 statement 240 230 .execute(&mut exec) 241 - .with_context(|| format!("Executing {}", statement.display_with(exec.ctx)))?; 231 + .with_context(|| format!("Executing {}", statement))?; 242 232 } 243 233 } 244 234 Ok(()) ··· 294 284 295 285 impl AddGraphNodeAttribute { 296 286 fn execute(&self, exec: &mut ExecutionContext) -> Result<(), ExecutionError> { 297 - let node = self.node.evaluate_as_node(exec)?; 287 + let node = self.node.evaluate(exec)?.into_graph_node_ref()?; 298 288 for attribute in &self.attributes { 299 289 let value = attribute.value.evaluate(exec)?; 300 290 exec.graph[node] 301 291 .attributes 302 - .add(attribute.name, value) 292 + .add(attribute.name.clone(), value) 303 293 .map_err(|_| { 304 294 ExecutionError::DuplicateAttribute(format!( 305 295 " {} on graph node ({}) in {}", 306 - attribute.name.display_with(exec.ctx), 307 - node.display_with(exec.graph), 308 - self.display_with(exec.ctx), 296 + attribute.name, node, self, 309 297 )) 310 298 })?; 311 299 } ··· 315 303 316 304 impl CreateEdge { 317 305 fn execute(&self, exec: &mut ExecutionContext) -> Result<(), ExecutionError> { 318 - let source = self.source.evaluate_as_node(exec)?; 319 - let sink = self.sink.evaluate_as_node(exec)?; 320 - let ctx = exec.ctx; 306 + let source = self.source.evaluate(exec)?.into_graph_node_ref()?; 307 + let sink = self.sink.evaluate(exec)?.into_graph_node_ref()?; 321 308 if let Err(_) = exec.graph[source].add_edge(sink) { 322 309 Err(ExecutionError::DuplicateEdge(format!( 323 310 "({} -> {}) in {}", 324 - source.display_with(exec.graph), 325 - sink.display_with(exec.graph), 326 - self.display_with(ctx) 311 + source, sink, self, 327 312 )))?; 328 313 } 329 314 Ok(()) ··· 332 317 333 318 impl AddEdgeAttribute { 334 319 fn execute(&self, exec: &mut ExecutionContext) -> Result<(), ExecutionError> { 335 - let source = self.source.evaluate_as_node(exec)?; 336 - let sink = self.sink.evaluate_as_node(exec)?; 320 + let source = self.source.evaluate(exec)?.into_graph_node_ref()?; 321 + let sink = self.sink.evaluate(exec)?.into_graph_node_ref()?; 337 322 for attribute in &self.attributes { 338 323 let value = attribute.value.evaluate(exec)?; 339 324 let edge = match exec.graph[source].get_edge_mut(sink) { 340 325 Some(edge) => Ok(edge), 341 326 None => Err(ExecutionError::UndefinedEdge(format!( 342 327 "({} -> {}) in {}", 343 - source.display_with(exec.graph), 344 - sink.display_with(exec.graph), 345 - self.display_with(exec.ctx) 328 + source, sink, self, 346 329 ))), 347 330 }?; 348 - edge.attributes.add(attribute.name, value).map_err(|_| { 349 - ExecutionError::DuplicateAttribute(format!( 350 - " {} on edge ({} -> {}) in {}", 351 - attribute.name.display_with(exec.ctx), 352 - source.display_with(exec.graph), 353 - sink.display_with(exec.graph), 354 - self.display_with(exec.ctx), 355 - )) 356 - })?; 331 + edge.attributes 332 + .add(attribute.name.clone(), value) 333 + .map_err(|_| { 334 + ExecutionError::DuplicateAttribute(format!( 335 + " {} on edge ({} -> {}) in {}", 336 + attribute.name, source, sink, self, 337 + )) 338 + })?; 357 339 } 358 340 Ok(()) 359 341 } ··· 361 343 362 344 impl Scan { 363 345 fn execute(&self, exec: &mut ExecutionContext) -> Result<(), ExecutionError> { 364 - let match_string = self.value.evaluate(exec)?.into_string(exec.graph)?; 346 + let match_string = self.value.evaluate(exec)?.into_string()?; 365 347 366 348 let mut i = 0; 367 349 let mut matches = Vec::new(); ··· 400 382 401 383 let mut arm_locals = VariableMap::new_child(exec.locals); 402 384 let mut arm_exec = ExecutionContext { 403 - ctx: exec.ctx, 404 385 source: exec.source, 405 386 graph: exec.graph, 406 387 functions: exec.functions, ··· 415 396 for statement in &arm.statements { 416 397 statement 417 398 .execute(&mut arm_exec) 418 - .with_context(|| format!("Executing {}", statement.display_with(arm_exec.ctx))) 399 + .with_context(|| format!("Executing {}", statement)) 419 400 .with_context(|| { 420 401 format!( 421 402 "Matching {} with arm \"{}\" {{ ... }}", ··· 438 419 eprint!("{}", expr.value); 439 420 } else { 440 421 let value = value.evaluate(exec)?; 441 - eprint!("{}", value.display_with(exec.graph)); 422 + eprint!("{}", value); 442 423 } 443 424 } 444 425 eprintln!(); ··· 456 437 if result { 457 438 let mut arm_locals = VariableMap::new_child(exec.locals); 458 439 let mut arm_exec = ExecutionContext { 459 - ctx: exec.ctx, 460 440 source: exec.source, 461 441 graph: exec.graph, 462 442 functions: exec.functions, ··· 482 462 match self { 483 463 Condition::Some { value, .. } => Ok(!value.evaluate(exec)?.is_null()), 484 464 Condition::None { value, .. } => Ok(value.evaluate(exec)?.is_null()), 485 - Condition::Bool { value, .. } => Ok(value.evaluate(exec)?.into_bool(exec.graph)?), 465 + Condition::Bool { value, .. } => Ok(value.evaluate(exec)?.into_boolean()?), 486 466 } 487 467 } 488 468 } 489 469 490 470 impl ForIn { 491 471 fn execute(&self, exec: &mut ExecutionContext) -> Result<(), ExecutionError> { 492 - let values = self.value.evaluate(exec)?.into_list(exec.graph)?; 472 + let values = self.value.evaluate(exec)?.into_list()?; 493 473 let mut loop_locals = VariableMap::new_child(exec.locals); 494 474 for value in values { 495 475 loop_locals.clear(); 496 476 let mut loop_exec = ExecutionContext { 497 - ctx: exec.ctx, 498 477 source: exec.source, 499 478 graph: exec.graph, 500 479 functions: exec.functions, ··· 530 509 Expression::RegexCapture(expr) => expr.evaluate(exec), 531 510 } 532 511 } 533 - 534 - fn evaluate_as_node( 535 - &self, 536 - exec: &mut ExecutionContext, 537 - ) -> Result<GraphNodeRef, ExecutionError> { 538 - let node = self.evaluate(exec)?; 539 - match node { 540 - Value::GraphNode(node) => Ok(node), 541 - _ => Err(ExecutionError::ExpectedGraphNode(format!( 542 - " {}, got {}", 543 - self.display_with(exec.ctx), 544 - node.display_with(exec.graph) 545 - ))), 546 - } 547 - } 548 512 } 549 513 550 514 impl IntegerConstant { ··· 599 563 exec.function_parameters.push(parameter); 600 564 } 601 565 exec.functions.call( 602 - exec.ctx, 603 - self.function, 566 + &self.function, 604 567 exec.graph, 605 568 exec.source, 606 569 &mut exec ··· 612 575 613 576 impl RegexCapture { 614 577 fn evaluate(&self, exec: &mut ExecutionContext) -> Result<Value, ExecutionError> { 615 - let capture = exec.current_regex_captures.get(self.match_index).ok_or( 616 - ExecutionError::UndefinedRegexCapture(format!("{}", self.display_with(exec.ctx))), 617 - )?; 578 + let capture = exec 579 + .current_regex_captures 580 + .get(self.match_index) 581 + .ok_or(ExecutionError::UndefinedRegexCapture(format!("{}", self)))?; 618 582 Ok(Value::String(capture.clone())) 619 583 } 620 584 } ··· 662 626 _ => { 663 627 return Err(ExecutionError::InvalidVariableScope(format!( 664 628 " got {}", 665 - scope.display_with(exec.graph) 629 + scope 666 630 ))) 667 631 } 668 632 }; ··· 672 636 } else { 673 637 Err(ExecutionError::UndefinedVariable(format!( 674 638 "{} on node {}", 675 - self.display_with(exec.ctx), 676 - scope.display_with(exec.graph) 639 + self, scope, 677 640 ))) 678 641 } 679 642 } ··· 690 653 _ => { 691 654 return Err(ExecutionError::InvalidVariableScope(format!( 692 655 " got {}", 693 - scope.display_with(exec.graph) 656 + scope 694 657 ))) 695 658 } 696 659 }; 697 660 let variables = exec.scoped.get(scope); 698 - variables.add(self.name, value, mutable).map_err(|_| { 699 - ExecutionError::DuplicateVariable(format!(" {}", self.display_with(exec.ctx))) 700 - }) 661 + variables 662 + .add(self.name.clone(), value, mutable) 663 + .map_err(|_| ExecutionError::DuplicateVariable(format!(" {}", self))) 701 664 } 702 665 703 666 fn set(&self, exec: &mut ExecutionContext, value: Value) -> Result<(), ExecutionError> { ··· 707 670 _ => { 708 671 return Err(ExecutionError::InvalidVariableScope(format!( 709 672 " got {}", 710 - scope.display_with(exec.graph) 673 + scope, 711 674 ))) 712 675 } 713 676 }; 714 677 let variables = exec.scoped.get(scope); 715 - variables.set(self.name, value).map_err(|_| { 716 - ExecutionError::DuplicateVariable(format!(" {}", self.display_with(exec.ctx))) 717 - }) 678 + variables 679 + .set(self.name.clone(), value) 680 + .map_err(|_| ExecutionError::DuplicateVariable(format!(" {}", self))) 718 681 } 719 682 } 720 683 ··· 725 688 } else { 726 689 exec.locals.get(&self.name) 727 690 } 728 - .ok_or_else(|| { 729 - ExecutionError::UndefinedVariable(format!("{}", self.display_with(exec.ctx))) 730 - }) 691 + .ok_or_else(|| ExecutionError::UndefinedVariable(format!("{}", self))) 731 692 } 732 693 733 694 fn add( ··· 739 700 if exec.globals.get(&self.name).is_some() { 740 701 return Err(ExecutionError::DuplicateVariable(format!( 741 702 " global {}", 742 - self.display_with(exec.ctx) 703 + self, 743 704 ))); 744 705 } 745 - exec.locals.add(self.name, value, mutable).map_err(|_| { 746 - ExecutionError::DuplicateVariable(format!(" local {}", self.display_with(exec.ctx))) 747 - }) 706 + exec.locals 707 + .add(self.name.clone(), value, mutable) 708 + .map_err(|_| ExecutionError::DuplicateVariable(format!(" local {}", self))) 748 709 } 749 710 750 711 fn set(&self, exec: &mut ExecutionContext, value: Value) -> Result<(), ExecutionError> { 751 712 if exec.globals.get(&self.name).is_some() { 752 713 return Err(ExecutionError::CannotAssignImmutableVariable(format!( 753 714 " global {}", 754 - self.display_with(exec.ctx) 715 + self, 755 716 ))); 756 717 } 757 - exec.locals.set(self.name, value).map_err(|_| { 718 + exec.locals.set(self.name.clone(), value).map_err(|_| { 758 719 if exec.locals.get(&self.name).is_some() { 759 - ExecutionError::CannotAssignImmutableVariable(format!( 760 - "{}", 761 - self.display_with(exec.ctx) 762 - )) 720 + ExecutionError::CannotAssignImmutableVariable(format!("{}", self)) 763 721 } else { 764 - ExecutionError::UndefinedVariable(format!("{}", self.display_with(exec.ctx))) 722 + ExecutionError::UndefinedVariable(format!("{}", self)) 765 723 } 766 724 }) 767 725 }
+41 -51
src/functions.rs
··· 12 12 use crate::execution::ExecutionError; 13 13 use crate::graph::Graph; 14 14 use crate::graph::Value; 15 - use crate::Context; 16 - use crate::DisplayWithContext; 17 15 use crate::Identifier; 18 16 19 17 /// The implementation of a function that can be called from the graph DSL. ··· 42 40 /// # use tree_sitter_graph::graph::Value; 43 41 /// # use tree_sitter_graph::ExecutionError; 44 42 /// # fn main() -> Result<(), ExecutionError> { 45 - /// # let graph = Graph::new(); 46 43 /// # let param_vec = vec![Value::String("test".to_string()), Value::Integer(42)]; 47 44 /// # let mut params = param_vec.into_iter(); 48 - /// let first_param = params.param()?.into_string(&graph)?; 49 - /// let second_param = params.param()?.into_integer(&graph)?; 45 + /// let first_param = params.param()?.into_string()?; 46 + /// let second_param = params.param()?.as_integer()?; 50 47 /// // etc 51 48 /// params.finish()?; 52 49 /// # Ok(()) ··· 99 96 100 97 /// Returns the standard library of functions, as defined in the [language 101 98 /// reference][`crate::reference::functions`]. 102 - pub fn stdlib(ctx: &mut Context) -> Functions { 99 + pub fn stdlib() -> Functions { 103 100 let mut functions = Functions::new(); 104 101 // general functions 105 - functions.add(ctx.add_identifier("is-null"), stdlib::IsNull); 102 + functions.add(Identifier::from("is-null"), stdlib::IsNull); 106 103 // tree functions 107 104 functions.add( 108 - ctx.add_identifier("named-child-index"), 105 + Identifier::from("named-child-index"), 109 106 stdlib::syntax::NamedChildIndex, 110 107 ); 108 + functions.add(Identifier::from("source-text"), stdlib::syntax::SourceText); 109 + functions.add(Identifier::from("start-row"), stdlib::syntax::StartRow); 111 110 functions.add( 112 - ctx.add_identifier("source-text"), 113 - stdlib::syntax::SourceText, 114 - ); 115 - functions.add(ctx.add_identifier("start-row"), stdlib::syntax::StartRow); 116 - functions.add( 117 - ctx.add_identifier("start-column"), 111 + Identifier::from("start-column"), 118 112 stdlib::syntax::StartColumn, 119 113 ); 120 - functions.add(ctx.add_identifier("end-row"), stdlib::syntax::EndRow); 121 - functions.add(ctx.add_identifier("end-column"), stdlib::syntax::EndColumn); 122 - functions.add(ctx.add_identifier("node-type"), stdlib::syntax::NodeType); 114 + functions.add(Identifier::from("end-row"), stdlib::syntax::EndRow); 115 + functions.add(Identifier::from("end-column"), stdlib::syntax::EndColumn); 116 + functions.add(Identifier::from("node-type"), stdlib::syntax::NodeType); 123 117 functions.add( 124 - ctx.add_identifier("named-child-count"), 118 + Identifier::from("named-child-count"), 125 119 stdlib::syntax::NamedChildCount, 126 120 ); 127 121 // graph functions 128 - functions.add(ctx.add_identifier("node"), stdlib::graph::Node); 122 + functions.add(Identifier::from("node"), stdlib::graph::Node); 129 123 // boolean functions 130 - functions.add(ctx.add_identifier("not"), stdlib::bool::Not); 131 - functions.add(ctx.add_identifier("and"), stdlib::bool::And); 132 - functions.add(ctx.add_identifier("or"), stdlib::bool::Or); 124 + functions.add(Identifier::from("not"), stdlib::bool::Not); 125 + functions.add(Identifier::from("and"), stdlib::bool::And); 126 + functions.add(Identifier::from("or"), stdlib::bool::Or); 133 127 // math functions 134 - functions.add(ctx.add_identifier("plus"), stdlib::math::Plus); 128 + functions.add(Identifier::from("plus"), stdlib::math::Plus); 135 129 // string functions 136 - functions.add(ctx.add_identifier("replace"), stdlib::string::Replace); 130 + functions.add(Identifier::from("replace"), stdlib::string::Replace); 137 131 functions 138 132 } 139 133 ··· 148 142 /// Calls a named function, returning an error if there is no function with that name. 149 143 pub fn call( 150 144 &mut self, 151 - ctx: &Context, 152 - name: Identifier, 145 + name: &Identifier, 153 146 graph: &mut Graph, 154 147 source: &str, 155 148 parameters: &mut dyn Parameters, 156 149 ) -> Result<Value, ExecutionError> { 157 150 let function = self 158 151 .functions 159 - .get_mut(&name) 160 - .ok_or(ExecutionError::UndefinedFunction(format!( 161 - "{}", 162 - name.display_with(ctx) 163 - )))?; 152 + .get_mut(name) 153 + .ok_or(ExecutionError::UndefinedFunction(format!("{}", name)))?; 164 154 function.call(graph, source, parameters) 165 155 } 166 156 } ··· 212 202 _source: &str, 213 203 parameters: &mut dyn Parameters, 214 204 ) -> Result<Value, ExecutionError> { 215 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 205 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 216 206 parameters.finish()?; 217 207 let parent = match node.parent() { 218 208 Some(parent) => parent, ··· 240 230 source: &str, 241 231 parameters: &mut dyn Parameters, 242 232 ) -> Result<Value, ExecutionError> { 243 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 233 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 244 234 parameters.finish()?; 245 235 Ok(Value::String(source[node.byte_range()].to_string())) 246 236 } ··· 257 247 _source: &str, 258 248 parameters: &mut dyn Parameters, 259 249 ) -> Result<Value, ExecutionError> { 260 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 250 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 261 251 parameters.finish()?; 262 252 Ok(Value::Integer(node.start_position().row as u32)) 263 253 } ··· 275 265 _source: &str, 276 266 parameters: &mut dyn Parameters, 277 267 ) -> Result<Value, ExecutionError> { 278 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 268 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 279 269 parameters.finish()?; 280 270 Ok(Value::Integer(node.start_position().column as u32)) 281 271 } ··· 292 282 _source: &str, 293 283 parameters: &mut dyn Parameters, 294 284 ) -> Result<Value, ExecutionError> { 295 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 285 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 296 286 parameters.finish()?; 297 287 Ok(Value::Integer(node.end_position().row as u32)) 298 288 } ··· 309 299 _source: &str, 310 300 parameters: &mut dyn Parameters, 311 301 ) -> Result<Value, ExecutionError> { 312 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 302 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 313 303 parameters.finish()?; 314 304 Ok(Value::Integer(node.end_position().column as u32)) 315 305 } ··· 326 316 _source: &str, 327 317 parameters: &mut dyn Parameters, 328 318 ) -> Result<Value, ExecutionError> { 329 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 319 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 330 320 parameters.finish()?; 331 321 Ok(Value::String(node.kind().to_string())) 332 322 } ··· 344 334 _source: &str, 345 335 parameters: &mut dyn Parameters, 346 336 ) -> Result<Value, ExecutionError> { 347 - let node = graph[parameters.param()?.into_syntax_node_ref(graph)?]; 337 + let node = graph[parameters.param()?.into_syntax_node_ref()?]; 348 338 parameters.finish()?; 349 339 Ok(Value::Integer(node.named_child_count() as u32)) 350 340 } ··· 380 370 impl Function for Not { 381 371 fn call( 382 372 &mut self, 383 - graph: &mut Graph, 373 + _graph: &mut Graph, 384 374 _source: &str, 385 375 parameters: &mut dyn Parameters, 386 376 ) -> Result<Value, ExecutionError> { 387 - let result = !parameters.param()?.into_bool(graph)?; 377 + let result = !parameters.param()?.as_boolean()?; 388 378 parameters.finish()?; 389 379 Ok(result.into()) 390 380 } ··· 396 386 impl Function for And { 397 387 fn call( 398 388 &mut self, 399 - graph: &mut Graph, 389 + _graph: &mut Graph, 400 390 _source: &str, 401 391 parameters: &mut dyn Parameters, 402 392 ) -> Result<Value, ExecutionError> { 403 393 let mut result = true; 404 394 while let Ok(parameter) = parameters.param() { 405 - result &= parameter.into_bool(graph)?; 395 + result &= parameter.as_boolean()?; 406 396 } 407 397 Ok(result.into()) 408 398 } ··· 414 404 impl Function for Or { 415 405 fn call( 416 406 &mut self, 417 - graph: &mut Graph, 407 + _graph: &mut Graph, 418 408 _source: &str, 419 409 parameters: &mut dyn Parameters, 420 410 ) -> Result<Value, ExecutionError> { 421 411 let mut result = false; 422 412 while let Ok(parameter) = parameters.param() { 423 - result |= parameter.into_bool(graph)?; 413 + result |= parameter.as_boolean()?; 424 414 } 425 415 Ok(result.into()) 426 416 } ··· 436 426 impl Function for Plus { 437 427 fn call( 438 428 &mut self, 439 - graph: &mut Graph, 429 + _graph: &mut Graph, 440 430 _source: &str, 441 431 parameters: &mut dyn Parameters, 442 432 ) -> Result<Value, ExecutionError> { 443 433 let mut result = 0; 444 434 while let Ok(parameter) = parameters.param() { 445 - result += parameter.into_integer(graph)?; 435 + result += parameter.as_integer()?; 446 436 } 447 437 Ok(Value::Integer(result)) 448 438 } ··· 458 448 impl Function for Replace { 459 449 fn call( 460 450 &mut self, 461 - graph: &mut Graph, 451 + _graph: &mut Graph, 462 452 _source: &str, 463 453 parameters: &mut dyn Parameters, 464 454 ) -> Result<Value, ExecutionError> { 465 - let text = parameters.param()?.into_string(graph)?; 466 - let pattern = parameters.param()?.into_string(graph)?; 455 + let text = parameters.param()?.into_string()?; 456 + let pattern = parameters.param()?.into_string()?; 467 457 let pattern = Regex::new(&pattern).map_err(ExecutionError::other)?; 468 - let replacement = parameters.param()?.into_string(graph)?; 458 + let replacement = parameters.param()?.into_string()?; 469 459 parameters.finish()?; 470 460 Ok(Value::String( 471 461 pattern.replace_all(&text, replacement).to_string(),
+176 -303
src/graph.rs
··· 7 7 8 8 //! Defines data types for the graphs produced by the graph DSL 9 9 10 + use std::borrow::Borrow; 10 11 use std::collections::hash_map::Entry; 11 12 use std::collections::BTreeSet; 12 13 use std::collections::HashMap; 13 14 use std::fmt; 15 + use std::hash::Hash; 14 16 use std::ops::Index; 15 17 use std::ops::IndexMut; 16 18 17 - use smallvec::SmallVec; 18 - use tree_sitter::Node; 19 - 20 - use serde::ser; 21 19 use serde::ser::SerializeMap; 22 20 use serde::ser::SerializeSeq; 21 + use serde::Serialize; 22 + use serde::Serializer; 23 23 use serde_json; 24 + use smallvec::SmallVec; 25 + use tree_sitter::Node; 24 26 25 27 use crate::execution::ExecutionError; 26 - use crate::Context; 27 28 use crate::Identifier; 28 29 29 30 /// A graph produced by executing a graph DSL file. Graphs include a lifetime parameter to ensure 30 31 /// that they don't outlive the tree-sitter syntax tree that they are generated from. 31 32 #[derive(Default)] 32 33 pub struct Graph<'tree> { 33 - syntax_nodes: HashMap<SyntaxNodeRef, Node<'tree>>, 34 + syntax_nodes: HashMap<SyntaxNodeID, Node<'tree>>, 34 35 graph_nodes: Vec<GraphNode>, 35 36 } 36 37 ··· 48 49 /// The graph won't contain _every_ syntax node in the parsed syntax tree; it will only contain 49 50 /// those nodes that are referenced at some point during the execution of the graph DSL file. 50 51 pub fn add_syntax_node(&mut self, node: Node<'tree>) -> SyntaxNodeRef { 51 - let index = SyntaxNodeRef(node.id() as SyntaxNodeID); 52 - self.syntax_nodes.insert(index, node); 53 - index 52 + let index = node.id() as SyntaxNodeID; 53 + let node_ref = SyntaxNodeRef { 54 + index, 55 + kind: node.kind(), 56 + position: node.start_position(), 57 + }; 58 + self.syntax_nodes.entry(index).or_insert(node); 59 + node_ref 54 60 } 55 61 56 62 /// Adds a new graph node to the graph, returning a graph DSL reference to it. ··· 61 67 GraphNodeRef(index) 62 68 } 63 69 64 - /// fmt::Displays the contents of this graph. 65 - pub fn display_with<'a>(&'a self, ctx: &'a Context) -> impl fmt::Display + 'a { 66 - struct DisplayGraph<'a, 'tree>(&'a Graph<'tree>, &'a Context); 70 + /// Pretty-prints the contents of this graph. 71 + pub fn pretty_print<'a>(&'a self) -> impl fmt::Display + 'a { 72 + struct DisplayGraph<'a, 'tree>(&'a Graph<'tree>); 67 73 68 74 impl<'a, 'tree> fmt::Display for DisplayGraph<'a, 'tree> { 69 75 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 70 76 let graph = self.0; 71 - let ctx = self.1; 72 77 for (node_index, node) in graph.graph_nodes.iter().enumerate() { 73 - write!( 74 - f, 75 - "node {}\n{}", 76 - node_index, 77 - node.attributes.display_with(ctx, graph) 78 - )?; 78 + write!(f, "node {}\n{}", node_index, node.attributes)?; 79 79 for (sink, edge) in &node.outgoing_edges { 80 - write!( 81 - f, 82 - "edge {} -> {}\n{}", 83 - node_index, 84 - *sink, 85 - edge.attributes.display_with(ctx, graph) 86 - )?; 80 + write!(f, "edge {} -> {}\n{}", node_index, *sink, edge.attributes)?; 87 81 } 88 82 } 89 83 Ok(()) 90 84 } 91 85 } 92 86 93 - DisplayGraph(self, ctx) 87 + DisplayGraph(self) 94 88 } 95 89 96 - pub fn display_json<'a>(&'a self, ctx: &'a Context) -> () { 97 - // TODO: move this all into a new module 98 - struct InContext<'a, T>(&'a T, &'a Context); 99 - 100 - impl<'a> Context { 101 - fn with<T>(&'a self, t: &'a T) -> InContext<'a, T> { 102 - InContext(t, self) 103 - } 104 - } 105 - 106 - impl<'a, 'tree> ser::Serialize for InContext<'a, Graph<'tree>> { 107 - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 108 - where 109 - S: serde::Serializer, 110 - { 111 - let graph = self.0; 112 - let ctx = self.1; 113 - let mut seq = serializer.serialize_seq(Some(graph.graph_nodes.len()))?; 114 - for (node_index, node) in graph.graph_nodes.iter().enumerate() { 115 - seq.serialize_element(&ctx.with(&(node_index, node)))?; 116 - } 117 - seq.end() 118 - } 119 - } 120 - 121 - impl<'a> ser::Serialize for InContext<'a, (usize, &'a GraphNode)> { 122 - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 123 - where 124 - S: serde::Serializer, 125 - { 126 - let node_index = self.0 .0; 127 - let node = self.0 .1; 128 - let ctx = self.1; 129 - // serializing as a map instead of a struct so we don't have to encode a struct name 130 - let mut map = serializer.serialize_map(None)?; 131 - map.serialize_entry("id", &node_index)?; 132 - map.serialize_entry("edges", &ctx.with(&node.outgoing_edges))?; 133 - map.serialize_entry("attrs", &ctx.with(&node.attributes))?; 134 - map.end() 135 - } 136 - } 137 - 138 - impl<'a> ser::Serialize for InContext<'a, SmallVec<[(GraphNodeID, Edge); 8]>> { 139 - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 140 - where 141 - S: serde::Serializer, 142 - { 143 - let elems = self.0; 144 - let ctx = self.1; 145 - let mut seq = serializer.serialize_seq(Some(elems.len()))?; 146 - for (_, (id, edge)) in elems.iter().enumerate() { 147 - seq.serialize_element(&ctx.with(&(id, edge)))?; 148 - } 149 - seq.end() 150 - } 151 - } 152 - 153 - impl<'a> ser::Serialize for InContext<'a, (&'a GraphNodeID, &'a Edge)> { 154 - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 155 - where 156 - S: serde::Serializer, 157 - { 158 - let sink = self.0 .0; 159 - let edge = self.0 .1; 160 - let ctx = self.1; 161 - let mut map = serializer.serialize_map(None)?; 162 - map.serialize_entry("sink", &sink)?; 163 - map.serialize_entry("attrs", &ctx.with(&edge.attributes))?; 164 - map.end() 165 - } 166 - } 167 - 168 - impl<'a> ser::Serialize for InContext<'a, Attributes> { 169 - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 170 - where 171 - S: serde::Serializer, 172 - { 173 - let attrs = self.0; 174 - let ctx = self.1; 175 - let mut map = serializer.serialize_map(None)?; 176 - for (_, (key, value)) in attrs.values.iter().enumerate() { 177 - map.serialize_entry(&ctx.with(key), &ctx.with(value))?; 178 - } 179 - map.end() 180 - } 181 - } 182 - 183 - impl<'a> ser::Serialize for InContext<'a, Identifier> { 184 - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 185 - where 186 - S: serde::Serializer, 187 - { 188 - let identifier = self.0; 189 - let ctx = self.1; 190 - let symbol = ctx.identifiers.resolve(identifier.0).unwrap(); 191 - serializer.serialize_str(symbol) 192 - } 193 - } 194 - 195 - impl<'a> ser::Serialize for InContext<'a, Value> { 196 - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 197 - where 198 - S: serde::Serializer, 199 - { 200 - let value = self.0; 201 - let ctx = self.1; 202 - match value { 203 - Value::Null => serializer.serialize_none(), 204 - Value::Boolean(bool) => serializer.serialize_bool(*bool), 205 - Value::Integer(integer) => serializer.serialize_u32(*integer), 206 - Value::String(string) => serializer.serialize_str(string), 207 - // FIXME: there's no way to distinguish sets and lists, so we can't roundtrip accurately 208 - Value::List(list) => { 209 - serializer.collect_seq(list.iter().map(|value| ctx.with(value))) 210 - } 211 - Value::Set(set) => { 212 - serializer.collect_seq(set.iter().map(|value| ctx.with(value))) 213 - } 214 - // FIXME: we don't distinguish between syntax tree node IDs, graph node IDs, and integers 215 - Value::SyntaxNode(node) => serializer.serialize_u32(node.0), 216 - Value::GraphNode(node) => serializer.serialize_u32(node.0), 217 - } 218 - } 219 - } 220 - 221 - let json_graph = ctx.with(self); 222 - let s = serde_json::to_string_pretty(&json_graph).unwrap(); 90 + pub fn display_json(&self) { 91 + let s = serde_json::to_string_pretty(self).unwrap(); 223 92 print!("{}", s) 224 93 } 225 94 ··· 236 105 237 106 impl<'tree> Index<SyntaxNodeRef> for Graph<'tree> { 238 107 type Output = Node<'tree>; 239 - fn index(&self, index: SyntaxNodeRef) -> &Node<'tree> { 240 - &self.syntax_nodes[&index] 108 + fn index(&self, node_ref: SyntaxNodeRef) -> &Node<'tree> { 109 + &self.syntax_nodes[&node_ref.index] 241 110 } 242 111 } 243 112 ··· 251 120 impl<'tree> IndexMut<GraphNodeRef> for Graph<'_> { 252 121 fn index_mut(&mut self, index: GraphNodeRef) -> &mut GraphNode { 253 122 &mut self.graph_nodes[index.0 as usize] 123 + } 124 + } 125 + 126 + impl<'tree> Serialize for Graph<'tree> { 127 + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 128 + let mut seq = serializer.serialize_seq(Some(self.graph_nodes.len()))?; 129 + for (node_index, node) in self.graph_nodes.iter().enumerate() { 130 + seq.serialize_element(&SerializeGraphNode(node_index, node))?; 131 + } 132 + seq.end() 254 133 } 255 134 } 256 135 ··· 317 196 } 318 197 } 319 198 199 + struct SerializeGraphNode<'a>(usize, &'a GraphNode); 200 + 201 + impl<'a> Serialize for SerializeGraphNode<'a> { 202 + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 203 + let node_index = self.0; 204 + let node = self.1; 205 + // serializing as a map instead of a struct so we don't have to encode a struct name 206 + let mut map = serializer.serialize_map(None)?; 207 + map.serialize_entry("id", &node_index)?; 208 + map.serialize_entry("edges", &SerializeGraphNodeEdges(&node.outgoing_edges))?; 209 + map.serialize_entry("attrs", &node.attributes)?; 210 + map.end() 211 + } 212 + } 213 + 214 + struct SerializeGraphNodeEdges<'a>(&'a SmallVec<[(GraphNodeID, Edge); 8]>); 215 + 216 + impl<'a> Serialize for SerializeGraphNodeEdges<'a> { 217 + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 218 + let edges = self.0; 219 + let mut seq = serializer.serialize_seq(Some(edges.len()))?; 220 + for element in edges { 221 + seq.serialize_element(&SerializeGraphNodeEdge(&element))?; 222 + } 223 + seq.end() 224 + } 225 + } 226 + 227 + struct SerializeGraphNodeEdge<'a>(&'a (GraphNodeID, Edge)); 228 + 229 + impl<'a> Serialize for SerializeGraphNodeEdge<'a> { 230 + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 231 + let wrapped = &self.0; 232 + let sink = &wrapped.0; 233 + let edge = &wrapped.1; 234 + let mut map = serializer.serialize_map(None)?; 235 + map.serialize_entry("sink", sink)?; 236 + map.serialize_entry("attrs", &edge.attributes)?; 237 + map.end() 238 + } 239 + } 240 + 320 241 /// An edge between two nodes in a graph 321 242 pub struct Edge { 322 243 /// The set of attributes associated with this edge ··· 360 281 } 361 282 362 283 /// Returns the value of a particular attribute, if it exists. 363 - pub fn get(&self, name: Identifier) -> Option<&Value> { 364 - self.values.get(&name) 284 + pub fn get<Q>(&self, name: &Q) -> Option<&Value> 285 + where 286 + Q: ?Sized + Eq + Hash, 287 + Identifier: Borrow<Q>, 288 + { 289 + self.values.get(name.borrow()) 365 290 } 366 - 367 - /// fmt::Displays the contents of this attribute set. 368 - pub fn display_with<'a>( 369 - &'a self, 370 - ctx: &'a Context, 371 - graph: &'a Graph, 372 - ) -> impl fmt::Display + 'a { 373 - struct DisplayAttributes<'a, 'tree>(&'a Attributes, &'a Context, &'a Graph<'tree>); 374 - 375 - impl<'a, 'tree> fmt::Display for DisplayAttributes<'a, 'tree> { 376 - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 377 - let attributes = self.0; 378 - let ctx = self.1; 379 - let graph = self.2; 291 + } 380 292 381 - let mut keys = attributes 382 - .values 383 - .keys() 384 - .map(|k| (ctx.resolve(*k), k)) 385 - .collect::<Vec<_>>(); 386 - keys.sort_by(|a, b| a.0.cmp(b.0)); 387 - for (name, key) in &keys { 388 - let value = &attributes.values[key]; 389 - write!(f, " {}: {}\n", name, value.display_with(graph),)?; 390 - } 391 - Ok(()) 392 - } 293 + impl std::fmt::Display for Attributes { 294 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 295 + let mut keys = self.values.keys().collect::<Vec<_>>(); 296 + keys.sort_by(|a, b| a.cmp(b)); 297 + for key in &keys { 298 + let value = &self.values[*key]; 299 + write!(f, " {}: {}\n", key, value)?; 393 300 } 301 + Ok(()) 302 + } 303 + } 394 304 395 - DisplayAttributes(self, ctx, graph) 305 + impl Serialize for Attributes { 306 + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 307 + let mut map = serializer.serialize_map(None)?; 308 + for (key, value) in &self.values { 309 + map.serialize_entry(key, value)?; 310 + } 311 + map.end() 396 312 } 397 313 } 398 314 ··· 414 330 415 331 impl Value { 416 332 /// Check if this value is null 417 - pub fn is_null(self) -> bool { 333 + pub fn is_null(&self) -> bool { 418 334 match self { 419 335 Value::Null => true, 420 336 _ => false, 421 337 } 422 338 } 339 + 423 340 /// Coerces this value into a boolean, returning an error if it's some other type of value. 424 - pub fn into_bool(self, graph: &Graph) -> Result<bool, ExecutionError> { 341 + pub fn into_boolean(self) -> Result<bool, ExecutionError> { 425 342 match self { 426 343 Value::Boolean(value) => Ok(value), 427 - _ => Err(ExecutionError::ExpectedBoolean(format!( 428 - "got {}", 429 - self.display_with(graph) 430 - ))), 344 + _ => Err(ExecutionError::ExpectedBoolean(format!("got {}", self))), 431 345 } 432 346 } 433 347 434 - pub fn as_bool(&self, graph: &Graph) -> Result<bool, ExecutionError> { 348 + pub fn as_boolean(&self) -> Result<bool, ExecutionError> { 435 349 match self { 436 350 Value::Boolean(value) => Ok(*value), 437 - _ => Err(ExecutionError::ExpectedBoolean(format!( 438 - "got {}", 439 - self.display_with(graph) 440 - ))), 351 + _ => Err(ExecutionError::ExpectedBoolean(format!("got {}", self))), 441 352 } 442 353 } 443 354 444 355 /// Coerces this value into an integer, returning an error if it's some other type of value. 445 - pub fn into_integer(self, graph: &Graph) -> Result<u32, ExecutionError> { 356 + pub fn into_integer(self) -> Result<u32, ExecutionError> { 446 357 match self { 447 358 Value::Integer(value) => Ok(value), 448 - _ => Err(ExecutionError::ExpectedInteger(format!( 449 - "got {}", 450 - self.display_with(graph) 451 - ))), 359 + _ => Err(ExecutionError::ExpectedInteger(format!("got {}", self))), 452 360 } 453 361 } 454 362 455 - pub fn as_integer(&self, graph: &Graph) -> Result<u32, ExecutionError> { 363 + pub fn as_integer(&self) -> Result<u32, ExecutionError> { 456 364 match self { 457 365 Value::Integer(value) => Ok(*value), 458 - _ => Err(ExecutionError::ExpectedInteger(format!( 459 - "got {}", 460 - self.display_with(graph) 461 - ))), 366 + _ => Err(ExecutionError::ExpectedInteger(format!("got {}", self))), 462 367 } 463 368 } 464 369 465 370 /// Coerces this value into a string, returning an error if it's some other type of value. 466 - pub fn into_string(self, graph: &Graph) -> Result<String, ExecutionError> { 371 + pub fn into_string(self) -> Result<String, ExecutionError> { 467 372 match self { 468 373 Value::String(value) => Ok(value), 469 - _ => Err(ExecutionError::ExpectedString(format!( 470 - "got {}", 471 - self.display_with(graph) 472 - ))), 374 + _ => Err(ExecutionError::ExpectedString(format!("got {}", self))), 473 375 } 474 376 } 475 377 476 - pub fn as_string(&self, graph: &Graph) -> Result<&str, ExecutionError> { 378 + pub fn as_str(&self) -> Result<&str, ExecutionError> { 477 379 match self { 478 380 Value::String(value) => Ok(value), 479 - _ => Err(ExecutionError::ExpectedString(format!( 480 - "got {}", 481 - self.display_with(graph) 482 - ))), 381 + _ => Err(ExecutionError::ExpectedString(format!("got {}", self))), 483 382 } 484 383 } 485 384 486 385 /// Coerces this value into a list, returning an error if it's some other type of value. 487 - pub fn into_list(self, graph: &Graph) -> Result<Vec<Value>, ExecutionError> { 386 + pub fn into_list(self) -> Result<Vec<Value>, ExecutionError> { 488 387 match self { 489 388 Value::List(values) => Ok(values), 490 - _ => Err(ExecutionError::ExpectedList(format!( 491 - "got {}", 492 - self.display_with(graph) 493 - ))), 389 + _ => Err(ExecutionError::ExpectedList(format!("got {}", self))), 494 390 } 495 391 } 496 392 497 - pub fn as_list(&self, graph: &Graph) -> Result<&Vec<Value>, ExecutionError> { 393 + pub fn as_list(&self) -> Result<&Vec<Value>, ExecutionError> { 498 394 match self { 499 395 Value::List(values) => Ok(values), 500 - _ => Err(ExecutionError::ExpectedList(format!( 501 - "got {}", 502 - self.display_with(graph) 503 - ))), 396 + _ => Err(ExecutionError::ExpectedList(format!("got {}", self))), 504 397 } 505 398 } 506 399 507 400 /// Coerces this value into a graph node reference, returning an error if it's some other type 508 401 /// of value. 509 - pub fn into_graph_node_ref<'a, 'tree>( 510 - self, 511 - graph: &'a Graph<'tree>, 512 - ) -> Result<GraphNodeRef, ExecutionError> { 402 + pub fn into_graph_node_ref<'a, 'tree>(self) -> Result<GraphNodeRef, ExecutionError> { 513 403 match self { 514 404 Value::GraphNode(node) => Ok(node), 515 - _ => Err(ExecutionError::ExpectedGraphNode(format!( 516 - "got {}", 517 - self.display_with(graph) 518 - ))), 405 + _ => Err(ExecutionError::ExpectedGraphNode(format!("got {}", self))), 519 406 } 520 407 } 521 408 522 - pub fn as_graph_node_ref<'a, 'tree>( 523 - &self, 524 - graph: &'a Graph<'tree>, 525 - ) -> Result<GraphNodeRef, ExecutionError> { 409 + pub fn as_graph_node_ref<'a, 'tree>(&self) -> Result<GraphNodeRef, ExecutionError> { 526 410 match self { 527 411 Value::GraphNode(node) => Ok(*node), 528 - _ => Err(ExecutionError::ExpectedGraphNode(format!( 529 - "got {}", 530 - self.display_with(graph) 531 - ))), 412 + _ => Err(ExecutionError::ExpectedGraphNode(format!("got {}", self))), 532 413 } 533 414 } 534 415 535 416 /// Coerces this value into a syntax node reference, returning an error if it's some other type 536 417 /// of value. 537 - pub fn into_syntax_node_ref<'a, 'tree>( 538 - self, 539 - graph: &'a Graph<'tree>, 540 - ) -> Result<SyntaxNodeRef, ExecutionError> { 418 + pub fn into_syntax_node_ref<'a, 'tree>(self) -> Result<SyntaxNodeRef, ExecutionError> { 541 419 match self { 542 420 Value::SyntaxNode(node) => Ok(node), 543 - _ => Err(ExecutionError::ExpectedSyntaxNode(format!( 544 - "got {}", 545 - self.display_with(graph) 546 - ))), 421 + _ => Err(ExecutionError::ExpectedSyntaxNode(format!("got {}", self))), 547 422 } 548 423 } 549 424 ··· 554 429 self, 555 430 graph: &'a Graph<'tree>, 556 431 ) -> Result<&'a Node<'tree>, ExecutionError> { 557 - Ok(&graph[self.into_syntax_node_ref(graph)?]) 432 + Ok(&graph[self.into_syntax_node_ref()?]) 558 433 } 559 434 560 - pub fn as_syntax_node_ref<'a, 'tree>( 561 - &self, 562 - graph: &'a Graph<'tree>, 563 - ) -> Result<SyntaxNodeRef, ExecutionError> { 435 + pub fn as_syntax_node_ref<'a, 'tree>(&self) -> Result<SyntaxNodeRef, ExecutionError> { 564 436 match self { 565 437 Value::SyntaxNode(node) => Ok(*node), 566 - _ => Err(ExecutionError::ExpectedSyntaxNode(format!( 567 - "got {}", 568 - self.display_with(graph) 569 - ))), 438 + _ => Err(ExecutionError::ExpectedSyntaxNode(format!("got {}", self))), 570 439 } 571 440 } 572 441 } ··· 601 470 } 602 471 } 603 472 604 - impl DisplayWithGraph for Value { 605 - fn fmt(&self, f: &mut fmt::Formatter, graph: &Graph) -> fmt::Result { 473 + impl std::fmt::Display for Value { 474 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 606 475 match self { 607 476 Value::Null => write!(f, "#null"), 608 477 Value::Boolean(value) => { ··· 619 488 let mut first = true; 620 489 for element in value { 621 490 if first { 622 - write!(f, "{}", element.display_with(graph))?; 491 + write!(f, "{}", element)?; 623 492 first = false; 624 493 } else { 625 - write!(f, ", {}", element.display_with(graph))?; 494 + write!(f, ", {}", element)?; 626 495 } 627 496 } 628 497 write!(f, "]") ··· 632 501 let mut first = true; 633 502 for element in value { 634 503 if first { 635 - write!(f, "{}", element.display_with(graph))?; 504 + write!(f, "{}", element)?; 636 505 first = false; 637 506 } else { 638 - write!(f, ", {}", element.display_with(graph))?; 507 + write!(f, ", {}", element)?; 639 508 } 640 509 } 641 510 write!(f, "}}") 642 511 } 643 - Value::SyntaxNode(node) => node.fmt(f, graph), 644 - Value::GraphNode(node) => node.fmt(f, graph), 512 + Value::SyntaxNode(node) => node.fmt(f), 513 + Value::GraphNode(node) => node.fmt(f), 514 + } 515 + } 516 + } 517 + 518 + impl Serialize for Value { 519 + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 520 + match self { 521 + Value::Null => serializer.serialize_none(), 522 + Value::Boolean(value) => serializer.serialize_bool(*value), 523 + Value::Integer(value) => serializer.serialize_u32(*value), 524 + Value::String(value) => serializer.serialize_str(value), 525 + // FIXME: there's no way to distinguish sets and lists, so we can't roundtrip accurately 526 + Value::List(list) => serializer.collect_seq(list), 527 + Value::Set(set) => serializer.collect_seq(set), 528 + // FIXME: we don't distinguish between syntax tree node IDs, graph node IDs, and integers 529 + Value::SyntaxNode(node) => serializer.serialize_u32(node.index), 530 + Value::GraphNode(node) => serializer.serialize_u32(node.0), 645 531 } 646 532 } 647 533 } 648 534 649 535 /// A reference to a syntax node in a graph 650 536 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 651 - pub struct SyntaxNodeRef(SyntaxNodeID); 537 + pub struct SyntaxNodeRef { 538 + index: SyntaxNodeID, 539 + kind: &'static str, 540 + position: tree_sitter::Point, 541 + } 652 542 653 543 impl From<SyntaxNodeRef> for Value { 654 544 fn from(value: SyntaxNodeRef) -> Value { ··· 656 546 } 657 547 } 658 548 659 - impl DisplayWithGraph for SyntaxNodeRef { 660 - fn fmt(&self, f: &mut fmt::Formatter, graph: &Graph) -> fmt::Result { 661 - let node = graph[*self]; 662 - write!(f, "{}", format_node(&node)) 549 + impl std::fmt::Display for SyntaxNodeRef { 550 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 551 + write!( 552 + f, 553 + "[syntax node {} ({}, {})]", 554 + self.kind, 555 + self.position.row + 1, 556 + self.position.column + 1, 557 + ) 663 558 } 664 559 } 665 560 666 - pub fn format_node(node: &Node) -> String { 667 - format!( 668 - "[syntax node {} ({}, {})]", 669 - node.kind(), 670 - node.start_position().row + 1, 671 - node.start_position().column + 1 672 - ) 673 - } 674 - 675 561 /// A reference to a graph node 676 562 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 677 563 pub struct GraphNodeRef(GraphNodeID); 678 564 565 + impl GraphNodeRef { 566 + /// Returns the index of the graph node that this reference refers to. 567 + pub fn index(self) -> usize { 568 + self.0 as usize 569 + } 570 + } 571 + 679 572 impl From<GraphNodeRef> for Value { 680 573 fn from(value: GraphNodeRef) -> Value { 681 574 Value::GraphNode(value) 682 575 } 683 576 } 684 577 685 - impl DisplayWithGraph for GraphNodeRef { 686 - fn fmt(&self, f: &mut fmt::Formatter, _graph: &Graph) -> fmt::Result { 578 + impl std::fmt::Display for GraphNodeRef { 579 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 687 580 write!(f, "[graph node {}]", self.0) 688 581 } 689 582 } 690 - 691 - /// Trait to Display with a given Context 692 - pub trait DisplayWithGraph 693 - where 694 - Self: Sized, 695 - { 696 - fn fmt<'tree>(&self, f: &mut fmt::Formatter, graph: &Graph<'tree>) -> fmt::Result; 697 - 698 - fn display_with<'a, 'tree>(&'a self, graph: &'a Graph<'tree>) -> Box<dyn fmt::Display + 'a> { 699 - struct Impl<'a, 'tree, T: DisplayWithGraph>(&'a T, &'a Graph<'tree>); 700 - 701 - impl<'a, 'tree, T: DisplayWithGraph> fmt::Display for Impl<'a, 'tree, T> { 702 - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 703 - self.0.fmt(f, self.1) 704 - } 705 - } 706 - 707 - Box::new(Impl(self, graph)) 708 - } 709 - }
+32 -104
src/lazy_execution.rs
··· 13 13 use log::{debug, trace}; 14 14 15 15 use std::collections::HashMap; 16 - use std::fmt; 17 16 18 17 use tree_sitter::CaptureQuantifier::One; 19 18 use tree_sitter::QueryCursor; ··· 25 24 use crate::execution::ExecutionError; 26 25 use crate::functions::Functions; 27 26 use crate::graph; 28 - use crate::graph::DisplayWithGraph as _; 29 27 use crate::graph::Graph; 30 28 use crate::variables::Globals; 31 29 use crate::variables::VariableMap; 32 30 use crate::variables::Variables; 33 - use crate::Context; 34 - use crate::DisplayWithContext as _; 35 31 use crate::Identifier; 36 32 37 33 use statements::*; ··· 44 40 /// provide the set of functions and global variables that are available during execution. 45 41 pub fn execute_lazy<'tree>( 46 42 &self, 47 - ctx: &Context, 48 43 tree: &'tree Tree, 49 44 source: &'tree str, 50 45 functions: &mut Functions, 51 46 globals: &Globals, 52 47 ) -> Result<Graph<'tree>, ExecutionError> { 53 48 let mut graph = Graph::new(); 54 - self.execute_lazy_into(ctx, &mut graph, tree, source, functions, globals)?; 49 + self.execute_lazy_into(&mut graph, tree, source, functions, globals)?; 55 50 Ok(graph) 56 51 } 57 52 ··· 62 57 /// “pre-seed” the graph with some predefined nodes and/or edges before executing the DSL file. 63 58 pub fn execute_lazy_into<'tree>( 64 59 &self, 65 - ctx: &Context, 66 60 graph: &mut Graph<'tree>, 67 61 tree: &'tree Tree, 68 62 source: &'tree str, ··· 85 79 for mat in matches { 86 80 let stanza = &self.stanzas[mat.pattern_index]; 87 81 stanza.execute_lazy( 88 - ctx, 89 82 source, 90 83 &mat, 91 84 graph, ··· 103 96 for graph_stmt in &lazy_graph { 104 97 graph_stmt 105 98 .evaluate(&mut EvaluationContext { 106 - ctx, 107 99 source, 108 100 graph, 109 101 functions, ··· 112 104 function_parameters: &mut function_parameters, 113 105 prev_element_debug_info: &mut prev_element_debug_info, 114 106 }) 115 - .with_context(|| format!("Executing {}", graph_stmt.display_with(ctx, &graph)))?; 107 + .with_context(|| format!("Executing {}", graph_stmt))?; 116 108 } 117 109 118 110 Ok(()) ··· 121 113 122 114 /// Context for execution, which executes stanzas to build the lazy graph 123 115 struct ExecutionContext<'a, 'g, 'tree> { 124 - ctx: &'a Context, 125 116 source: &'tree str, 126 117 graph: &'a mut Graph<'tree>, 127 118 functions: &'a mut Functions, ··· 138 129 139 130 /// Context for evaluation, which evalautes the lazy graph to build the actual graph 140 131 pub(self) struct EvaluationContext<'a, 'tree> { 141 - pub ctx: &'a Context, 142 132 pub source: &'tree str, 143 133 pub graph: &'a mut Graph<'tree>, 144 134 pub functions: &'a mut Functions, ··· 158 148 impl ast::Stanza { 159 149 fn execute_lazy<'l, 'g, 'q, 'tree>( 160 150 &self, 161 - ctx: &Context, 162 151 source: &'tree str, 163 152 mat: &QueryMatch<'_, 'tree>, 164 153 graph: &mut Graph<'tree>, ··· 174 163 let current_regex_captures = vec![]; 175 164 locals.clear(); 176 165 let mut exec = ExecutionContext { 177 - ctx, 178 166 source, 179 167 graph, 180 168 functions, ··· 189 177 prev_element_debug_info, 190 178 }; 191 179 let node = query_capture_value(self.full_match_file_capture_index, One, &mat, exec.graph); 192 - debug!( 193 - "match {} at {}", 194 - node.display_with(exec.graph), 195 - self.location 196 - ); 180 + debug!("match {} at {}", node, self.location); 197 181 trace!("{{"); 198 182 for statement in &self.statements { 199 183 statement 200 184 .execute_lazy(&mut exec) 201 - .with_context(|| format!("Executing {}", statement.display_with(exec.ctx)))?; 185 + .with_context(|| format!("Executing {}", statement))?; 202 186 } 203 187 trace!("}}"); 204 188 Ok(()) ··· 290 274 291 275 impl ast::Scan { 292 276 fn execute_lazy(&self, exec: &mut ExecutionContext) -> Result<(), ExecutionError> { 293 - let match_string = self.value.evaluate_eager(exec)?.into_string(exec.graph)?; 277 + let match_string = self.value.evaluate_eager(exec)?.into_string()?; 294 278 295 279 let mut i = 0; 296 280 let mut matches = Vec::new(); ··· 329 313 330 314 let mut arm_locals = VariableMap::new_child(exec.locals); 331 315 let mut arm_exec = ExecutionContext { 332 - ctx: exec.ctx, 333 316 source: exec.source, 334 317 graph: exec.graph, 335 318 functions: exec.functions, ··· 347 330 for statement in &arm.statements { 348 331 statement 349 332 .execute_lazy(&mut arm_exec) 350 - .with_context(|| format!("Executing {}", statement.display_with(arm_exec.ctx))) 333 + .with_context(|| format!("Executing {}", statement)) 351 334 .with_context(|| { 352 335 format!( 353 336 "Matching {} with arm \"{}\" {{ ... }}", ··· 390 373 if result { 391 374 let mut arm_locals = VariableMap::new_child(exec.locals); 392 375 let mut arm_exec = ExecutionContext { 393 - ctx: exec.ctx, 394 376 source: exec.source, 395 377 graph: exec.graph, 396 378 functions: exec.functions, ··· 421 403 match self { 422 404 Self::Some { value, .. } => Ok(!value.evaluate_eager(exec)?.is_null()), 423 405 Self::None { value, .. } => Ok(value.evaluate_eager(exec)?.is_null()), 424 - Self::Bool { value, .. } => Ok(value.evaluate_eager(exec)?.into_bool(exec.graph)?), 406 + Self::Bool { value, .. } => Ok(value.evaluate_eager(exec)?.into_boolean()?), 425 407 } 426 408 } 427 409 } 428 410 429 411 impl ast::ForIn { 430 412 fn execute_lazy(&self, exec: &mut ExecutionContext) -> Result<(), ExecutionError> { 431 - let values = self.value.evaluate_eager(exec)?.into_list(exec.graph)?; 413 + let values = self.value.evaluate_eager(exec)?.into_list()?; 432 414 let mut loop_locals = VariableMap::new_child(exec.locals); 433 415 for value in values { 434 416 loop_locals.clear(); 435 417 let mut loop_exec = ExecutionContext { 436 - ctx: exec.ctx, 437 418 source: exec.source, 438 419 graph: exec.graph, 439 420 functions: exec.functions, ··· 478 459 // only be called on expressions that are local (i.e., `is_local = true` in the checker). 479 460 fn evaluate_eager(&self, exec: &mut ExecutionContext) -> Result<graph::Value, ExecutionError> { 480 461 self.evaluate_lazy(exec)?.evaluate(&mut EvaluationContext { 481 - ctx: exec.ctx, 482 462 source: exec.source, 483 463 graph: exec.graph, 484 464 functions: exec.functions, ··· 540 520 for parameter in &self.parameters { 541 521 parameters.push(parameter.evaluate_lazy(exec)?); 542 522 } 543 - Ok(LazyCall::new(self.function, parameters).into()) 523 + Ok(LazyCall::new(self.function.clone(), parameters).into()) 544 524 } 545 525 } 546 526 ··· 588 568 impl ast::ScopedVariable { 589 569 fn evaluate_lazy(&self, exec: &mut ExecutionContext) -> Result<LazyValue, ExecutionError> { 590 570 let scope = self.scope.evaluate_lazy(exec)?; 591 - let value = LazyScopedVariable::new(scope, self.name); 571 + let value = LazyScopedVariable::new(scope, self.name.clone()); 592 572 Ok(value.into()) 593 573 } 594 574 ··· 601 581 if mutable { 602 582 return Err(ExecutionError::CannotDefineMutableScopedVariable(format!( 603 583 "{}", 604 - self.display_with(exec.ctx) 584 + self 605 585 ))); 606 586 } 607 587 let scope = self.scope.evaluate_lazy(exec)?; 608 - let variable = exec 609 - .store 610 - .add(value, self.location.into(), exec.ctx, exec.graph); 588 + let variable = exec.store.add(value, self.location.into()); 611 589 exec.scoped_store.add( 612 590 scope, 613 - self.name, 591 + self.name.clone(), 614 592 variable.into(), 615 593 self.location.into(), 616 - exec.ctx, 617 594 ) 618 595 } 619 596 620 597 fn set_lazy( 621 598 &self, 622 - exec: &mut ExecutionContext, 599 + _exec: &mut ExecutionContext, 623 600 _value: LazyValue, 624 601 ) -> Result<(), ExecutionError> { 625 602 Err(ExecutionError::CannotAssignScopedVariable(format!( 626 603 "{}", 627 - self.display_with(exec.ctx) 604 + self 628 605 ))) 629 606 } 630 607 } ··· 636 613 } else { 637 614 exec.locals.get(&self.name).map(|value| value.clone()) 638 615 } 639 - .ok_or_else(|| { 640 - ExecutionError::UndefinedVariable(format!("{}", self.display_with(exec.ctx))) 641 - }) 616 + .ok_or_else(|| ExecutionError::UndefinedVariable(format!("{}", self))) 642 617 } 643 618 } 644 619 ··· 652 627 if exec.globals.get(&self.name).is_some() { 653 628 return Err(ExecutionError::DuplicateVariable(format!( 654 629 " global {}", 655 - self.display_with(exec.ctx) 630 + self 656 631 ))); 657 632 } 658 - let value = exec 659 - .store 660 - .add(value, self.location.into(), exec.ctx, exec.graph); 633 + let value = exec.store.add(value, self.location.into()); 661 634 exec.locals 662 - .add(self.name, value.into(), mutable) 663 - .map_err(|_| { 664 - ExecutionError::DuplicateVariable(format!(" local {}", self.display_with(exec.ctx))) 665 - }) 635 + .add(self.name.clone(), value.into(), mutable) 636 + .map_err(|_| ExecutionError::DuplicateVariable(format!(" local {}", self))) 666 637 } 667 638 668 639 fn set_lazy( ··· 673 644 if exec.globals.get(&self.name).is_some() { 674 645 return Err(ExecutionError::CannotAssignImmutableVariable(format!( 675 646 " global {}", 676 - self.display_with(exec.ctx) 647 + self 677 648 ))); 678 649 } 679 - let value = exec 680 - .store 681 - .add(value, self.location.into(), exec.ctx, exec.graph); 682 - exec.locals.set(self.name, value.into()).map_err(|_| { 683 - if exec.locals.get(&self.name).is_some() { 684 - ExecutionError::CannotAssignImmutableVariable(format!( 685 - "{}", 686 - self.display_with(exec.ctx) 687 - )) 688 - } else { 689 - ExecutionError::UndefinedVariable(format!("{}", self.display_with(exec.ctx))) 690 - } 691 - }) 650 + let value = exec.store.add(value, self.location.into()); 651 + exec.locals 652 + .set(self.name.clone(), value.into()) 653 + .map_err(|_| { 654 + if exec.locals.get(&self.name).is_some() { 655 + ExecutionError::CannotAssignImmutableVariable(format!("{}", self)) 656 + } else { 657 + ExecutionError::UndefinedVariable(format!("{}", self)) 658 + } 659 + }) 692 660 } 693 661 } 694 662 695 663 impl ast::Attribute { 696 664 fn evaluate_lazy(&self, exec: &mut ExecutionContext) -> Result<LazyAttribute, ExecutionError> { 697 665 let value = self.value.evaluate_lazy(exec)?; 698 - let attribute = LazyAttribute::new(self.name, value); 666 + let attribute = LazyAttribute::new(self.name.clone(), value); 699 667 Ok(attribute) 700 668 } 701 669 } 702 - 703 - /// Trait to Display with a given Context and Graph 704 - pub trait DisplayWithContextAndGraph 705 - where 706 - Self: Sized, 707 - { 708 - fn fmt<'tree>( 709 - &self, 710 - f: &mut fmt::Formatter, 711 - ctx: &Context, 712 - graph: &Graph<'tree>, 713 - ) -> fmt::Result; 714 - 715 - fn display_with<'a, 'tree>( 716 - &'a self, 717 - ctx: &'a Context, 718 - graph: &'a Graph<'tree>, 719 - ) -> Box<dyn fmt::Display + 'a> { 720 - struct Impl<'a, 'tree, T: DisplayWithContextAndGraph>(&'a T, &'a Context, &'a Graph<'tree>); 721 - 722 - impl<'a, 'tree, T: DisplayWithContextAndGraph> fmt::Display for Impl<'a, 'tree, T> { 723 - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 724 - self.0.fmt(f, self.1, self.2) 725 - } 726 - } 727 - 728 - Box::new(Impl(self, ctx, graph)) 729 - } 730 - } 731 - 732 - impl<T: DisplayWithContextAndGraph> DisplayWithContextAndGraph for Box<T> { 733 - fn fmt<'tree>( 734 - &self, 735 - f: &mut fmt::Formatter, 736 - ctx: &Context, 737 - graph: &Graph<'tree>, 738 - ) -> fmt::Result { 739 - self.as_ref().fmt(f, ctx, graph) 740 - } 741 - }
+45 -62
src/lazy_execution/statements.rs
··· 13 13 use std::fmt; 14 14 15 15 use crate::execution::ExecutionError; 16 - use crate::graph::DisplayWithGraph; 17 - use crate::graph::Graph; 18 - use crate::Context; 19 - use crate::DisplayWithContext as _; 20 16 use crate::Identifier; 21 17 22 18 use super::store::DebugInfo; 23 19 use super::values::*; 24 - use super::DisplayWithContextAndGraph; 25 20 use super::EvaluationContext; 26 21 use super::GraphElementKey; 27 22 ··· 36 31 37 32 impl LazyStatement { 38 33 pub(super) fn evaluate(&self, exec: &mut EvaluationContext) -> Result<(), ExecutionError> { 39 - debug!("eval {}", self.display_with(exec.ctx, exec.graph)); 34 + debug!("eval {}", self); 40 35 trace!("{{"); 41 36 let result = match self { 42 37 Self::AddGraphNodeAttribute(stmt) => stmt.evaluate(exec), ··· 73 68 } 74 69 } 75 70 76 - impl DisplayWithContextAndGraph for LazyStatement { 77 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 71 + impl fmt::Display for LazyStatement { 72 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 78 73 match self { 79 - Self::AddGraphNodeAttribute(stmt) => stmt.fmt(f, ctx, graph), 80 - Self::CreateEdge(stmt) => stmt.fmt(f, ctx, graph), 81 - Self::AddEdgeAttribute(stmt) => stmt.fmt(f, ctx, graph), 82 - Self::Print(stmt) => stmt.fmt(f, ctx, graph), 74 + Self::AddGraphNodeAttribute(stmt) => stmt.fmt(f), 75 + Self::CreateEdge(stmt) => stmt.fmt(f), 76 + Self::AddEdgeAttribute(stmt) => stmt.fmt(f), 77 + Self::Print(stmt) => stmt.fmt(f), 83 78 } 84 79 } 85 80 } ··· 110 105 for attribute in &self.attributes { 111 106 let value = attribute.value.evaluate(exec)?; 112 107 let prev_debug_info = exec.prev_element_debug_info.insert( 113 - GraphElementKey::NodeAttribute(node, attribute.name), 108 + GraphElementKey::NodeAttribute(node, attribute.name.clone()), 114 109 self.debug_info, 115 110 ); 116 111 exec.graph[node] 117 112 .attributes 118 - .add(attribute.name, value) 113 + .add(attribute.name.clone(), value) 119 114 .map_err(|_| { 120 115 ExecutionError::DuplicateAttribute(format!( 121 116 "{} on {} at {} and {}", 122 - attribute.name.display_with(exec.ctx), 123 - node.display_with(exec.graph), 117 + attribute.name, 118 + node, 124 119 prev_debug_info.unwrap(), 125 120 self.debug_info, 126 121 )) ··· 130 125 } 131 126 } 132 127 133 - impl DisplayWithContextAndGraph for LazyAddGraphNodeAttribute { 134 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 135 - write!(f, "attr ({})", self.node.display_with(ctx, graph))?; 128 + impl fmt::Display for LazyAddGraphNodeAttribute { 129 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 130 + write!(f, "attr ({})", self.node)?; 136 131 for attr in &self.attributes { 137 - write!(f, " {}", attr.display_with(ctx, graph))?; 132 + write!(f, " {}", attr)?; 138 133 } 139 134 write!(f, " at {}", self.debug_info) 140 135 } ··· 166 161 if let Err(_) = exec.graph[source].add_edge(sink) { 167 162 Err(ExecutionError::DuplicateEdge(format!( 168 163 "({} -> {}) at {} and {}", 169 - source.display_with(exec.graph), 170 - sink.display_with(exec.graph), 164 + source, 165 + sink, 171 166 prev_debug_info.unwrap(), 172 167 self.debug_info, 173 168 )))?; ··· 176 171 } 177 172 } 178 173 179 - impl DisplayWithContextAndGraph for LazyCreateEdge { 180 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 174 + impl fmt::Display for LazyCreateEdge { 175 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 181 176 write!( 182 177 f, 183 178 "edge {} -> {} at {}", 184 - self.source.display_with(ctx, graph), 185 - self.sink.display_with(ctx, graph), 186 - self.debug_info, 179 + self.source, self.sink, self.debug_info, 187 180 ) 188 181 } 189 182 } ··· 221 214 Some(edge) => Ok(edge), 222 215 None => Err(ExecutionError::UndefinedEdge(format!( 223 216 "({} -> {}) at {}", 224 - source.display_with(exec.graph), 225 - sink.display_with(exec.graph), 226 - self.debug_info, 217 + source, sink, self.debug_info, 227 218 ))), 228 219 }?; 229 220 let prev_debug_info = exec.prev_element_debug_info.insert( 230 - GraphElementKey::EdgeAttribute(source, sink, attribute.name), 221 + GraphElementKey::EdgeAttribute(source, sink, attribute.name.clone()), 231 222 self.debug_info, 232 223 ); 233 - edge.attributes.add(attribute.name, value).map_err(|_| { 234 - ExecutionError::DuplicateAttribute(format!( 235 - "{} on edge ({} -> {}) at {} and {}", 236 - attribute.name.display_with(exec.ctx), 237 - source.display_with(exec.graph), 238 - sink.display_with(exec.graph), 239 - prev_debug_info.unwrap(), 240 - self.debug_info, 241 - )) 242 - })?; 224 + edge.attributes 225 + .add(attribute.name.clone(), value) 226 + .map_err(|_| { 227 + ExecutionError::DuplicateAttribute(format!( 228 + "{} on edge ({} -> {}) at {} and {}", 229 + attribute.name, 230 + source, 231 + sink, 232 + prev_debug_info.unwrap(), 233 + self.debug_info, 234 + )) 235 + })?; 243 236 } 244 237 Ok(()) 245 238 } 246 239 } 247 240 248 - impl DisplayWithContextAndGraph for LazyAddEdgeAttribute { 249 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 250 - write!( 251 - f, 252 - "attr ({} -> {})", 253 - self.source.display_with(ctx, graph), 254 - self.sink.display_with(ctx, graph), 255 - )?; 241 + impl fmt::Display for LazyAddEdgeAttribute { 242 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 243 + write!(f, "attr ({} -> {})", self.source, self.sink,)?; 256 244 for attr in &self.attributes { 257 - write!(f, " {}", attr.display_with(ctx, graph),)?; 245 + write!(f, " {}", attr,)?; 258 246 } 259 247 write!(f, " at {}", self.debug_info) 260 248 } ··· 287 275 LazyPrintArgument::Text(string) => eprint!("{}", string), 288 276 LazyPrintArgument::Value(value) => { 289 277 let value = value.evaluate(exec)?; 290 - eprint!("{}", value.display_with(exec.graph)); 278 + eprint!("{}", value); 291 279 } 292 280 } 293 281 } ··· 296 284 } 297 285 } 298 286 299 - impl DisplayWithContextAndGraph for LazyPrint { 300 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 287 + impl fmt::Display for LazyPrint { 288 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 301 289 write!(f, "print")?; 302 290 let mut first = true; 303 291 for argument in &self.arguments { ··· 308 296 } 309 297 match argument { 310 298 LazyPrintArgument::Text(string) => write!(f, "\"{}\"", string)?, 311 - LazyPrintArgument::Value(value) => write!(f, "{}", value.display_with(ctx, graph))?, 299 + LazyPrintArgument::Value(value) => write!(f, "{}", value)?, 312 300 }; 313 301 } 314 302 write!(f, " at {}", self.debug_info) ··· 328 316 } 329 317 } 330 318 331 - impl DisplayWithContextAndGraph for LazyAttribute { 332 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 333 - write!( 334 - f, 335 - "{} = {}", 336 - self.name.display_with(ctx), 337 - self.value.display_with(ctx, graph), 338 - ) 319 + impl fmt::Display for LazyAttribute { 320 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 321 + write!(f, "{} = {}", self.name, self.value,) 339 322 } 340 323 }
+26 -53
src/lazy_execution/store.rs
··· 19 19 20 20 use crate::execution::ExecutionError; 21 21 use crate::graph; 22 - use crate::graph::DisplayWithGraph; 23 - use crate::graph::Graph; 24 22 use crate::graph::SyntaxNodeRef; 25 23 use crate::parser::Location; 26 - use crate::Context; 27 - use crate::DisplayWithContext; 28 24 use crate::Identifier; 29 25 30 26 use super::values::*; 31 - use super::DisplayWithContextAndGraph; 32 27 use super::EvaluationContext; 33 28 34 29 /// Variable that points to a thunk in the store ··· 50 45 } 51 46 } 52 47 53 - impl DisplayWithContextAndGraph for LazyVariable { 54 - fn fmt(&self, f: &mut fmt::Formatter, _ctx: &Context, _graph: &Graph) -> fmt::Result { 48 + impl fmt::Display for LazyVariable { 49 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 55 50 write!(f, "(load {})", self.store_location) 56 51 } 57 52 } ··· 69 64 } 70 65 } 71 66 72 - pub(super) fn add( 73 - &mut self, 74 - value: LazyValue, 75 - debug_info: DebugInfo, 76 - ctx: &Context, 77 - graph: &Graph, 78 - ) -> LazyVariable { 67 + pub(super) fn add(&mut self, value: LazyValue, debug_info: DebugInfo) -> LazyVariable { 79 68 let store_location = self.elements.len(); 80 69 let variable = LazyVariable::new(store_location); 81 - trace!( 82 - "store {} = {}", 83 - store_location, 84 - value.display_with(ctx, graph) 85 - ); 70 + trace!("store {} = {}", store_location, value); 86 71 self.elements.push(Thunk::new(value, debug_info)); 87 72 variable 88 73 } ··· 94 79 ) -> Result<graph::Value, ExecutionError> { 95 80 let variable = &self.elements[variable.store_location]; 96 81 let debug_info = variable.debug_info; 97 - let value = variable.force(exec).with_context(|| { 98 - format!( 99 - "via {} at {}", 100 - (*variable.state.borrow()).display_with(exec.ctx, exec.graph), 101 - debug_info 102 - ) 103 - })?; 82 + let value = variable 83 + .force(exec) 84 + .with_context(|| format!("via {} at {}", (*variable.state.borrow()), debug_info))?; 104 85 Ok(value) 105 86 } 106 87 } ··· 123 104 name: Identifier, 124 105 value: LazyValue, 125 106 debug_info: DebugInfo, 126 - ctx: &Context, 127 107 ) -> Result<(), ExecutionError> { 128 108 let values = self 129 109 .variables 130 - .entry(name) 110 + .entry(name.clone()) 131 111 .or_insert_with(|| Cell::new(ScopedValues::new())); 132 112 match values.replace(ScopedValues::Forcing) { 133 113 ScopedValues::Unforced(mut pairs) => { ··· 136 116 Ok(()) 137 117 } 138 118 ScopedValues::Forcing => Err(ExecutionError::RecursivelyDefinedScopedVariable( 139 - format!("{}", name.display_with(ctx)), 119 + format!("{}", name), 140 120 )), 141 121 ScopedValues::Forced(map) => { 142 122 values.replace(ScopedValues::Forced(map)); 143 123 Err(ExecutionError::VariableScopesAlreadyForced(format!( 144 124 "{}", 145 - name.display_with(ctx) 125 + name 146 126 ))) 147 127 } 148 128 } ··· 150 130 151 131 pub(super) fn evaluate( 152 132 &self, 153 - scope: SyntaxNodeRef, 154 - name: Identifier, 133 + scope: &SyntaxNodeRef, 134 + name: &Identifier, 155 135 exec: &mut EvaluationContext, 156 136 ) -> Result<LazyValue, ExecutionError> { 157 - let values = match self.variables.get(&name) { 137 + let values = match self.variables.get(name) { 158 138 Some(v) => v, 159 139 None => { 160 140 return Err(ExecutionError::UndefinedScopedVariable(format!( 161 141 "{}.{}", 162 - scope.display_with(exec.graph), 163 - name.display_with(exec.ctx), 142 + scope, name, 164 143 ))); 165 144 } 166 145 }; ··· 175 154 Some(_) => { 176 155 return Err(ExecutionError::DuplicateVariable(format!( 177 156 "{}.{} set at {} and {}", 178 - node.display_with(exec.graph), 179 - name.display_with(exec.ctx), 157 + node, 158 + name, 180 159 prev_debug_info.unwrap(), 181 160 debug_info, 182 161 ))); ··· 188 167 .get(&scope) 189 168 .ok_or(ExecutionError::UndefinedScopedVariable(format!( 190 169 "{}.{}", 191 - scope.display_with(exec.graph), 192 - name.display_with(exec.ctx), 170 + scope, name, 193 171 )))? 194 172 .clone(); 195 173 values.replace(ScopedValues::Forced(map)); 196 174 Ok(result) 197 175 } 198 - ScopedValues::Forcing => { 199 - Err(ExecutionError::RecursivelyDefinedScopedVariable(format!( 200 - "_.{} requested on {}", 201 - name.display_with(exec.ctx), 202 - scope.display_with(exec.graph) 203 - ))) 204 - } 176 + ScopedValues::Forcing => Err(ExecutionError::RecursivelyDefinedScopedVariable( 177 + format!("_.{} requested on {}", name, scope), 178 + )), 205 179 ScopedValues::Forced(map) => { 206 180 let result = map 207 181 .get(&scope) 208 182 .ok_or(ExecutionError::UndefinedScopedVariable(format!( 209 183 "{}.{}", 210 - scope.display_with(exec.graph), 211 - name.display_with(exec.ctx), 184 + scope, name, 212 185 )))? 213 186 .clone(); 214 187 values.replace(ScopedValues::Forced(map)); ··· 242 215 Forced(graph::Value), 243 216 } 244 217 245 - impl DisplayWithContextAndGraph for ThunkState { 246 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 218 + impl fmt::Display for ThunkState { 219 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 247 220 match self { 248 - Self::Unforced(value) => write!(f, "?{{{}}}", value.display_with(ctx, graph)), 221 + Self::Unforced(value) => write!(f, "?{{{}}}", value), 249 222 Self::Forcing => write!(f, "~{{?}}"), 250 - Self::Forced(value) => write!(f, "!{{{}}}", value.display_with(graph)), 223 + Self::Forced(value) => write!(f, "!{{{}}}", value), 251 224 } 252 225 } 253 226 } ··· 262 235 263 236 fn force(&self, exec: &mut EvaluationContext) -> Result<graph::Value, ExecutionError> { 264 237 let state = self.state.replace(ThunkState::Forcing); 265 - trace!("force {}", state.display_with(exec.ctx, exec.graph)); 238 + trace!("force {}", state); 266 239 let value = match state { 267 240 ThunkState::Unforced(value) => { 268 241 // it is important that we do not hold a borrow of self.forced_values when executing self.value.evaluate
+29 -51
src/lazy_execution/values.rs
··· 13 13 use std::fmt; 14 14 15 15 use crate::execution::ExecutionError; 16 - use crate::graph::DisplayWithGraph; 17 - use crate::graph::Graph; 18 16 use crate::graph::GraphNodeRef; 19 17 use crate::graph::SyntaxNodeRef; 20 18 use crate::graph::Value; 21 - use crate::Context; 22 - use crate::DisplayWithContext; 23 19 use crate::Identifier; 24 20 25 21 use super::store::*; 26 - use super::DisplayWithContextAndGraph; 27 22 use super::EvaluationContext; 28 23 29 24 /// Lazy values ··· 123 118 124 119 impl LazyValue { 125 120 pub(super) fn evaluate(&self, exec: &mut EvaluationContext) -> Result<Value, ExecutionError> { 126 - trace!("eval {} {{", self.display_with(exec.ctx, exec.graph)); 121 + trace!("eval {} {{", self); 127 122 let ret = match self { 128 123 Self::Value(value) => Ok(value.clone()), 129 124 Self::List(expr) => expr.evaluate(exec), ··· 132 127 Self::ScopedVariable(expr) => expr.evaluate(exec), 133 128 Self::Call(expr) => expr.evaluate(exec), 134 129 }?; 135 - trace!("}} = {}", ret.display_with(exec.graph)); 130 + trace!("}} = {}", ret); 136 131 Ok(ret) 137 132 } 138 133 ··· 143 138 let node = self.evaluate(exec)?; 144 139 match node { 145 140 Value::GraphNode(node) => Ok(node), 146 - _ => Err(ExecutionError::ExpectedGraphNode(format!( 147 - " got {}", 148 - node.display_with(exec.graph) 149 - ))), 141 + _ => Err(ExecutionError::ExpectedGraphNode(format!(" got {}", node))), 150 142 } 151 143 } 152 144 ··· 157 149 let node = self.evaluate(exec)?; 158 150 match node { 159 151 Value::SyntaxNode(node) => Ok(node), 160 - _ => Err(ExecutionError::ExpectedSyntaxNode(format!( 161 - " got {}", 162 - node.display_with(exec.graph) 163 - ))), 152 + _ => Err(ExecutionError::ExpectedSyntaxNode(format!(" got {}", node))), 164 153 } 165 154 } 166 155 } 167 156 168 - impl DisplayWithContextAndGraph for LazyValue { 169 - fn fmt<'tree>( 170 - &self, 171 - f: &mut fmt::Formatter, 172 - ctx: &Context, 173 - graph: &Graph<'tree>, 174 - ) -> fmt::Result { 157 + impl fmt::Display for LazyValue { 158 + fn fmt<'tree>(&self, f: &mut fmt::Formatter) -> fmt::Result { 175 159 match self { 176 - Self::Value(value) => write!(f, "{}", value.display_with(graph)), 177 - Self::List(expr) => expr.fmt(f, ctx, graph), 178 - Self::Set(expr) => expr.fmt(f, ctx, graph), 179 - Self::Variable(expr) => expr.fmt(f, ctx, graph), 180 - Self::ScopedVariable(expr) => expr.fmt(f, ctx, graph), 181 - Self::Call(expr) => expr.fmt(f, ctx, graph), 160 + Self::Value(value) => write!(f, "{}", value), 161 + Self::List(expr) => expr.fmt(f), 162 + Self::Set(expr) => expr.fmt(f), 163 + Self::Variable(expr) => expr.fmt(f), 164 + Self::ScopedVariable(expr) => expr.fmt(f), 165 + Self::Call(expr) => expr.fmt(f), 182 166 } 183 167 } 184 168 } ··· 201 185 fn resolve<'a>(&self, exec: &'a mut EvaluationContext) -> Result<LazyValue, ExecutionError> { 202 186 let scope = self.scope.as_ref().evaluate_as_syntax_node(exec)?; 203 187 let scoped_store = &exec.scoped_store; 204 - scoped_store.evaluate(scope, self.name, exec) 188 + scoped_store.evaluate(&scope, &self.name, exec) 205 189 } 206 190 207 191 pub(super) fn evaluate(&self, exec: &mut EvaluationContext) -> Result<Value, ExecutionError> { ··· 210 194 } 211 195 } 212 196 213 - impl DisplayWithContextAndGraph for LazyScopedVariable { 214 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 215 - write!( 216 - f, 217 - "(scoped {} '{})", 218 - self.scope.display_with(ctx, graph), 219 - self.name.display_with(ctx), 220 - ) 197 + impl fmt::Display for LazyScopedVariable { 198 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 199 + write!(f, "(scoped {} '{})", self.scope, self.name,) 221 200 } 222 201 } 223 202 ··· 242 221 } 243 222 } 244 223 245 - impl DisplayWithContextAndGraph for LazyList { 246 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 224 + impl fmt::Display for LazyList { 225 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 247 226 write!(f, "(list")?; 248 227 let mut first = true; 249 228 for elem in &self.elements { 250 229 if first { 251 230 first = false; 252 - write!(f, "{}", elem.display_with(ctx, graph))?; 231 + write!(f, "{}", elem)?; 253 232 } else { 254 - write!(f, " {}", elem.display_with(ctx, graph))?; 233 + write!(f, " {}", elem)?; 255 234 } 256 235 } 257 236 write!(f, ")") ··· 279 258 } 280 259 } 281 260 282 - impl DisplayWithContextAndGraph for LazySet { 283 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 261 + impl fmt::Display for LazySet { 262 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 284 263 write!(f, "(set")?; 285 264 let mut first = true; 286 265 for elem in &self.elements { 287 266 if first { 288 267 first = false; 289 - write!(f, "{}", elem.display_with(ctx, graph))?; 268 + write!(f, "{}", elem)?; 290 269 } else { 291 - write!(f, " {}", elem.display_with(ctx, graph))?; 270 + write!(f, " {}", elem)?; 292 271 } 293 272 } 294 273 write!(f, ")") ··· 317 296 } 318 297 319 298 exec.functions.call( 320 - exec.ctx, 321 - self.function, 299 + &self.function, 322 300 exec.graph, 323 301 exec.source, 324 302 &mut exec ··· 328 306 } 329 307 } 330 308 331 - impl DisplayWithContextAndGraph for LazyCall { 332 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context, graph: &Graph) -> fmt::Result { 333 - write!(f, "(call '{}", self.function.display_with(ctx))?; 309 + impl fmt::Display for LazyCall { 310 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 311 + write!(f, "(call '{}", self.function)?; 334 312 for arg in &self.arguments { 335 - write!(f, " {}", arg.display_with(ctx, graph))?; 313 + write!(f, " {}", arg)?; 336 314 } 337 315 write!(f, ")") 338 316 }
+47 -46
src/lib.rs
··· 42 42 pub use parser::Location; 43 43 pub use parser::ParseError; 44 44 45 - use string_interner::symbol::SymbolU32; 46 - use string_interner::StringInterner; 45 + use std::borrow::Borrow; 46 + use std::hash::Hash; 47 + use std::ops::Deref; 48 + use std::rc::Rc; 47 49 48 - use std::fmt; 50 + use serde::Serialize; 51 + use serde::Serializer; 49 52 50 53 /// An identifier that appears in a graph DSL file or in the graph that is produced as an output. 51 - #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 52 - pub struct Identifier(SymbolU32); 54 + #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] 55 + pub struct Identifier(Rc<String>); 53 56 54 - impl DisplayWithContext for Identifier { 55 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 56 - write!(f, "{}", ctx.identifiers.resolve(self.0).unwrap()) 57 + impl Identifier { 58 + pub fn as_str(&self) -> &str { 59 + self.0.as_str() 60 + } 61 + 62 + pub fn into_string(mut self) -> String { 63 + Rc::make_mut(&mut self.0); 64 + Rc::try_unwrap(self.0).unwrap() 57 65 } 58 66 } 59 67 60 - /// A context in which graph DSL files are executed. 61 - #[derive(Default)] 62 - pub struct Context { 63 - identifiers: StringInterner, 68 + impl Borrow<str> for Identifier { 69 + fn borrow(&self) -> &str { 70 + self.as_str() 71 + } 64 72 } 65 73 66 - impl Context { 67 - /// Creates a new, empty execution context. 68 - pub fn new() -> Context { 69 - Context::default() 74 + impl Deref for Identifier { 75 + type Target = str; 76 + fn deref(&self) -> &str { 77 + self.as_str() 70 78 } 79 + } 71 80 72 - /// Adds an identifier to the context. 73 - #[inline(always)] 74 - pub fn add_identifier<T: AsRef<str>>(&mut self, identifier: T) -> Identifier { 75 - Identifier(self.identifiers.get_or_intern(identifier)) 81 + impl std::fmt::Display for Identifier { 82 + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 83 + self.0.fmt(f) 76 84 } 85 + } 77 86 78 - /// Returns the [`Identifier`][] instance for an identifier, if it has already been added to 79 - /// the context. Returns `None` otherwise. 80 - #[inline(always)] 81 - pub fn get_identifier<T: AsRef<str>>(&self, identifier: T) -> Option<Identifier> { 82 - self.identifiers.get(identifier).map(Identifier) 87 + impl From<&str> for Identifier { 88 + fn from(value: &str) -> Identifier { 89 + Identifier(Rc::new(String::from(value))) 83 90 } 91 + } 84 92 85 - pub fn resolve(&self, identifier: Identifier) -> &str { 86 - self.identifiers.resolve(identifier.0).unwrap() 93 + impl Hash for Identifier { 94 + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { 95 + self.0.hash(state); 87 96 } 88 97 } 89 98 90 - /// Trait to Display with a given Context 91 - pub trait DisplayWithContext 92 - where 93 - Self: Sized, 94 - { 95 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result; 96 - 97 - fn display_with<'a>(&'a self, ctx: &'a Context) -> Box<dyn fmt::Display + 'a> { 98 - struct Impl<'a, T: DisplayWithContext>(&'a T, &'a Context); 99 + impl PartialEq<str> for Identifier { 100 + fn eq(&self, other: &str) -> bool { 101 + self.as_str() == other 102 + } 103 + } 99 104 100 - impl<'a, T: DisplayWithContext> fmt::Display for Impl<'a, T> { 101 - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 102 - self.0.fmt(f, self.1) 103 - } 104 - } 105 - 106 - Box::new(Impl(self, ctx)) 105 + impl<'a> PartialEq<&'a str> for Identifier { 106 + fn eq(&self, other: &&'a str) -> bool { 107 + self.as_str() == *other 107 108 } 108 109 } 109 110 110 - impl<T: DisplayWithContext> DisplayWithContext for Box<T> { 111 - fn fmt(&self, f: &mut fmt::Formatter, ctx: &Context) -> fmt::Result { 112 - self.as_ref().fmt(f, ctx) 111 + impl Serialize for Identifier { 112 + fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 113 + serializer.serialize_str(self.as_str()) 113 114 } 114 115 }
+50 -83
src/parser.rs
··· 17 17 use tree_sitter::QueryError; 18 18 19 19 use crate::ast; 20 - use crate::Context; 21 20 use crate::Identifier; 22 21 23 22 pub const FULL_MATCH: &str = "__tsg__full_match"; 24 23 25 24 impl ast::File { 26 25 /// Parses a graph DSL file, returning a new `File` instance. 27 - pub fn from_str( 28 - language: Language, 29 - ctx: &mut Context, 30 - source: &str, 31 - ) -> Result<Self, ParseError> { 26 + pub fn from_str(language: Language, source: &str) -> Result<Self, ParseError> { 32 27 let mut file = ast::File::new(language); 33 28 #[allow(deprecated)] 34 - file.parse(ctx, source)?; 35 - file.check(ctx)?; 29 + file.parse(source)?; 30 + file.check()?; 36 31 Ok(file) 37 32 } 38 33 ··· 40 35 #[deprecated( 41 36 note = "Parsing multiple times into the same `File` instance is unsound. Use `File::from_str` instead." 42 37 )] 43 - pub fn parse(&mut self, ctx: &mut Context, content: &str) -> Result<(), ParseError> { 44 - Parser::new(ctx, content).parse_into_file(self) 38 + pub fn parse(&mut self, content: &str) -> Result<(), ParseError> { 39 + Parser::new(content).parse_into_file(self) 45 40 } 46 41 } 47 42 ··· 72 67 UnexpectedLiteral(String, Location), 73 68 #[error(transparent)] 74 69 Check(#[from] crate::checker::CheckError), 70 + #[error(transparent)] 71 + Other(#[from] anyhow::Error), 72 + } 73 + 74 + impl ParseError { 75 + /// Wraps an existing [`std::error::Error`][] as an execution error 76 + pub fn other<E>(err: E) -> ParseError 77 + where 78 + E: Into<anyhow::Error>, 79 + { 80 + Self::Other(err.into()) 81 + } 75 82 } 76 83 77 84 /// The location of a graph DSL entity within its file ··· 99 106 } 100 107 101 108 struct Parser<'a> { 102 - ctx: &'a mut Context, 103 109 source: &'a str, 104 110 chars: Peekable<Chars<'a>>, 105 111 offset: usize, 106 112 location: Location, 107 113 query_source: String, 108 - // Keywords 109 - attr_keyword: Identifier, 110 - edge_keyword: Identifier, 111 - false_keyword: Identifier, 112 - for_keyword: Identifier, 113 - if_keyword: Identifier, 114 - let_keyword: Identifier, 115 - node_keyword: Identifier, 116 - null_keyword: Identifier, 117 - print_keyword: Identifier, 118 - scan_keyword: Identifier, 119 - set_keyword: Identifier, 120 - true_keyword: Identifier, 121 - var_keyword: Identifier, 122 114 } 123 115 124 116 fn is_ident_start(c: char) -> bool { ··· 130 122 } 131 123 132 124 impl<'a> Parser<'a> { 133 - fn new(ctx: &'a mut Context, source: &'a str) -> Parser<'a> { 125 + fn new(source: &'a str) -> Parser<'a> { 134 126 let chars = source.chars().peekable(); 135 127 let query_source = String::with_capacity(source.len()); 136 - // Keywords 137 - let attr_keyword = ctx.add_identifier("attr"); 138 - let edge_keyword = ctx.add_identifier("edge"); 139 - let false_keyword = ctx.add_identifier("false"); 140 - let for_keyword = ctx.add_identifier("for"); 141 - let if_keyword = ctx.add_identifier("if"); 142 - let let_keyword = ctx.add_identifier("let"); 143 - let node_keyword = ctx.add_identifier("node"); 144 - let null_keyword = ctx.add_identifier("null"); 145 - let print_keyword = ctx.add_identifier("print"); 146 - let scan_keyword = ctx.add_identifier("scan"); 147 - let set_keyword = ctx.add_identifier("set"); 148 - let true_keyword = ctx.add_identifier("true"); 149 - let var_keyword = ctx.add_identifier("var"); 150 128 Parser { 151 - ctx, 152 129 source, 153 130 chars, 154 131 offset: 0, 155 132 location: Location::default(), 156 133 query_source, 157 - // Keywords 158 - attr_keyword, 159 - edge_keyword, 160 - false_keyword, 161 - for_keyword, 162 - let_keyword, 163 - if_keyword, 164 - node_keyword, 165 - null_keyword, 166 - print_keyword, 167 - scan_keyword, 168 - set_keyword, 169 - true_keyword, 170 - var_keyword, 171 134 } 172 135 } 173 136 } 174 137 175 - impl Parser<'_> { 138 + impl<'a> Parser<'a> { 176 139 fn peek(&mut self) -> Result<char, ParseError> { 177 140 self.chars 178 141 .peek() ··· 331 294 Ok(statements) 332 295 } 333 296 297 + fn parse_name(&mut self, within: &'static str) -> Result<&'a str, ParseError> { 298 + let start = self.offset; 299 + let ch = self.next()?; 300 + if !is_ident_start(ch) { 301 + return Err(ParseError::UnexpectedCharacter(ch, within, self.location)); 302 + } 303 + self.consume_while(is_ident); 304 + let end = self.offset; 305 + Ok(&self.source[start..end]) 306 + } 307 + 334 308 fn parse_statement(&mut self) -> Result<ast::Statement, ParseError> { 335 309 let keyword_location = self.location; 336 - let keyword = self.parse_identifier("keyword")?; 310 + let keyword = self.parse_name("keyword")?; 337 311 self.consume_whitespace(); 338 - if keyword == self.let_keyword { 312 + if keyword == "let" { 339 313 let variable = self.parse_variable()?; 340 314 self.consume_whitespace(); 341 315 self.consume_token("=")?; ··· 347 321 location: keyword_location, 348 322 } 349 323 .into()) 350 - } else if keyword == self.var_keyword { 324 + } else if keyword == "var" { 351 325 let variable = self.parse_variable()?; 352 326 self.consume_whitespace(); 353 327 self.consume_token("=")?; ··· 359 333 location: keyword_location, 360 334 } 361 335 .into()) 362 - } else if keyword == self.set_keyword { 336 + } else if keyword == "set" { 363 337 let variable = self.parse_variable()?; 364 338 self.consume_whitespace(); 365 339 self.consume_token("=")?; ··· 371 345 location: keyword_location, 372 346 } 373 347 .into()) 374 - } else if keyword == self.node_keyword { 348 + } else if keyword == "node" { 375 349 let node = self.parse_variable()?; 376 350 Ok(ast::CreateGraphNode { 377 351 node, 378 352 location: keyword_location, 379 353 } 380 354 .into()) 381 - } else if keyword == self.edge_keyword { 355 + } else if keyword == "edge" { 382 356 let source = self.parse_expression()?; 383 357 self.consume_whitespace(); 384 358 self.consume_token("->")?; ··· 390 364 location: keyword_location, 391 365 } 392 366 .into()) 393 - } else if keyword == self.attr_keyword { 367 + } else if keyword == "attr" { 394 368 self.consume_token("(")?; 395 369 self.consume_whitespace(); 396 370 let node_or_source = self.parse_expression()?; ··· 425 399 } 426 400 .into()) 427 401 } 428 - } else if keyword == self.print_keyword { 402 + } else if keyword == "print" { 429 403 let mut values = vec![self.parse_expression()?]; 430 404 self.consume_whitespace(); 431 405 while self.try_peek() == Some(',') { ··· 440 414 location: keyword_location, 441 415 } 442 416 .into()) 443 - } else if keyword == self.scan_keyword { 417 + } else if keyword == "scan" { 444 418 let value = self.parse_expression()?; 445 419 self.consume_whitespace(); 446 420 self.consume_token("{")?; ··· 467 441 location: keyword_location, 468 442 } 469 443 .into()) 470 - } else if keyword == self.if_keyword { 444 + } else if keyword == "if" { 471 445 let mut arms = Vec::new(); 472 446 473 447 // if ··· 520 494 location: keyword_location, 521 495 } 522 496 .into()) 523 - } else if keyword == self.for_keyword { 497 + } else if keyword == "for" { 524 498 self.consume_whitespace(); 525 499 let variable = match self.parse_variable()? { 526 500 ast::Variable::Unscoped(variable) => Ok(variable), ··· 543 517 .into()) 544 518 } else { 545 519 Err(ParseError::UnexpectedKeyword( 546 - self.ctx.resolve(keyword).into(), 520 + keyword.into(), 547 521 keyword_location, 548 522 )) 549 523 } ··· 590 564 } 591 565 592 566 fn parse_identifier(&mut self, within: &'static str) -> Result<Identifier, ParseError> { 593 - let start = self.offset; 594 - let ch = self.next()?; 595 - if !is_ident_start(ch) { 596 - return Err(ParseError::UnexpectedCharacter(ch, within, self.location)); 597 - } 598 - self.consume_while(is_ident); 599 - let end = self.offset; 600 - Ok(self.ctx.add_identifier(&self.source[start..end])) 567 + let content = self.parse_name(within)?; 568 + Ok(Identifier::from(content)) 601 569 } 602 570 603 571 fn parse_string(&mut self) -> Result<String, ParseError> { ··· 727 695 } 728 696 self.consume_while(is_ident); 729 697 let end = self.offset; 730 - let name = &self.source[start + 1..end]; 731 - let name = self.ctx.add_identifier(name); 698 + let name = Identifier::from(&self.source[start + 1..end]); 732 699 Ok(ast::Capture { 733 700 name, 734 701 quantifier: Zero, // set in checker ··· 751 718 fn parse_literal(&mut self) -> Result<ast::Expression, ParseError> { 752 719 let literal_location = self.location; 753 720 self.consume_token("#")?; 754 - let literal = self.parse_identifier("literal")?; 755 - if literal == self.false_keyword { 721 + let literal = self.parse_name("literal")?; 722 + if literal == "false" { 756 723 return Ok(ast::Expression::FalseLiteral); 757 - } else if literal == self.null_keyword { 724 + } else if literal == "null" { 758 725 return Ok(ast::Expression::NullLiteral); 759 - } else if literal == self.true_keyword { 726 + } else if literal == "true" { 760 727 return Ok(ast::Expression::TrueLiteral); 761 728 } else { 762 729 Err(ParseError::UnexpectedLiteral( 763 - self.ctx.resolve(literal).into(), 730 + literal.into(), 764 731 literal_location, 765 732 )) 766 733 }
+13 -9
src/variables.rs
··· 16 16 #[derive(Debug, Error)] 17 17 pub enum VariableError { 18 18 #[error("Cannot assign immutable variable")] 19 - CannotAssignImmutableVariable(Identifier), 19 + CannotAssignImmutableVariable(String), 20 20 #[error("Variable already defined")] 21 - VariableAlreadyDefined(Identifier), 21 + VariableAlreadyDefined(String), 22 22 #[error("Undefined variable")] 23 - UndefinedVariable(Identifier), 23 + UndefinedVariable(String), 24 24 } 25 25 26 26 /// An environment of named variables ··· 82 82 v.insert(variable); 83 83 Ok(()) 84 84 } 85 - Occupied(_) => Err(VariableError::VariableAlreadyDefined(name)), 85 + Occupied(o) => Err(VariableError::VariableAlreadyDefined(o.key().to_string())), 86 86 } 87 87 } 88 88 89 89 fn set(&mut self, name: Identifier, value: V) -> Result<(), VariableError> { 90 90 match self.values.entry(name) { 91 - Vacant(_) => self 91 + Vacant(v) => self 92 92 .parent 93 93 .as_mut() 94 - .map(|parent| parent.set(name, value)) 95 - .unwrap_or(Err(VariableError::UndefinedVariable(name))), 94 + .map(|parent| parent.set(v.key().clone(), value)) 95 + .unwrap_or(Err(VariableError::UndefinedVariable( 96 + v.into_key().to_string(), 97 + ))), 96 98 Occupied(mut o) => { 97 99 let mut variable = o.get_mut(); 98 100 if variable.mutable { 99 101 variable.value = value; 100 102 Ok(()) 101 103 } else { 102 - Err(VariableError::CannotAssignImmutableVariable(name)) 104 + Err(VariableError::CannotAssignImmutableVariable( 105 + o.key().to_string(), 106 + )) 103 107 } 104 108 } 105 109 } ··· 107 111 108 112 fn get(&self, name: &Identifier) -> Option<&V> { 109 113 self.values 110 - .get(&name) 114 + .get(name) 111 115 .map(|v| &v.value) 112 116 .or_else(|| self.parent.as_ref().map(|p| p.get(name)).flatten()) 113 117 }
+7 -8
tests/it/execution.rs
··· 9 9 use tree_sitter::Parser; 10 10 use tree_sitter_graph::ast::File; 11 11 use tree_sitter_graph::functions::Functions; 12 - use tree_sitter_graph::Context; 13 12 use tree_sitter_graph::ExecutionError; 13 + use tree_sitter_graph::Identifier; 14 14 use tree_sitter_graph::Variables; 15 15 16 16 fn init_log() { ··· 27 27 let mut parser = Parser::new(); 28 28 parser.set_language(tree_sitter_python::language()).unwrap(); 29 29 let tree = parser.parse(python_source, None).unwrap(); 30 - let mut ctx = Context::new(); 31 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, dsl_source) 32 - .expect("Cannot parse file"); 33 - let mut functions = Functions::stdlib(&mut ctx); 30 + let file = 31 + File::from_str(tree_sitter_python::language(), dsl_source).expect("Cannot parse file"); 32 + let mut functions = Functions::stdlib(); 34 33 let mut globals = Variables::new(); 35 34 globals 36 - .add(ctx.add_identifier("filename"), "test.py".into()) 35 + .add(Identifier::from("filename"), "test.py".into()) 37 36 .map_err(|_| ExecutionError::DuplicateVariable("filename".into()))?; 38 - let graph = file.execute(&ctx, &tree, python_source, &mut functions, &mut globals)?; 39 - let result = graph.display_with(&ctx).to_string(); 37 + let graph = file.execute(&tree, python_source, &mut functions, &mut globals)?; 38 + let result = graph.pretty_print().to_string(); 40 39 Ok(result) 41 40 } 42 41
+12 -14
tests/it/graph.rs
··· 9 9 use tree_sitter::Parser; 10 10 use tree_sitter_graph::graph::Graph; 11 11 use tree_sitter_graph::graph::Value; 12 - use tree_sitter_graph::Context; 12 + use tree_sitter_graph::Identifier; 13 13 14 14 #[test] 15 15 fn can_overwrite_attributes() { 16 - let mut ctx = Context::new(); 17 16 let mut graph = Graph::new(); 18 17 let node = graph.add_graph_node(); 19 18 let attrs = &mut graph[node].attributes; 20 - let name = ctx.add_identifier("name"); 21 - attrs.add(name, "node0").unwrap(); 22 - attrs.add(name, "overwritten").unwrap_err(); 23 - assert_eq!(*attrs.get(name).unwrap(), Value::from("overwritten")); 19 + let name = Identifier::from("name"); 20 + attrs.add(name.clone(), "node0").unwrap(); 21 + attrs.add(name.clone(), "overwritten").unwrap_err(); 22 + assert_eq!(*attrs.get(&name).unwrap(), Value::from("overwritten")); 24 23 } 25 24 26 25 #[test] ··· 55 54 parser.set_language(tree_sitter_python::language()).unwrap(); 56 55 let tree = parser.parse(python_source, None).unwrap(); 57 56 58 - let mut ctx = Context::new(); 59 57 let mut graph = Graph::new(); 60 58 let root = graph.add_syntax_node(tree.root_node()); 61 59 let node0 = graph.add_graph_node(); 62 60 graph[node0] 63 61 .attributes 64 - .add(ctx.add_identifier("name"), "node0") 62 + .add(Identifier::from("name"), "node0") 65 63 .unwrap(); 66 64 graph[node0] 67 65 .attributes 68 - .add(ctx.add_identifier("source"), root) 66 + .add(Identifier::from("source"), root) 69 67 .unwrap(); 70 68 let node1 = graph.add_graph_node(); 71 69 graph[node1] 72 70 .attributes 73 - .add(ctx.add_identifier("name"), "node1") 71 + .add(Identifier::from("name"), "node1") 74 72 .unwrap(); 75 73 let node2 = graph.add_graph_node(); 76 74 graph[node2] 77 75 .attributes 78 - .add(ctx.add_identifier("name"), "node2") 76 + .add(Identifier::from("name"), "node2") 79 77 .unwrap(); 80 78 graph[node2] 81 79 .attributes 82 - .add(ctx.add_identifier("parent"), node1) 80 + .add(Identifier::from("parent"), node1) 83 81 .unwrap(); 84 82 let edge01 = graph[node0] 85 83 .add_edge(node1) 86 84 .unwrap_or_else(|_| unreachable!()); 87 85 edge01 88 86 .attributes 89 - .add(ctx.add_identifier("precedence"), 14) 87 + .add(Identifier::from("precedence"), 14) 90 88 .unwrap(); 91 89 assert_eq!( 92 - graph.display_with(&ctx).to_string(), 90 + graph.pretty_print().to_string(), 93 91 indoc! {r#" 94 92 node 0 95 93 name: "node0"
+6 -8
tests/it/lazy_execution.rs
··· 9 9 use tree_sitter::Parser; 10 10 use tree_sitter_graph::ast::File; 11 11 use tree_sitter_graph::functions::Functions; 12 - use tree_sitter_graph::Context; 13 12 use tree_sitter_graph::ExecutionError; 14 13 use tree_sitter_graph::Variables; 15 14 ··· 27 26 let mut parser = Parser::new(); 28 27 parser.set_language(tree_sitter_python::language()).unwrap(); 29 28 let tree = parser.parse(python_source, None).unwrap(); 30 - let mut ctx = Context::new(); 31 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, dsl_source) 32 - .expect("Cannot parse file"); 33 - let mut functions = Functions::stdlib(&mut ctx); 29 + let file = 30 + File::from_str(tree_sitter_python::language(), dsl_source).expect("Cannot parse file"); 31 + let mut functions = Functions::stdlib(); 34 32 let mut globals = Variables::new(); 35 33 globals 36 - .add(ctx.add_identifier("filename"), "test.py".into()) 34 + .add("filename".into(), "test.py".into()) 37 35 .map_err(|_| ExecutionError::DuplicateVariable("filename".into()))?; 38 - let graph = file.execute_lazy(&mut ctx, &tree, python_source, &mut functions, &globals)?; 39 - let result = graph.display_with(&ctx).to_string(); 36 + let graph = file.execute_lazy(&tree, python_source, &mut functions, &globals)?; 37 + let result = graph.pretty_print().to_string(); 40 38 Ok(result) 41 39 } 42 40
+88 -127
tests/it/parser.rs
··· 8 8 use tree_sitter::CaptureQuantifier::*; 9 9 10 10 use tree_sitter_graph::ast::*; 11 - use tree_sitter_graph::Context; 11 + use tree_sitter_graph::Identifier; 12 12 use tree_sitter_graph::Location; 13 13 14 14 #[test] 15 15 fn can_parse_blocks() { 16 - let mut ctx = Context::new(); 17 16 let source = r#" 18 17 (function_definition 19 18 name: (identifier) @cap1) @cap2 ··· 27 26 set @cap2.var1 = loc1 28 27 } 29 28 "#; 30 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 31 - .expect("Cannot parse file"); 29 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 32 30 33 - let loc1 = ctx.add_identifier("loc1"); 34 - let precedence = ctx.add_identifier("precedence"); 35 - let pop = ctx.add_identifier("pop"); 36 - let prop1 = ctx.add_identifier("prop1"); 37 - let push = ctx.add_identifier("push"); 38 - let cap2 = ctx.add_identifier("cap2"); 39 - let var1 = ctx.add_identifier("var1"); 31 + let loc1 = Identifier::from("loc1"); 32 + let precedence = Identifier::from("precedence"); 33 + let pop = Identifier::from("pop"); 34 + let prop1 = Identifier::from("prop1"); 35 + let push = Identifier::from("push"); 36 + let cap2 = Identifier::from("cap2"); 37 + let var1 = Identifier::from("var1"); 40 38 41 39 let statements = file 42 40 .stanzas ··· 48 46 vec![vec![ 49 47 CreateGraphNode { 50 48 node: UnscopedVariable { 51 - name: loc1, 49 + name: loc1.clone(), 52 50 location: Location { row: 4, column: 15 } 53 51 } 54 52 .into(), ··· 60 58 scope: Box::new( 61 59 Capture { 62 60 quantifier: One, 63 - name: cap2, 61 + name: cap2.clone(), 64 62 file_capture_index: 1, 65 63 stanza_capture_index: 1, 66 64 location: Location { row: 5, column: 15 } 67 65 } 68 66 .into() 69 67 ), 70 - name: prop1, 68 + name: prop1.clone(), 71 69 location: Location { row: 5, column: 21 } 72 70 } 73 71 .into(), ··· 79 77 scope: Box::new( 80 78 Capture { 81 79 quantifier: One, 82 - name: cap2, 80 + name: cap2.clone(), 83 81 file_capture_index: 1, 84 82 stanza_capture_index: 1, 85 83 location: Location { row: 6, column: 15 } 86 84 } 87 85 .into() 88 86 ), 89 - name: prop1, 87 + name: prop1.clone(), 90 88 location: Location { row: 6, column: 21 } 91 89 } 92 90 .into(), 93 91 sink: UnscopedVariable { 94 - name: loc1, 92 + name: loc1.clone(), 95 93 location: Location { row: 6, column: 30 }, 96 94 } 97 95 .into(), ··· 103 101 scope: Box::new( 104 102 Capture { 105 103 quantifier: One, 106 - name: cap2, 104 + name: cap2.clone(), 107 105 file_capture_index: 1, 108 106 stanza_capture_index: 1, 109 107 location: Location { row: 7, column: 16 } 110 108 } 111 109 .into() 112 110 ), 113 - name: prop1, 111 + name: prop1.clone(), 114 112 location: Location { row: 7, column: 22 }, 115 113 } 116 114 .into(), 117 115 sink: UnscopedVariable { 118 - name: loc1.into(), 116 + name: loc1.clone(), 119 117 location: Location { row: 7, column: 31 }, 120 118 } 121 119 .into(), ··· 131 129 scope: Box::new( 132 130 Capture { 133 131 quantifier: One, 134 - name: cap2, 132 + name: cap2.clone(), 135 133 file_capture_index: 1, 136 134 stanza_capture_index: 1, 137 135 location: Location { row: 8, column: 16 } 138 136 } 139 137 .into() 140 138 ), 141 - name: prop1, 139 + name: prop1.clone(), 142 140 location: Location { row: 8, column: 22 }, 143 141 } 144 142 .into(), 145 143 attributes: vec![ 146 144 Attribute { 147 - name: push, 145 + name: push.clone(), 148 146 value: String::from("str2").into(), 149 147 }, 150 148 Attribute { 151 - name: pop, 152 - value: Expression::TrueLiteral 149 + name: pop.clone(), 150 + value: Expression::TrueLiteral, 153 151 }, 154 152 ], 155 153 location: Location { row: 8, column: 10 }, ··· 160 158 scope: Box::new( 161 159 Capture { 162 160 quantifier: One, 163 - name: cap2, 161 + name: cap2.clone(), 164 162 file_capture_index: 1, 165 163 stanza_capture_index: 1, 166 164 location: Location { row: 9, column: 14 } 167 165 } 168 166 .into() 169 167 ), 170 - name: var1, 168 + name: var1.clone(), 171 169 location: Location { row: 9, column: 20 }, 172 170 } 173 171 .into(), 174 172 value: UnscopedVariable { 175 - name: loc1, 173 + name: loc1.clone(), 176 174 location: Location { row: 9, column: 27 }, 177 175 } 178 176 .into(), ··· 184 182 scope: Box::new( 185 183 Capture { 186 184 quantifier: One, 187 - name: cap2, 185 + name: cap2.clone(), 188 186 file_capture_index: 1, 189 187 stanza_capture_index: 1, 190 188 location: Location { ··· 194 192 } 195 193 .into() 196 194 ), 197 - name: var1, 195 + name: var1.clone(), 198 196 location: Location { 199 197 row: 10, 200 198 column: 20 ··· 202 200 } 203 201 .into(), 204 202 value: UnscopedVariable { 205 - name: loc1, 203 + name: loc1.clone(), 206 204 location: Location { 207 205 row: 10, 208 206 column: 27 ··· 221 219 222 220 #[test] 223 221 fn can_parse_literals() { 224 - let mut ctx = Context::new(); 225 222 let source = r#" 226 223 (identifier) 227 224 { ··· 230 227 let t = #true 231 228 } 232 229 "#; 233 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 234 - .expect("Cannot parse file"); 230 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 235 231 236 - let f = ctx.add_identifier("f"); 237 - let n = ctx.add_identifier("n"); 238 - let t = ctx.add_identifier("t"); 232 + let f = Identifier::from("f"); 233 + let n = Identifier::from("n"); 234 + let t = Identifier::from("t"); 239 235 240 236 let statements = file 241 237 .stanzas ··· 247 243 vec![vec![ 248 244 DeclareImmutable { 249 245 variable: UnscopedVariable { 250 - name: f, 246 + name: f.clone(), 251 247 location: Location { row: 3, column: 14 } 252 248 } 253 249 .into(), ··· 257 253 .into(), 258 254 DeclareImmutable { 259 255 variable: UnscopedVariable { 260 - name: n, 256 + name: n.clone(), 261 257 location: Location { row: 4, column: 14 } 262 258 } 263 259 .into(), ··· 267 263 .into(), 268 264 DeclareImmutable { 269 265 variable: UnscopedVariable { 270 - name: t, 266 + name: t.clone(), 271 267 location: Location { row: 5, column: 14 } 272 268 } 273 269 .into(), ··· 281 277 282 278 #[test] 283 279 fn can_parse_strings() { 284 - let mut ctx = Context::new(); 285 280 let source = r#" 286 281 (identifier) 287 282 { 288 283 let loc1 = "\"abc,\ndef\\" 289 284 } 290 285 "#; 291 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 292 - .expect("Cannot parse file"); 286 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 293 287 294 - let loc1 = ctx.add_identifier("loc1"); 288 + let loc1 = Identifier::from("loc1"); 295 289 296 290 let statements = file 297 291 .stanzas ··· 302 296 statements, 303 297 vec![vec![DeclareImmutable { 304 298 variable: UnscopedVariable { 305 - name: loc1, 299 + name: loc1.clone(), 306 300 location: Location { row: 3, column: 14 } 307 301 } 308 302 .into(), ··· 315 309 316 310 #[test] 317 311 fn can_parse_lists() { 318 - let mut ctx = Context::new(); 319 312 let source = r#" 320 313 (identifier) 321 314 { ··· 324 317 let list3 = ["hello", "world",] 325 318 } 326 319 "#; 327 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 328 - .expect("Cannot parse file"); 320 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 329 321 330 - let list1 = ctx.add_identifier("list1"); 331 - let list2 = ctx.add_identifier("list2"); 332 - let list3 = ctx.add_identifier("list3"); 322 + let list1 = Identifier::from("list1"); 323 + let list2 = Identifier::from("list2"); 324 + let list3 = Identifier::from("list3"); 333 325 334 326 let statements = file 335 327 .stanzas ··· 341 333 vec![vec![ 342 334 DeclareImmutable { 343 335 variable: UnscopedVariable { 344 - name: list1, 336 + name: list1.clone(), 345 337 location: Location { row: 3, column: 14 } 346 338 } 347 339 .into(), ··· 358 350 .into(), 359 351 DeclareImmutable { 360 352 variable: UnscopedVariable { 361 - name: list2, 353 + name: list2.clone(), 362 354 location: Location { row: 4, column: 14 } 363 355 } 364 356 .into(), ··· 368 360 .into(), 369 361 DeclareImmutable { 370 362 variable: UnscopedVariable { 371 - name: list3, 363 + name: list3.clone(), 372 364 location: Location { row: 5, column: 14 } 373 365 } 374 366 .into(), ··· 394 386 395 387 #[test] 396 388 fn can_parse_sets() { 397 - let mut ctx = Context::new(); 398 389 let source = r#" 399 390 (identifier) 400 391 { ··· 403 394 let set3 = {"hello", "world",} 404 395 } 405 396 "#; 406 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 407 - .expect("Cannot parse file"); 397 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 408 398 409 - let set1 = ctx.add_identifier("set1"); 410 - let set2 = ctx.add_identifier("set2"); 411 - let set3 = ctx.add_identifier("set3"); 399 + let set1 = Identifier::from("set1"); 400 + let set2 = Identifier::from("set2"); 401 + let set3 = Identifier::from("set3"); 412 402 413 403 let statements = file 414 404 .stanzas ··· 420 410 vec![vec![ 421 411 DeclareImmutable { 422 412 variable: UnscopedVariable { 423 - name: set1, 413 + name: set1.clone(), 424 414 location: Location { row: 3, column: 14 } 425 415 } 426 416 .into(), ··· 437 427 .into(), 438 428 DeclareImmutable { 439 429 variable: UnscopedVariable { 440 - name: set2, 430 + name: set2.clone(), 441 431 location: Location { row: 4, column: 14 } 442 432 } 443 433 .into(), ··· 447 437 .into(), 448 438 DeclareImmutable { 449 439 variable: UnscopedVariable { 450 - name: set3, 440 + name: set3.clone(), 451 441 location: Location { row: 5, column: 14 } 452 442 } 453 443 .into(), ··· 473 463 474 464 #[test] 475 465 fn can_parse_print() { 476 - let mut ctx = Context::new(); 477 466 let source = r#" 478 467 (identifier) 479 468 { 480 469 print "x =", 5 481 470 } 482 471 "#; 483 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 484 - .expect("Cannot parse file"); 472 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 485 473 486 474 let statements = file 487 475 .stanzas ··· 506 494 507 495 #[test] 508 496 fn cannot_parse_nullable_regex() { 509 - let mut ctx = Context::new(); 510 497 let source = r#" 511 498 (module) @root 512 499 { ··· 517 504 node n 518 505 } 519 506 "#; 520 - if let Ok(_) = File::from_str(tree_sitter_python::language(), &mut ctx, source) { 507 + if let Ok(_) = File::from_str(tree_sitter_python::language(), source) { 521 508 panic!("Parse succeeded unexpectedly"); 522 509 } 523 510 } 524 511 525 512 #[test] 526 513 fn can_parse_star_capture() { 527 - let mut ctx = Context::new(); 528 514 let source = r#" 529 515 (module (_)* @stmts) 530 516 { 531 517 print @stmts 532 518 } 533 519 "#; 534 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 535 - .expect("Cannot parse file"); 520 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 536 521 537 - let stmts = ctx.add_identifier("stmts"); 522 + let stmts = Identifier::from("stmts"); 538 523 539 524 let statements = file 540 525 .stanzas ··· 560 545 561 546 #[test] 562 547 fn can_parse_star_multiple_capture() { 563 - let mut ctx = Context::new(); 564 548 let source = r#" 565 549 (module (_) @stmt * @stmts) 566 550 { ··· 568 552 print @stmts 569 553 } 570 554 "#; 571 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 572 - .expect("Cannot parse file"); 555 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 573 556 574 - let stmt = ctx.add_identifier("stmt"); 575 - let stmts = ctx.add_identifier("stmts"); 557 + let stmt = Identifier::from("stmt"); 558 + let stmts = Identifier::from("stmts"); 576 559 577 560 let statements = file 578 561 .stanzas ··· 612 595 613 596 #[test] 614 597 fn can_parse_plus_capture() { 615 - let mut ctx = Context::new(); 616 598 let source = r#" 617 599 (module (_)+ @stmts) 618 600 { 619 601 print @stmts 620 602 } 621 603 "#; 622 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 623 - .expect("Cannot parse file"); 604 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 624 605 625 - let stmts = ctx.add_identifier("stmts"); 606 + let stmts = Identifier::from("stmts"); 626 607 627 608 let statements = file 628 609 .stanzas ··· 648 629 649 630 #[test] 650 631 fn can_parse_optional_capture() { 651 - let mut ctx = Context::new(); 652 632 let source = r#" 653 633 (module (_)? @stmt) 654 634 { 655 635 print @stmt 656 636 } 657 637 "#; 658 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 659 - .expect("Cannot parse file"); 638 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 660 639 661 - let stmt = ctx.add_identifier("stmt"); 640 + let stmt = Identifier::from("stmt"); 662 641 663 642 let statements = file 664 643 .stanzas ··· 684 663 685 664 #[test] 686 665 fn can_parse_parent_optional_capture() { 687 - let mut ctx = Context::new(); 688 666 let source = r#" 689 667 (module (_) @stmt) ? 690 668 { 691 669 print @stmt 692 670 } 693 671 "#; 694 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 695 - .expect("Cannot parse file"); 672 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 696 673 697 - let stmt = ctx.add_identifier("stmt"); 674 + let stmt = Identifier::from("stmt"); 698 675 699 676 let statements = file 700 677 .stanzas ··· 720 697 721 698 #[test] 722 699 fn can_parse_alternative_capture() { 723 - let mut ctx = Context::new(); 724 700 let source = r#" 725 701 (module [(_) (_) @stmt]) 726 702 { 727 703 print @stmt 728 704 } 729 705 "#; 730 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 731 - .expect("Cannot parse file"); 706 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 732 707 733 - let stmt = ctx.add_identifier("stmt"); 708 + let stmt = Identifier::from("stmt"); 734 709 735 710 let statements = file 736 711 .stanzas ··· 756 731 757 732 #[test] 758 733 fn can_parse_nested_plus_and_optional_capture() { 759 - let mut ctx = Context::new(); 760 734 let source = r#" 761 735 (module (_)+ @stmt) ? 762 736 { 763 737 print @stmt 764 738 } 765 739 "#; 766 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 767 - .expect("Cannot parse file"); 740 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 768 741 769 - let stmt = ctx.add_identifier("stmt"); 742 + let stmt = Identifier::from("stmt"); 770 743 771 744 let statements = file 772 745 .stanzas ··· 792 765 793 766 #[test] 794 767 fn can_parse_if() { 795 - let mut ctx = Context::new(); 796 768 let source = r#" 797 769 (module (pass_statement)? @x) 798 770 { ··· 801 773 } 802 774 } 803 775 "#; 804 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 805 - .expect("Cannot parse file"); 776 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 806 777 807 - let x = ctx.add_identifier("x"); 778 + let x = Identifier::from("x"); 808 779 809 780 let statements = file 810 781 .stanzas ··· 844 815 845 816 #[test] 846 817 fn can_parse_if_elif() { 847 - let mut ctx = Context::new(); 848 818 let source = r#" 849 819 (module (pass_statement)? @x) 850 820 { ··· 855 825 } 856 826 } 857 827 "#; 858 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 859 - .expect("Cannot parse file"); 828 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 860 829 861 - let x = ctx.add_identifier("x"); 830 + let x = Identifier::from("x"); 862 831 863 832 let statements = file 864 833 .stanzas ··· 873 842 conditions: vec![Condition::None { 874 843 value: Capture { 875 844 quantifier: ZeroOrOne, 876 - name: x, 845 + name: x.clone(), 877 846 file_capture_index: 0, 878 847 stanza_capture_index: 0, 879 848 location: Location { row: 3, column: 18 }, ··· 896 865 conditions: vec![Condition::Some { 897 866 value: Capture { 898 867 quantifier: ZeroOrOne, 899 - name: x, 868 + name: x.clone(), 900 869 file_capture_index: 0, 901 870 stanza_capture_index: 0, 902 871 location: Location { row: 5, column: 22 }, ··· 923 892 924 893 #[test] 925 894 fn can_parse_if_else() { 926 - let mut ctx = Context::new(); 927 895 let source = r#" 928 896 (module (pass_statement)? @x) 929 897 { ··· 934 902 } 935 903 } 936 904 "#; 937 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 938 - .expect("Cannot parse file"); 905 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 939 906 940 - let x = ctx.add_identifier("x"); 907 + let x = Identifier::from("x"); 941 908 942 909 let statements = file 943 910 .stanzas ··· 991 958 992 959 #[test] 993 960 fn cannot_parse_if_some_list_capture() { 994 - let mut ctx = Context::new(); 995 961 let source = r#" 996 962 (module (_)+ @xs) @root 997 963 { ··· 1000 966 } 1001 967 } 1002 968 "#; 1003 - if let Ok(_) = File::from_str(tree_sitter_python::language(), &mut ctx, source) { 969 + if let Ok(_) = File::from_str(tree_sitter_python::language(), source) { 1004 970 panic!("Parse succeeded unexpectedly"); 1005 971 } 1006 972 } 1007 973 1008 974 #[test] 1009 975 fn can_parse_for_in() { 1010 - let mut ctx = Context::new(); 1011 976 let source = r#" 1012 977 (module (_)* @xs) 1013 978 { ··· 1016 981 } 1017 982 } 1018 983 "#; 1019 - let file = File::from_str(tree_sitter_python::language(), &mut ctx, source) 1020 - .expect("Cannot parse file"); 984 + let file = File::from_str(tree_sitter_python::language(), source).expect("Cannot parse file"); 1021 985 1022 - let xs = ctx.add_identifier("xs"); 1023 - let x = ctx.add_identifier("x"); 986 + let xs = Identifier::from("xs"); 987 + let x = Identifier::from("x"); 1024 988 1025 989 let statements = file 1026 990 .stanzas ··· 1031 995 statements, 1032 996 vec![vec![ForIn { 1033 997 variable: UnscopedVariable { 1034 - name: x, 998 + name: x.clone(), 1035 999 location: Location { row: 3, column: 14 } 1036 1000 }, 1037 1001 value: Capture { 1038 1002 quantifier: ZeroOrMore, 1039 - name: xs, 1003 + name: xs.clone(), 1040 1004 file_capture_index: 0, 1041 1005 stanza_capture_index: 0, 1042 1006 location: Location { row: 3, column: 19 }, ··· 1044 1008 .into(), 1045 1009 statements: vec![Print { 1046 1010 values: vec![UnscopedVariable { 1047 - name: x, 1011 + name: x.clone(), 1048 1012 location: Location { row: 4, column: 18 }, 1049 1013 } 1050 1014 .into()], ··· 1059 1023 1060 1024 #[test] 1061 1025 fn cannot_parse_for_in_optional_capture() { 1062 - let mut ctx = Context::new(); 1063 1026 let source = r#" 1064 1027 (module (_)? @xs) @root 1065 1028 { ··· 1068 1031 } 1069 1032 } 1070 1033 "#; 1071 - if let Ok(_) = File::from_str(tree_sitter_python::language(), &mut ctx, source) { 1034 + if let Ok(_) = File::from_str(tree_sitter_python::language(), source) { 1072 1035 panic!("Parse succeeded unexpectedly"); 1073 1036 } 1074 1037 } 1075 1038 1076 1039 #[test] 1077 1040 fn cannot_parse_scan_of_nonlocal_call_expression() { 1078 - let mut ctx = Context::new(); 1079 1041 let source = r#" 1080 1042 (function_definition 1081 1043 name: (identifier) @name) ··· 1088 1050 } 1089 1051 } 1090 1052 "#; 1091 - if let Ok(_) = File::from_str(tree_sitter_python::language(), &mut ctx, source) { 1053 + if let Ok(_) = File::from_str(tree_sitter_python::language(), source) { 1092 1054 panic!("Parse succeeded unexpectedly"); 1093 1055 } 1094 1056 } 1095 1057 1096 1058 #[test] 1097 1059 fn cannot_parse_scan_of_nonlocal_variable() { 1098 - let mut ctx = Context::new(); 1099 1060 let source = r#" 1100 1061 (function_definition 1101 1062 name: (identifier) @name) ··· 1109 1070 } 1110 1071 } 1111 1072 "#; 1112 - if let Ok(_) = File::from_str(tree_sitter_python::language(), &mut ctx, source) { 1073 + if let Ok(_) = File::from_str(tree_sitter_python::language(), source) { 1113 1074 panic!("Parse succeeded unexpectedly"); 1114 1075 } 1115 1076 }