doc_examples.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // SPDX-License-Identifier: Apache-2.0
  2. use rayon::prelude::*;
  3. use solang::{
  4. codegen::{codegen, OptimizationLevel, Options},
  5. file_resolver::FileResolver,
  6. sema::diagnostics::Diagnostics,
  7. Target,
  8. };
  9. use std::{
  10. ffi::OsStr,
  11. fs::{read_dir, read_to_string},
  12. path::PathBuf,
  13. };
  14. /// Populates a file resolver with all imports that could be used by some example.
  15. fn file_resolver() -> FileResolver {
  16. let mut resolver = FileResolver::default();
  17. resolver.add_import_path(&PathBuf::from("."));
  18. resolver
  19. }
  20. /// Returns a list of all `.sol` files in the given `dir` path.
  21. fn get_source_files(dir: &str) -> Vec<String> {
  22. read_dir(dir)
  23. .unwrap()
  24. .filter_map(|entry| {
  25. let e = entry.unwrap();
  26. if let (true, Some(ext)) = (e.path().is_file(), e.path().extension()) {
  27. if ext == "sol" {
  28. return Some(e.path().display().to_string());
  29. }
  30. }
  31. None
  32. })
  33. .collect()
  34. }
  35. /// Attempts to compile the file at `path` for the `target`, returning the diagnostics on fail.
  36. fn try_compile(path: &str, target: Target) -> Result<(), Diagnostics> {
  37. let mut cache = file_resolver();
  38. cache.set_file_contents(path, read_to_string(path).unwrap());
  39. let mut ns = solang::parse_and_resolve(OsStr::new(path), &mut cache, target);
  40. if ns.diagnostics.any_errors() {
  41. return Err(ns.diagnostics);
  42. }
  43. // Codegen should work too
  44. codegen(
  45. &mut ns,
  46. &Options {
  47. dead_storage: true,
  48. constant_folding: true,
  49. strength_reduce: true,
  50. vector_to_slice: true,
  51. common_subexpression_elimination: true,
  52. opt_level: OptimizationLevel::Default,
  53. ..Default::default()
  54. },
  55. );
  56. Ok(())
  57. }
  58. /// Assert no compilation errors for all `.sol` files found in `dir`.
  59. fn assert_compile(dir: &str, target: Target) {
  60. let errors = get_source_files(dir)
  61. .par_iter()
  62. .filter_map(|path| try_compile(path, target).err().map(|msg| (path, msg)))
  63. .map(|(path, msg)| println!("{path} failed: {msg:#?}"))
  64. .count();
  65. assert_eq!(0, errors);
  66. }
  67. #[test]
  68. fn polkadot_general() {
  69. assert_compile("examples", Target::default_polkadot());
  70. assert_compile("docs/examples/", Target::default_polkadot());
  71. }
  72. #[test]
  73. fn polkadot_specific() {
  74. assert_compile("docs/examples/polkadot/", Target::default_polkadot());
  75. assert_compile("examples/polkadot/", Target::default_polkadot());
  76. }
  77. #[test]
  78. fn solana_general() {
  79. assert_compile("examples", Target::Solana);
  80. assert_compile("docs/examples/", Target::Solana);
  81. }
  82. #[test]
  83. fn solana_specific() {
  84. assert_compile("docs/examples/solana", Target::Solana);
  85. }