fn def_ana_schema_content(&mut self, name: QualifiedSymbol, block: &EA::SpecBlock) {
        let loc = self.parent.env.to_loc(&block.loc);
        let entry = self
            .parent
            .spec_schema_table
            .get(&name)
            .expect("schema defined");
        let type_params = entry.type_params.clone();
        let mut all_vars: BTreeMap<Symbol, LocalVarEntry> = entry
            .vars
            .iter()
            .map(|(n, ty)| {
                (
                    *n,
                    LocalVarEntry {
                        loc: loc.clone(),
                        type_: ty.clone(),
                        operation: None,
                    },
                )
            })
            .collect();
        let mut included_spec = Spec::default();

        // Store back all_vars computed so far (which does not include those coming from
        // included schemas). This is needed so we can analyze lets.
        {
            let entry = self
                .parent
                .spec_schema_table
                .get_mut(&name)
                .expect("schema defined");
            entry.all_vars = all_vars.clone();
        }

        // Process all lets. We need to do this before includes so we have them available
        // in schema arguments of includes. This unfortunately means we can't refer in
        // lets to variables included from schemas, but this seems to be a rare use case.
        assert!(self.spec_block_lets.is_empty());
        for member in &block.value.members {
            let member_loc = self.parent.to_loc(&member.loc);
            if let EA::SpecBlockMember_::Let {
                name: let_name,
                def,
            } = &member.value
            {
                let context = SpecBlockContext::Schema(name.clone());
                self.def_ana_let(&context, &member_loc, let_name, def);
            }
        }

        // Process all schema includes. We need to do this before we type check expressions to have
        // all variables from includes in the environment.
        for (_, included_props, included_exp) in self.iter_schema_includes(&block.value.members) {
            let included_props = self.translate_properties(included_props, &|_| None);
            self.def_ana_schema_exp(
                &type_params,
                &mut all_vars,
                &mut included_spec,
                true,
                &included_props,
                included_exp,
            );
        }
        // Store the results back to the schema entry.
        {
            let entry = self
                .parent
                .spec_schema_table
                .get_mut(&name)
                .expect("schema defined");
            entry.all_vars = all_vars;
            entry.included_spec = included_spec;
        }

        // Now process all conditions and invariants.
        for member in &block.value.members {
            let member_loc = self.parent.to_loc(&member.loc);
            match &member.value {
                EA::SpecBlockMember_::Variable {
                    is_global: false, ..
                } => { /* handled during decl analysis */ }
                EA::SpecBlockMember_::Include { .. } => { /* handled above */ }
                EA::SpecBlockMember_::Let { .. } => { /* handled above */ }
                EA::SpecBlockMember_::Condition {
                    kind,
                    properties,
                    exp,
                    additional_exps,
                } => {
                    let context = SpecBlockContext::Schema(name.clone());
                    if let Some((kind, exp)) = self.extract_condition_kind(&context, kind, exp) {
                        let properties = self.translate_properties(properties, &|prop| {
                            if !is_property_valid_for_condition(&kind, prop) {
                                Some(member_loc.clone())
                            } else {
                                None
                            }
                        });
                        self.def_ana_condition(
                            &member_loc,
                            &context,
                            kind,
                            properties,
                            exp,
                            additional_exps,
                        );
                    } else {
                        // Error reported.
                    }
                }
                _ => {
                    self.parent.error(&member_loc, "item not allowed in schema");
                }
            };
        }
        self.spec_block_lets.clear();
    }
/// Analysis of schema after it is ensured that all included schemas are fully analyzed.
Analysis of schema after it is ensured that all included schemas are fully analyzed.
Analysis of schema after it is ensured that all included schemas are fully analyzed .
fn def_ana_schema_content(&mut self, name: QualifiedSymbol, block: &EA::SpecBlock) {
        let loc = self.parent.env.to_loc(&block.loc);
        let entry = self
            .parent
            .spec_schema_table
            .get(&name)
            .expect("schema defined");
        let type_params = entry.type_params.clone();
        let mut all_vars: BTreeMap<Symbol, LocalVarEntry> = entry
            .vars
            .iter()
            .map(|(n, ty)| {
                (
                    *n,
                    LocalVarEntry {
                        loc: loc.clone(),
                        type_: ty.clone(),
                        operation: None,
                    },
                )
            })
            .collect();
        let mut included_spec = Spec::default();
        // Store back all_vars computed so far (which does not include those coming from
        // included schemas). This is needed so we can analyze lets.
        {
            let entry = self
                .parent
                .spec_schema_table
                .get_mut(&name)
                .expect("schema defined");
            entry.all_vars = all_vars.clone();
        }
        // Process all lets. We need to do this before includes so we have them available
        // in schema arguments of includes. This unfortunately means we can't refer in
        // lets to variables included from schemas, but this seems to be a rare use case.
        assert!(self.spec_block_lets.is_empty());
        for member in &block.value.members {
            let member_loc = self.parent.to_loc(&member.loc);
            if let EA::SpecBlockMember_::Let {
                name: let_name,
                def,
            } = &member.value
            {
                let context = SpecBlockContext::Schema(name.clone());
                self.def_ana_let(&context, &member_loc, let_name, def);
            }
        }
        // Process all schema includes. We need to do this before we type check expressions to have
        // all variables from includes in the environment.
        for (_, included_props, included_exp) in self.iter_schema_includes(&block.value.members) {
            let included_props = self.translate_properties(included_props, &|_| None);
            self.def_ana_schema_exp(
                &type_params,
                &mut all_vars,
                &mut included_spec,
                true,
                &included_props,
                included_exp,
            );
        }
        // Store the results back to the schema entry.
        {
            let entry = self
                .parent
                .spec_schema_table
                .get_mut(&name)
                .expect("schema defined");
            entry.all_vars = all_vars;
            entry.included_spec = included_spec;
        }
        // Now process all conditions and invariants.
        for member in &block.value.members {
            let member_loc = self.parent.to_loc(&member.loc);
            match &member.value {
                EA::SpecBlockMember_::Variable {
                    is_global: false, ..
                } => { /* handled during decl analysis */ }
                EA::SpecBlockMember_::Include { .. } => { /* handled above */ }
                EA::SpecBlockMember_::Let { .. } => { /* handled above */ }
                EA::SpecBlockMember_::Condition {
                    kind,
                    properties,
                    exp,
                    additional_exps,
                } => {
                    let context = SpecBlockContext::Schema(name.clone());
                    if let Some((kind, exp)) = self.extract_condition_kind(&context, kind, exp) {
                        let properties = self.translate_properties(properties, &|prop| {
                            if !is_property_valid_for_condition(&kind, prop) {
                                Some(member_loc.clone())
                            } else {
                                None
                            }
                        });
                        self.def_ana_condition(
                            &member_loc,
                            &context,
                            kind,
                            properties,
                            exp,
                            additional_exps,
                        );
                    } else {
                        // Error reported.
                    }
                }
                _ => {
                    self.parent.error(&member_loc, "item not allowed in schema");
                }
            };
        }
        self.spec_block_lets.clear();
    }
