Skip to content

Commit

Permalink
Compiler API overhaul (#104)
Browse files Browse the repository at this point in the history
* compiler api WIP

* metrics plugin

* make large structs Cow in compiler

* compiler change done

* clean up comments

* run fix

* fix plugins not compiling

* fix web client and added stat display

* fix rest of client issues

* clean up imports
  • Loading branch information
Pistonight authored Oct 11, 2023
1 parent e9384a8 commit f9bc981
Show file tree
Hide file tree
Showing 35 changed files with 904 additions and 729 deletions.
2 changes: 1 addition & 1 deletion compiler-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ wasm = [
"instant/wasm-bindgen",
"no-async-send",
]
no-async-send=[]
no-async-send = []

[lib]
name = "celerc"
Expand Down
162 changes: 0 additions & 162 deletions compiler-core/src/api.rs

This file was deleted.

79 changes: 79 additions & 0 deletions compiler-core/src/api/compile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::borrow::Cow;

use celerctypes::ExecDoc;

use crate::comp::Compiler;
use crate::pack::pack_route;
use crate::plug::PluginRuntime;
use crate::util::async_for;

use super::CompilerContext;

impl CompilerContext {
// TODO #78: will no longer need Option after compiler become not cancelable
pub async fn compile(&self) -> Option<ExecDoc<'_>> {
let mut plugin_runtimes = self.create_plugin_runtimes().await;

// pack phase 1
// resolve uses in the route
let route = pack_route(
&self.project_resource,
self.phase0.route.clone(),
self.setting.max_use_depth,
self.setting.max_ref_depth,
)
.await;

// comp phase
let compiler = self.create_compiler();
let mut comp_doc = match compiler.comp_doc(route).await {
Ok(doc) => doc,
// TODO #78: will no longer need Option after compiler become not cancelable
Err(_) => {
return None;
}
};

for plugin in plugin_runtimes.iter_mut() {
if let Err(e) = plugin.on_compile(&self.phase0.meta, &mut comp_doc).await {
e.add_to_diagnostics(&mut comp_doc.diagnostics);
}
}

// exec phase
let mut exec_doc = match comp_doc.exec(&self.phase0.project).await {
Ok(doc) => doc,
// TODO #78: will no longer need Option after compiler become not cancelable
Err(_) => {
return None;
}
};

for plugin in plugin_runtimes.iter_mut() {
if let Err(e) = plugin
.on_post_compile(&self.phase0.meta, &mut exec_doc)
.await
{
e.add_to_diagnostics(&mut exec_doc.diagnostics);
}
}
Some(exec_doc)
}
async fn create_plugin_runtimes(&self) -> Vec<Box<dyn PluginRuntime>> {
let mut runtimes = Vec::with_capacity(self.phase0.meta.plugins.len());
let _ = async_for!(plugin_inst in &self.phase0.meta.plugins, {
let runtime = plugin_inst.create_runtime(self);
runtimes.push(runtime);
});
runtimes
}
fn create_compiler(&self) -> Compiler<'_> {
Compiler {
meta: Cow::Borrowed(&self.phase0.meta),
color: self.phase0.project.map.initial_color.clone(),
coord: self.phase0.project.map.initial_coord.clone(),
project: Cow::Borrowed(&self.phase0.project),
max_preset_depth: self.setting.max_preset_ref_depth,
}
}
}
119 changes: 119 additions & 0 deletions compiler-core/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//! Celer Compiler API
use celerctypes::{ExecDoc, RouteMetadata};
use instant::Instant;
use log::{error, info};
use std::borrow::Cow;
use std::collections::HashMap;

mod prepare;
pub use prepare::*;
mod compile;
pub use compile::*;

use derivative::Derivative;

use crate::comp::Compiler;
use crate::lang::Preset;
use crate::pack::{PackerError, PackerResult, Phase0, Resource, ValidUse};
use crate::plug::PluginInstance;

/// Resolve project.yaml resource under the root resource
pub async fn resolve_project(root_resource: &Resource) -> PackerResult<Resource> {
let project_ref = ValidUse::Relative("./project.yaml".to_string());
match root_resource.resolve(&project_ref).await {
Err(_) => {
error!("fail to resolve project.yaml");
Err(PackerError::InvalidProject)
}
x => x,
}
}

pub fn make_project_for_error(source: &str) -> RouteMetadata {
RouteMetadata {
title: "[compile error]".to_string(),
version: "[compile error]".to_string(),
source: source.to_string(),
..Default::default()
}
}

// TODO #78: Option no longer needed
pub async fn make_doc_for_packer_error(
source: &str,
error: PackerError,
) -> Option<ExecDoc<'static>> {
let comp_doc = Compiler::default()
.create_empty_doc_for_packer_error(error)
.await;
let project = make_project_for_error(source);
let exec_doc = comp_doc.exec(&project).await.ok()?;
Some(ExecDoc {
preface: exec_doc.preface,
route: exec_doc.route,
diagnostics: exec_doc.diagnostics,
project: Cow::Owned(project),
})
}

pub struct CompilerContext {
pub start_time: Instant,
pub project_resource: Resource,
pub setting: Setting,
pub phase0: Phase0,
}

impl CompilerContext {
/// Reset the start time to be now.
///
/// If using a cached compiler context, this should be called so metrics are reported
/// correctly.
pub fn reset_start_time(&mut self) {
self.start_time = Instant::now();
}

/// Get the start time of the compilation
pub fn get_start_time(&self) -> &Instant {
&self.start_time
}
}

/// Metadata of the compiler
///
/// This is information needed during compilation,
/// but not needed to render the route.
/// IDEs may also find this useful to provide auto-complete, etc.
#[derive(Default, Debug, Clone)]
pub struct CompilerMetadata {
pub presets: HashMap<String, Preset>,
pub plugins: Vec<PluginInstance>,
pub default_icon_priority: i64,
}

/// Compiler settings
#[derive(Debug, Derivative)]
#[derivative(Default)]
pub struct Setting {
/// The maximum depth of `use` properties
#[derivative(Default(value = "8"))]
pub max_use_depth: usize,

/// The maximum depth of object/array levels in the route
#[derivative(Default(value = "32"))]
pub max_ref_depth: usize,

/// The maximum depth of preset namespaces in config
#[derivative(Default(value = "16"))]
pub max_preset_namespace_depth: usize,

/// The maximum depth of preset references in route
#[derivative(Default(value = "8"))]
pub max_preset_ref_depth: usize,
}

#[cfg(feature = "wasm")]
#[inline]
pub fn cancel_current_compilation() {
crate::util::set_cancelled(true);
info!("cancel requested");
}
Loading

0 comments on commit f9bc981

Please sign in to comment.