mirror of
https://github.com/polserver/polserver
synced 2026-08-13 08:23:08 -04:00
* move compiler-generated ctor registration to within class declaration registration; update test error messages * add more ctor inheritance tests * skip "Unknown identifier" error for calling undefined ctor * add test for actual, previously crashing source * add test for actual, previously crashing source * move compiler-generator super registration to within class declaration registration * add super local var test * make register_available_generated_function private * remove ClassDeclaration::has_super_ctor This property was based on if FunctionResolver created the function, so the logic can be moved to FunctionResolver. * add core-changes * use constant for "super" string
128 lines
5.6 KiB
C++
128 lines
5.6 KiB
C++
#ifndef POLSERVER_FUNCTIONRESOLVER_H
|
|
#define POLSERVER_FUNCTIONRESOLVER_H
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <EscriptGrammar/EscriptParser.h>
|
|
|
|
#include "bscript/compiler/astbuilder/AvailableParseTree.h"
|
|
#include "bscript/compiler/file/SourceLocation.h"
|
|
#include "bscript/compiler/model/ScopableName.h"
|
|
#include "bscript/compiler/model/ScopeName.h"
|
|
#include "bscript/compiler/model/UserFunctionType.h"
|
|
#include "clib/maputil.h"
|
|
|
|
namespace Pol::Bscript::Compiler
|
|
{
|
|
class AvailableSecondPassTarget;
|
|
class ClassDeclaration;
|
|
class ClassLink;
|
|
class CompilerWorkspace;
|
|
class Function;
|
|
class FunctionLink;
|
|
class ModuleFunctionDeclaration;
|
|
class Report;
|
|
class UserFunction;
|
|
class GeneratedFunction;
|
|
|
|
class FunctionResolver
|
|
{
|
|
public:
|
|
explicit FunctionResolver( CompilerWorkspace&, Report& );
|
|
~FunctionResolver();
|
|
|
|
// Force reference to a function
|
|
void force_reference( const ScopableName& name, const SourceLocation& );
|
|
|
|
// Force reference to a class
|
|
void force_reference( const ScopeName& name, const SourceLocation& );
|
|
|
|
void register_available_user_function( const SourceLocation&,
|
|
EscriptGrammar::EscriptParser::FunctionDeclarationContext*,
|
|
bool force_reference );
|
|
|
|
void register_available_scoped_function(
|
|
const SourceLocation&, const ScopeName& scope,
|
|
EscriptGrammar::EscriptParser::FunctionDeclarationContext* );
|
|
|
|
void register_available_class_declaration(
|
|
const SourceLocation& class_loc, const ScopeName& class_name,
|
|
EscriptGrammar::EscriptParser::ClassDeclarationContext* class_ctx,
|
|
Node* top_level_statements_child_node );
|
|
|
|
void register_function_link( const ScopableName& name,
|
|
std::shared_ptr<FunctionLink> function_link );
|
|
void register_class_link( const ScopeName& name, std::shared_ptr<ClassLink> class_link );
|
|
std::string register_function_expression(
|
|
const SourceLocation&, EscriptGrammar::EscriptParser::FunctionExpressionContext* );
|
|
void register_module_function( ModuleFunctionDeclaration* );
|
|
void register_user_function( const std::string& scope, UserFunction* );
|
|
void register_class_declaration( ClassDeclaration* );
|
|
|
|
bool resolve( std::vector<std::unique_ptr<AvailableSecondPassTarget>>& user_functions_to_build );
|
|
|
|
static std::string function_expression_name( const SourceLocation& );
|
|
|
|
private:
|
|
void register_available_generated_function( const SourceLocation&, const ScopableName& name,
|
|
Node* context, UserFunctionType type );
|
|
|
|
void register_available_function_parse_tree( const SourceLocation&, const ScopableName& name,
|
|
std::unique_ptr<AvailableSecondPassTarget> apt );
|
|
void register_available_user_function_parse_tree( const SourceLocation&,
|
|
antlr4::ParserRuleContext*,
|
|
const ScopableName& name,
|
|
bool force_reference );
|
|
void register_available_class_decl_parse_tree( const SourceLocation&, antlr4::ParserRuleContext*,
|
|
const ScopeName& scope,
|
|
Node* top_level_statements_child_node );
|
|
|
|
CompilerWorkspace& workspace;
|
|
Report& report;
|
|
|
|
using FunctionMap = std::map<ScopableName, Function*>;
|
|
using ClassDeclarationMap = std::map<ScopeName, ClassDeclaration*>;
|
|
|
|
using FunctionReferenceMap = std::map<ScopableName, std::vector<std::shared_ptr<FunctionLink>>>;
|
|
using ClassReferenceMap = std::map<ScopeName, std::vector<std::shared_ptr<ClassLink>>>;
|
|
// Maps parent -> children (direct children, not all descendants)
|
|
using ClassChildrenMap = std::map<std::string, std::vector<ClassDeclaration*>, Clib::ci_cmp_pred>;
|
|
|
|
using AvailableParseTreeMap =
|
|
std::map<std::string, std::unique_ptr<AvailableSecondPassTarget>, Clib::ci_cmp_pred>;
|
|
|
|
AvailableParseTreeMap available_user_function_parse_trees;
|
|
AvailableParseTreeMap available_class_decl_parse_trees;
|
|
FunctionMap resolved_functions;
|
|
ClassDeclarationMap resolved_classes;
|
|
FunctionReferenceMap unresolved_function_links;
|
|
ClassReferenceMap unresolved_classes;
|
|
ClassChildrenMap class_children;
|
|
|
|
// Returns Function if the key's `{call_scope, name}` exists in
|
|
// `resolved_functions_by_name`, otherwise nullptr.
|
|
Function* check_existing( const ScopableName& key, bool requires_constructor ) const;
|
|
ClassDeclaration* check_existing( const ScopeName& key ) const;
|
|
|
|
// Checks if `{call_scope, name}` exists in either
|
|
// `available_user_function_parse_trees` as a function or a class (that would
|
|
// eventually provide the function) inside `available_class_decl_parse_trees`,
|
|
// using `calling_scope` for context.
|
|
bool build_if_available( std::vector<std::unique_ptr<AvailableSecondPassTarget>>& to_build_ast,
|
|
const std::string& calling_scope, const ScopableName& call );
|
|
bool build_if_available( std::vector<std::unique_ptr<AvailableSecondPassTarget>>& to_build_ast,
|
|
const ScopeName& call );
|
|
|
|
// Given a scoped name, looks for an existing function in `resolved_functions`. If found, links
|
|
// the function and returns `true`; otherwise, returns `false`.
|
|
bool resolve_if_existing( const ScopableName&, std::shared_ptr<FunctionLink>& );
|
|
bool resolve_if_existing( const ScopeName&, std::shared_ptr<ClassLink>& );
|
|
|
|
bool super_function_created( ClassDeclaration* cd ) const;
|
|
};
|
|
|
|
} // namespace Pol::Bscript::Compiler
|
|
|
|
#endif // POLSERVER_FUNCTIONRESOLVER_H
|