fn def_ana_schema_content ( & mut self , name : QualifiedSymbol , block : & EA :: SpecBlock ) { let loc = self . parent . env . to_loc ( & block . loc ) ; let entry = self . parent . spec_schema_table . get ( & name ) . expect ( " " ) ; let type_params = entry . type_params . clone ( ) ; let mut all_vars : BTreeMap < Symbol , LocalVarEntry > = entry . vars . iter ( ) . map ( | ( n , ty ) | { ( * n , LocalVarEntry { loc : loc . clone ( ) , type_ : ty . clone ( ) , operation : None , } , ) } ) . collect ( ) ; let mut included_spec = Spec :: default ( ) ; // Store back all_vars computed so far (which does not include those coming from // included schemas). This is needed so we can analyze lets. { let entry = self . parent . spec_schema_table . get_mut ( & name ) . expect ( " " ) ; entry . all_vars = all_vars . clone ( ) ; } // Process all lets. We need to do this before includes so we have them available // in schema arguments of includes. This unfortunately means we can't refer in // lets to variables included from schemas, but this seems to be a rare use case. assert ! ( self spec_block_lets is_empty ( ) ) ; for member in & block . value . members { let member_loc = self . parent . to_loc ( & member . loc ) ; if let EA :: SpecBlockMember_ :: Let { name : let_name , def , } = & member . value { let context = SpecBlockContext :: Schema ( name . clone ( ) ) ; self . def_ana_let ( & context , & member_loc , let_name , def ) ; } } // Process all schema includes. We need to do this before we type check expressions to have // all variables from includes in the environment. for ( _ , included_props , included_exp ) in self . iter_schema_includes ( & block . value . members ) { let included_props = self . translate_properties ( included_props , & | _ | None ) ; self . def_ana_schema_exp ( & type_params , & mut all_vars , & mut included_spec , true , & included_props , included_exp , ) ; } // Store the results back to the schema entry. { let entry = self . parent . spec_schema_table . get_mut ( & name ) . expect ( " " ) ; entry . all_vars = all_vars ; entry . included_spec = included_spec ; } // Now process all conditions and invariants. for member in & block . value . members { let member_loc = self . parent . to_loc ( & member . loc ) ; match & member . value { EA :: SpecBlockMember_ :: Variable { is_global : false , .. } => { /* handled during decl analysis */ } EA :: SpecBlockMember_ :: Include { .. } => { /* handled above */ } EA :: SpecBlockMember_ :: Let { .. } => { /* handled above */ } EA :: SpecBlockMember_ :: Condition { kind , properties , exp , additional_exps , } => { let context = SpecBlockContext :: Schema ( name . clone ( ) ) ; if let Some ( ( kind , exp ) ) = self . extract_condition_kind ( & context , kind , exp ) { let properties = self . translate_properties ( properties , & | prop | { if ! is_property_valid_for_condition ( & kind , prop ) { Some ( member_loc . clone ( ) ) } else { None } } ) ; self . def_ana_condition ( & member_loc , & context , kind , properties , exp , additional_exps , ) ; } else { // Error reported. } } _ => { self . parent . error ( & member_loc , " " ) ; } } ; } self . spec_block_lets . clear ( ) ; }
Analysis of schema after it is ensured that all included schemas are fully analyzed.
Analysis of schema after it is ensured that all included schemas are fully analyzed .
&mut self
name
QualifiedSymbol
block
&EA::SpecBlock
&mut self
name
QualifiedSymbol
block
&EA::SpecBlock