1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use serde::{Deserialize, Serialize};
use sway_core::OptLevel;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
#[serde(rename_all = "kebab-case")]
pub struct ExperimentalFlags {
    pub new_encoding: bool,
}

/// Parameters to pass through to the `sway_core::BuildConfig` during compilation.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct BuildProfile {
    #[serde(default)]
    pub name: String,
    #[serde(default)]
    pub print_ast: bool,
    pub print_dca_graph: Option<String>,
    pub print_dca_graph_url_format: Option<String>,
    #[serde(default)]
    pub print_ir: bool,
    #[serde(default)]
    pub print_finalized_asm: bool,
    #[serde(default)]
    pub print_intermediate_asm: bool,
    #[serde(default)]
    pub print_bytecode: bool,
    #[serde(default)]
    pub terse: bool,
    #[serde(default)]
    pub time_phases: bool,
    #[serde(default)]
    pub metrics_outfile: Option<String>,
    #[serde(default)]
    pub include_tests: bool,
    #[serde(default)]
    pub json_abi_with_callpaths: bool,
    #[serde(default)]
    pub error_on_warnings: bool,
    #[serde(default)]
    pub reverse_results: bool,
    #[serde(default)]
    pub optimization_level: OptLevel,
    #[serde(default)]
    pub experimental: ExperimentalFlags,
}

impl BuildProfile {
    pub const DEBUG: &'static str = "debug";
    pub const RELEASE: &'static str = "release";
    pub const DEFAULT: &'static str = Self::DEBUG;

    pub fn debug() -> Self {
        Self {
            name: Self::DEBUG.into(),
            print_ast: false,
            print_dca_graph: None,
            print_dca_graph_url_format: None,
            print_ir: false,
            print_finalized_asm: false,
            print_intermediate_asm: false,
            print_bytecode: false,
            terse: false,
            time_phases: false,
            metrics_outfile: None,
            include_tests: false,
            json_abi_with_callpaths: false,
            error_on_warnings: false,
            reverse_results: false,
            optimization_level: OptLevel::Opt0,
            experimental: ExperimentalFlags {
                new_encoding: false,
            },
        }
    }

    pub fn release() -> Self {
        Self {
            name: Self::RELEASE.to_string(),
            print_ast: false,
            print_dca_graph: None,
            print_dca_graph_url_format: None,
            print_ir: false,
            print_finalized_asm: false,
            print_intermediate_asm: false,
            print_bytecode: false,
            terse: false,
            time_phases: false,
            metrics_outfile: None,
            include_tests: false,
            json_abi_with_callpaths: false,
            error_on_warnings: false,
            reverse_results: false,
            optimization_level: OptLevel::Opt1,
            experimental: ExperimentalFlags {
                new_encoding: false,
            },
        }
    }
}

impl Default for BuildProfile {
    fn default() -> Self {
        Self::debug()
    }
}

#[cfg(test)]
mod tests {
    use sway_core::OptLevel;

    use crate::{manifest::build_profile::ExperimentalFlags, BuildProfile, PackageManifest};

    #[test]
    fn test_build_profile_custom_release_section() {
        let manifest = PackageManifest::from_dir("./tests/sections").expect("manifest");
        let build_profiles = manifest.build_profile.expect("build profile");
        assert_eq!(build_profiles.len(), 3);

        let expected = BuildProfile::debug();
        let profile = build_profiles.get("debug").expect("debug profile");
        assert_eq!(*profile, expected);

        let expected = BuildProfile {
            name: "".into(),
            print_finalized_asm: true,
            ..BuildProfile::debug()
        };
        let profile = build_profiles.get("custom").expect("custom profile");
        assert_eq!(*profile, expected);

        let expected = BuildProfile {
            name: "".into(),
            print_ast: true,
            print_dca_graph: Some("dca_graph".into()),
            print_dca_graph_url_format: Some("print_dca_graph_url_format".into()),
            print_ir: true,
            print_finalized_asm: true,
            print_intermediate_asm: true,
            print_bytecode: true,
            terse: true,
            time_phases: true,
            metrics_outfile: Some("metrics_outfile".into()),
            include_tests: true,
            json_abi_with_callpaths: true,
            error_on_warnings: true,
            reverse_results: true,
            optimization_level: OptLevel::Opt0,
            experimental: ExperimentalFlags { new_encoding: true },
        };
        let profile = build_profiles.get("release").expect("release profile");
        assert_eq!(*profile, expected);
    }
}