Add auto-completion for DRC rule function calls.

This commit is contained in:
Jeff Young 2020-07-22 21:27:38 +01:00
parent 70b98c3b49
commit 86c9adbcba
4 changed files with 90 additions and 79 deletions

View File

@ -24,6 +24,7 @@
#include <fctsys.h>
#include <scintilla_tricks.h>
#include <wx/stc/stc.h>
#include <gal/color4d.h>
#include <dialog_shim.h>
@ -190,7 +191,10 @@ void SCINTILLA_TRICKS::DoAutocomplete( const wxString& aPartial, const wxArraySt
{
// NB: tokens MUST be in alphabetical order because the Scintilla engine is going
// to do a binary search on them
matchedTokens.Sort();
matchedTokens.Sort( []( const wxString& first, const wxString& second ) -> int
{
return first.CmpNoCase( second );
});
m_te->AutoCompShow( aPartial.size(), wxJoin( matchedTokens, ' ' ) );
}

View File

@ -23,6 +23,7 @@
#include <widgets/paged_dialog.h>
#include <pcb_edit_frame.h>
#include <pcb_expr_evaluator.h>
#include <project.h>
#include <tool/tool_manager.h>
#include <drc/drc.h>
@ -31,6 +32,7 @@
#include <scintilla_tricks.h>
#include <drc/drc_rule_parser.h>
PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) :
PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ),
m_Parent( aParent ),
@ -46,6 +48,7 @@ PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFr
m_textEditor->StyleSetFont( i, fixedFont );
m_textEditor->Bind( wxEVT_STC_CHARADDED, &PANEL_SETUP_RULES::onScintillaCharAdded, this );
m_textEditor->Bind( wxEVT_STC_AUTOCOMP_CHAR_DELETED, &PANEL_SETUP_RULES::onScintillaCharAdded, this );
}
@ -205,6 +208,11 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
for( const wxString& propName : propNames )
tokens += " " + propName;
PCB_EXPR_BUILTIN_FUNCTIONS& functions = PCB_EXPR_BUILTIN_FUNCTIONS::Instance();
for( const wxString& funcSig : functions.GetSignatures() )
tokens += " " + funcSig;
}
}

View File

@ -28,39 +28,7 @@
#include "class_board.h"
#include "pcb_expr_evaluator.h"
class PCB_EXPR_BUILTIN_FUNCTIONS
{
public:
using FPTR = LIBEVAL::UCODE::FUNC_PTR;
PCB_EXPR_BUILTIN_FUNCTIONS();
static PCB_EXPR_BUILTIN_FUNCTIONS& Instance()
{
static PCB_EXPR_BUILTIN_FUNCTIONS self;
return self;
}
std::string tolower( const std::string& str ) const
{
std::string rv;
std::transform( str.begin(), str.end(), rv.begin(), ::tolower );
return rv;
}
FPTR Get( const std::string &name ) const
{
auto it = m_funcs.find( name );
if( it == m_funcs.end() )
return nullptr;
return it->second;
}
private:
std::map<std::string, FPTR> m_funcs;
static void onLayer( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self )
{
@ -92,6 +60,7 @@ private:
result->Set( 1.0 );
}
static void isPlated( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self )
{
LIBEVAL::VALUE* result = aCtx->AllocValue();
@ -106,13 +75,19 @@ private:
if( pad && pad->GetAttribute() == PAD_ATTRIB_STANDARD )
result->Set( 1.0 );
}
};
PCB_EXPR_BUILTIN_FUNCTIONS::PCB_EXPR_BUILTIN_FUNCTIONS()
{
m_funcs[ "onlayer" ] = onLayer;
m_funcs[ "isplated" ] = isPlated;
auto registerFunc = [&]( const wxString& funcSignature, FPTR funcPtr )
{
wxString funcName = funcSignature.BeforeFirst( '(' );
m_funcs[ std::string( funcName.Lower() ) ] = std::move( funcPtr );
m_funcSigs.Add( funcSignature );
};
registerFunc( "onLayer('x')", onLayer );
registerFunc( "isPlated()", isPlated );
}

View File

@ -41,9 +41,11 @@ class PCB_EXPR_UCODE : public LIBEVAL::UCODE
{
public:
virtual LIBEVAL::VAR_REF* createVarRef( LIBEVAL::COMPILER *aCompiler,
const std::string& aVar, const std::string& aField ) override;
const std::string& aVar,
const std::string& aField ) override;
virtual FUNC_PTR createFuncCall( LIBEVAL::COMPILER* aCompiler, const std::string& name ) override;
virtual FUNC_PTR createFuncCall( LIBEVAL::COMPILER* aCompiler,
const std::string& name ) override;
void SetItems( BOARD_ITEM* a, BOARD_ITEM* b = nullptr )
{
@ -75,24 +77,16 @@ public:
void SetIsEnum( bool s ) { m_isEnum = s; }
bool IsEnum() const { return m_isEnum; }
void SetType( LIBEVAL::VAR_TYPE_T type )
{
m_type = type;
}
void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; }
LIBEVAL::VAR_TYPE_T GetType() override { return m_type; }
void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop )
{
m_matchingTypes[type_hash] = prop;
}
virtual LIBEVAL::VAR_TYPE_T GetType() override
{
return m_type;
}
virtual LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx, LIBEVAL::UCODE* aUcode ) override;
BOARD_ITEM* GetObject( LIBEVAL::UCODE* aUcode ) const;
private:
@ -103,6 +97,36 @@ private:
};
class PCB_EXPR_BUILTIN_FUNCTIONS
{
public:
using FPTR = LIBEVAL::UCODE::FUNC_PTR;
PCB_EXPR_BUILTIN_FUNCTIONS();
static PCB_EXPR_BUILTIN_FUNCTIONS& Instance()
{
static PCB_EXPR_BUILTIN_FUNCTIONS self;
return self;
}
LIBEVAL::UCODE::FUNC_PTR Get( const std::string &name )
{
return m_funcs[ name ];
}
const wxArrayString GetSignatures() const
{
return m_funcSigs;
}
private:
std::map<std::string, LIBEVAL::UCODE::FUNC_PTR> m_funcs;
wxArrayString m_funcSigs;
};
class PCB_EXPR_COMPILER : public LIBEVAL::COMPILER
{
public: