fn parse(&mut self, items: impl Iterator<Item = &'a mut syn::ImplItem>) -> Result<()> {
        for items in items {
            match items {
                syn::ImplItem::Const(c) => {
                    let attr = PhpConstAttribute::from_attributes(&c.attrs)?;
                    let name = c.ident.rename(self.rename_constants);
                    let name = attr.rename.rename(name);
                    let docs = get_docs(&attr.attrs)?;
                    c.attrs.retain(|attr| !attr.path().is_ident("php"));

                    self.constants.push(Constant {
                        name,
                        ident: &c.ident,
                        docs,
                    });
                }
                syn::ImplItem::Fn(method) => {
                    let attr = PhpFunctionImplAttribute::from_attributes(&method.attrs)?;
                    let name = method.sig.ident.rename_method(self.rename_methods);
                    let name = attr.rename.rename(name);
                    let docs = get_docs(&attr.attrs)?;
                    method.attrs.retain(|attr| !attr.path().is_ident("php"));

                    let opts = MethodArgs::new(name, attr);
                    let args = Args::parse_from_fnargs(method.sig.inputs.iter(), opts.defaults)?;
                    let mut func = Function::new(&method.sig, opts.name, args, opts.optional, docs);

                    let mut modifiers: HashSet<MethodModifier> = HashSet::new();

                    if matches!(opts.ty, MethodTy::Constructor) {
                        if self.constructor.replace(func).is_some() {
                            bail!(method => "Only one constructor can be provided per class.");
                        }
                    } else {
                        let call_type = CallType::Method {
                            class: self.path,
                            receiver: if func.args.receiver.is_some() {
                                // `&self` or `&mut self`
                                MethodReceiver::Class
                            } else if func
                                .args
                                .typed
                                .first()
                                .is_some_and(|arg| arg.name == "self_")
                            {
                                // `self_: &[mut] ZendClassObject<Self>`
                                // Need to remove arg from argument list
                                func.args.typed.pop();
                                MethodReceiver::ZendClassObject
                            } else {
                                modifiers.insert(MethodModifier::Static);
                                // Static method
                                MethodReceiver::Static
                            },
                        };
                        if matches!(opts.ty, MethodTy::Abstract) {
                            modifiers.insert(MethodModifier::Abstract);
                        }

                        let builder = func.function_builder(call_type);

                        self.functions.push(FnBuilder {
                            builder,
                            vis: opts.vis,
                            modifiers,
                        });
                    }
                }
                _ => {}
            }
        }
        Ok(())
    }
Parses an impl block from `items`, populating `self`.
crates/macros/src/impl_.rs