fn emit_prop_expr(
    e: &mut Emitter,
    env: &Env,
    nullflavor: &ast_defs::OgNullFlavor,
    stack_index: StackIndex,
    prop: &tast::Expr,
    null_coalesce_assignment: bool,
) -> Result<(MemberKey, InstrSeq, StackIndex)> {
    let mk = match &prop.1 {
        tast::Expr_::Id(id) => {
            let ast_defs::Id(pos, name) = &**id;
            if name.starts_with("$") {
                MemberKey::PL(get_local(e, env, pos, name)?)
            } else {
                // Special case for known property name

                // TODO(hrust) enable `let pid = prop::Type::from_ast_name(name);`,
                // `from_ast_name` should be able to accpet Cow<str>
                let pid: prop::Type = string_utils::strip_global_ns(&name).to_string().into();
                match nullflavor {
                    ast_defs::OgNullFlavor::OGNullthrows => MemberKey::PT(pid),
                    ast_defs::OgNullFlavor::OGNullsafe => MemberKey::QT(pid),
                }
            }
        }
        // Special case for known property name
        tast::Expr_::String(name) => {
            // TODO(hrust) enable `let pid = prop::Type::from_ast_name(name);`,
            // `from_ast_name` should be able to accpet Cow<str>
            let pid: prop::Type = string_utils::strip_global_ns(&name).to_string().into();
            match nullflavor {
                ast_defs::OgNullFlavor::OGNullthrows => MemberKey::PT(pid),
                ast_defs::OgNullFlavor::OGNullsafe => MemberKey::QT(pid),
            }
        }
        tast::Expr_::Lvar(lid) if !(is_local_this(env, &lid.1)) => {
            MemberKey::PL(get_local(e, env, &lid.0, local_id::get_name(&lid.1))?)
        }
        _ => {
            // General case
            MemberKey::PC(stack_index)
        }
    };
    // For nullsafe access, insist that property is known
    Ok(match mk {
        MemberKey::PL(_) | MemberKey::PC(_)
            if nullflavor.eq(&ast_defs::OgNullFlavor::OGNullsafe) =>
        {
            return Err(emit_fatal::raise_fatal_parse(
                &prop.0,
                "?-> can only be used with scalar property names",
            ))
        }
        MemberKey::PC(_) => (mk, emit_expr(e, env, prop)?, 1),
        MemberKey::PL(local) if null_coalesce_assignment => {
            (MemberKey::PC(stack_index), instr::cgetl(local), 1)
        }
        _ => (mk, instr::empty(), 0),
    })
}
// Get the member key for a property, and return any instructions and
// the size of the stack in the case that the property cannot be
// placed inline in the instruction.
Get the member key for a property, and return any instructions and
the size of the stack in the case that the property cannot be
placed inline in the instruction.
Get the member key for a property and return any instructions and the size of the stack in the case that the property cannot be placed inline in the instruction .
fn emit_prop_expr(
    e: &mut Emitter,
    env: &Env,
    nullflavor: &ast_defs::OgNullFlavor,
    stack_index: StackIndex,
    prop: &tast::Expr,
    null_coalesce_assignment: bool,
) -> Result<(MemberKey, InstrSeq, StackIndex)> {
    let mk = match &prop.1 {
        tast::Expr_::Id(id) => {
            let ast_defs::Id(pos, name) = &**id;
            if name.starts_with("$") {
                MemberKey::PL(get_local(e, env, pos, name)?)
            } else {
                // Special case for known property name
                // TODO(hrust) enable `let pid = prop::Type::from_ast_name(name);`,
                // `from_ast_name` should be able to accpet Cow<str>
                let pid: prop::Type = string_utils::strip_global_ns(&name).to_string().into();
                match nullflavor {
                    ast_defs::OgNullFlavor::OGNullthrows => MemberKey::PT(pid),
                    ast_defs::OgNullFlavor::OGNullsafe => MemberKey::QT(pid),
                }
            }
        }
        // Special case for known property name
        tast::Expr_::String(name) => {
            // TODO(hrust) enable `let pid = prop::Type::from_ast_name(name);`,
            // `from_ast_name` should be able to accpet Cow<str>
            let pid: prop::Type = string_utils::strip_global_ns(&name).to_string().into();
            match nullflavor {
                ast_defs::OgNullFlavor::OGNullthrows => MemberKey::PT(pid),
                ast_defs::OgNullFlavor::OGNullsafe => MemberKey::QT(pid),
            }
        }
        tast::Expr_::Lvar(lid) if !(is_local_this(env, &lid.1)) => {
            MemberKey::PL(get_local(e, env, &lid.0, local_id::get_name(&lid.1))?)
        }
        _ => {
            // General case
            MemberKey::PC(stack_index)
        }
    };
    // For nullsafe access, insist that property is known
    Ok(match mk {
        MemberKey::PL(_) | MemberKey::PC(_)
            if nullflavor.eq(&ast_defs::OgNullFlavor::OGNullsafe) =>
        {
            return Err(emit_fatal::raise_fatal_parse(
                &prop.0,
                "?-> can only be used with scalar property names",
            ))
        }
        MemberKey::PC(_) => (mk, emit_expr(e, env, prop)?, 1),
        MemberKey::PL(local) if null_coalesce_assignment => {
            (MemberKey::PC(stack_index), instr::cgetl(local), 1)
        }
        _ => (mk, instr::empty(), 0),
    })
}
fn emit_prop_expr ( e : & mut Emitter , env : & Env , nullflavor : & ast_defs :: OgNullFlavor , stack_index : StackIndex , prop : & tast :: Expr , null_coalesce_assignment : bool , ) -> Result < ( MemberKey , InstrSeq , StackIndex ) > { let mk = match & prop . 1 { tast :: Expr_ :: Id ( id ) => { let ast_defs :: Id ( pos , name ) = & * * id ; if name . starts_with ( " " ) { MemberKey :: PL ( get_local ( e , env , pos , name ) ? ) } else { // Special case for known property name // TODO(hrust) enable `let pid = prop::Type::from_ast_name(name);`, // `from_ast_name` should be able to accpet Cow<str> let pid : prop :: Type = string_utils :: strip_global_ns ( & name ) . to_string ( ) . into ( ) ; match nullflavor { ast_defs :: OgNullFlavor :: OGNullthrows => MemberKey :: PT ( pid ) , ast_defs :: OgNullFlavor :: OGNullsafe => MemberKey :: QT ( pid ) , } } } // Special case for known property name tast :: Expr_ :: String ( name ) => { // TODO(hrust) enable `let pid = prop::Type::from_ast_name(name);`, // `from_ast_name` should be able to accpet Cow<str> let pid : prop :: Type = string_utils :: strip_global_ns ( & name ) . to_string ( ) . into ( ) ; match nullflavor { ast_defs :: OgNullFlavor :: OGNullthrows => MemberKey :: PT ( pid ) , ast_defs :: OgNullFlavor :: OGNullsafe => MemberKey :: QT ( pid ) , } } tast :: Expr_ :: Lvar ( lid ) if ! ( is_local_this ( env , & lid . 1 ) ) => { MemberKey :: PL ( get_local ( e , env , & lid . 0 , local_id :: get_name ( & lid . 1 ) ) ? ) } _ => { // General case MemberKey :: PC ( stack_index ) } } ; // For nullsafe access, insist that property is known Ok ( match mk { MemberKey :: PL ( _ ) | MemberKey :: PC ( _ ) if nullflavor . eq ( & ast_defs :: OgNullFlavor :: OGNullsafe ) => { return Err ( emit_fatal :: raise_fatal_parse ( & prop . 0 , " " , ) ) } MemberKey :: PC ( _ ) => ( mk , emit_expr ( e , env , prop ) ? , 1 ) , MemberKey :: PL ( local ) if null_coalesce_assignment => { ( MemberKey :: PC ( stack_index ) , instr :: cgetl ( local ) , 1 ) } _ => ( mk , instr :: empty ( ) , 0 ) , } ) }
Get the member key for a property, and return any instructions and
the size of the stack in the case that the property cannot be
placed inline in the instruction.
Get the member key for a property and return any instructions and the size of the stack in the case that the property cannot be placed inline in the instruction .
e
&mut Emitter
env
&Env
nullflavor
&ast_defs::OgNullFlavor
stack_index
StackIndex
prop
&tast::Expr
null_coalesce_assignment
bool