Parse a function declaration: FunctionDecl = "fun" "(" Comma ")" (":" )? ("acquires" ("," )*)? ("{" "}" | ";")
(
attributes: Vec<Attributes>,
start_loc: usize,
modifiers: Modifiers,
context: &mut Context,
)
| 1783 | // ("{" <Sequence> "}" | ";") |
| 1784 | // |
| 1785 | fn parse_function_decl( |
| 1786 | attributes: Vec<Attributes>, |
| 1787 | start_loc: usize, |
| 1788 | modifiers: Modifiers, |
| 1789 | context: &mut Context, |
| 1790 | ) -> Result<Function, Diagnostic> { |
| 1791 | let Modifiers { |
| 1792 | visibility, |
| 1793 | mut entry, |
| 1794 | native, |
| 1795 | } = modifiers; |
| 1796 | |
| 1797 | if let Some(Visibility::Script(vloc)) = visibility { |
| 1798 | let msg = format!( |
| 1799 | "'{script}' is deprecated in favor of the '{entry}' modifier. \ |
| 1800 | Replace with '{public} {entry}'", |
| 1801 | script = Visibility::SCRIPT, |
| 1802 | public = Visibility::PUBLIC, |
| 1803 | entry = ENTRY_MODIFIER, |
| 1804 | ); |
| 1805 | context |
| 1806 | .env |
| 1807 | .add_diag(diag!(Uncategorized::DeprecatedWillBeRemoved, (vloc, msg,))); |
| 1808 | if entry.is_none() { |
| 1809 | entry = Some(vloc) |
| 1810 | } |
| 1811 | } |
| 1812 | |
| 1813 | // "fun" <FunctionDefName> |
| 1814 | consume_token(context.tokens, Tok::Fun)?; |
| 1815 | let name = FunctionName(parse_identifier(context)?); |
| 1816 | let type_parameters = parse_optional_type_parameters(context)?; |
| 1817 | |
| 1818 | // "(" Comma<Parameter> ")" |
| 1819 | let parameters = parse_comma_list( |
| 1820 | context, |
| 1821 | Tok::LParen, |
| 1822 | Tok::RParen, |
| 1823 | parse_parameter, |
| 1824 | "a function parameter", |
| 1825 | )?; |
| 1826 | |
| 1827 | // (":" <Type>)? |
| 1828 | let return_type = if match_token(context.tokens, Tok::Colon)? { |
| 1829 | parse_type(context)? |
| 1830 | } else { |
| 1831 | sp(name.loc(), Type_::Unit) |
| 1832 | }; |
| 1833 | |
| 1834 | // ("acquires" (<NameAccessChain> ",")* <NameAccessChain> ","? |
| 1835 | let mut acquires = vec![]; |
| 1836 | if match_token(context.tokens, Tok::Acquires)? { |
| 1837 | let follows_acquire = |tok| matches!(tok, Tok::Semicolon | Tok::LBrace); |
| 1838 | loop { |
| 1839 | acquires.push(parse_name_access_chain(context, || { |
| 1840 | "a resource struct name" |
| 1841 | })?); |
| 1842 | if follows_acquire(context.tokens.peek()) { |
no test coverage detected