From 04cb3c9eb13b3824f676bc29e037802bffc3bdac Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 25 Aug 2015 20:45:51 -0300 Subject: Ability to edit all kinds of arrays from the property editor. Yes, I'm trying to convince you to test the alpha release by adding all these now :) --- modules/gdscript/gd_parser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index f7aaaf7ee..283b50f96 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2625,14 +2625,14 @@ void GDParser::_parse_class(ClassNode *p_class) { Node *subexpr=NULL; - subexpr = _parse_and_reduce_expression(p_class,false); + subexpr = _parse_and_reduce_expression(p_class,false,autoexport); if (!subexpr) return; member.expression=subexpr; if (autoexport) { - if (subexpr->type==Node::TYPE_ARRAY) { + if (1)/*(subexpr->type==Node::TYPE_ARRAY) { member._export.type=Variant::ARRAY; @@ -2640,7 +2640,7 @@ void GDParser::_parse_class(ClassNode *p_class) { member._export.type=Variant::DICTIONARY; - } else { + } else*/ { if (subexpr->type!=Node::TYPE_CONSTANT) { -- cgit v1.2.3-70-g09d2 From 319cc7e3aec12fee28b3ea750d5ce1bf7a27bd8d Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 30 Aug 2015 11:50:10 -0300 Subject: detect node and variable assignments in _ready, _init, etc for further code completion --- modules/gdscript/gd_editor.cpp | 54 +++++++++++++++++++++++++++- modules/gdscript/gd_parser.cpp | 82 ++++++++++++++++++++++++++++++++++++------ modules/gdscript/gd_parser.h | 2 ++ 3 files changed, 127 insertions(+), 11 deletions(-) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index 7cb9882f3..0d986e92a 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -998,6 +998,44 @@ static bool _guess_identifier_type_in_block(GDCompletionContext& context,int p_l return false; } + +static bool _guess_identifier_from_assignment_in_function(GDCompletionContext& context,const StringName& p_identifier, const StringName& p_function,GDCompletionIdentifier &r_type) { + + const GDParser::FunctionNode* func=NULL; + for(int i=0;ifunctions.size();i++) { + if (context._class->functions[i]->name==p_function) { + func=context._class->functions[i]; + break; + } + } + + if (!func) + return false; + + for(int i=0;ibody->statements.size();i++) { + + + + if (func->body->statements[i]->type==GDParser::BlockNode::TYPE_OPERATOR) { + const GDParser::OperatorNode *op = static_cast(func->body->statements[i]); + if (op->op==GDParser::OperatorNode::OP_ASSIGN) { + + if (op->arguments.size() && op->arguments[0]->type==GDParser::Node::TYPE_IDENTIFIER) { + + const GDParser::IdentifierNode *id = static_cast(op->arguments[0]); + + if (id->name==p_identifier) { + + return _guess_expression_type(context,op->arguments[1],func->body->statements[i]->line,r_type); + } + } + } + } + } + + return false; +} + static bool _guess_identifier_type(GDCompletionContext& context,int p_line,const StringName& p_identifier,GDCompletionIdentifier &r_type) { //go to block first @@ -1089,8 +1127,22 @@ static bool _guess_identifier_type(GDCompletionContext& context,int p_line,const r_type=_get_type_from_pinfo(context._class->variables[i]._export); return true; } else if (context._class->variables[i].expression) { - return _guess_expression_type(context,context._class->variables[i].expression,context._class->variables[i].line,r_type); + + bool rtype = _guess_expression_type(context,context._class->variables[i].expression,context._class->variables[i].line,r_type); + if (rtype && r_type.type!=Variant::NIL) + return true; + //return _guess_expression_type(context,context._class->variables[i].expression,context._class->variables[i].line,r_type); } + + //try to guess from assignment in construtor or _ready + if (_guess_identifier_from_assignment_in_function(context,p_identifier,"_ready",r_type)) + return true; + if (_guess_identifier_from_assignment_in_function(context,p_identifier,"_enter_tree",r_type)) + return true; + if (_guess_identifier_from_assignment_in_function(context,p_identifier,"_init",r_type)) + return true; + + return false; } } } diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 283b50f96..571d34095 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -170,6 +170,7 @@ void GDParser::_make_completable_call(int p_arg) { completion_line=tokenizer->get_token_line(); completion_argument=p_arg; completion_block=current_block; + completion_found=true; tokenizer->advance(); } @@ -190,6 +191,7 @@ bool GDParser::_get_completable_identifier(CompletionType p_type,StringName& ide completion_function=current_function; completion_line=tokenizer->get_token_line(); completion_block=current_block; + completion_found=true; tokenizer->advance(); if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) { @@ -1414,6 +1416,20 @@ GDParser::Node* GDParser::_parse_and_reduce_expression(Node *p_parent,bool p_sta return expr; } +bool GDParser::_recover_from_completion() { + + if (!completion_found) { + return false; //can't recover if no completion + } + //skip stuff until newline + while(tokenizer->get_token()!=GDTokenizer::TK_NEWLINE && tokenizer->get_token()!=GDTokenizer::TK_EOF) { + tokenizer->advance(); + } + completion_found=false; + error_set=false; + return true; +} + void GDParser::_parse_block(BlockNode *p_block,bool p_static) { int indent_level = tab_level.back()->get(); @@ -1511,8 +1527,14 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { Node *subexpr=NULL; subexpr = _parse_and_reduce_expression(p_block,p_static); - if (!subexpr) + if (!subexpr) { + if (_recover_from_completion()) { + break; + } return; + } + + lv->assign=subexpr; assigned=subexpr; @@ -1543,8 +1565,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { tokenizer->advance(); Node *condition = _parse_and_reduce_expression(p_block,p_static); - if (!condition) + if (!condition) { + if (_recover_from_completion()) { + break; + } return; + } ControlFlowNode *cf_if = alloc_node(); @@ -1598,8 +1624,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { //condition Node *condition = _parse_and_reduce_expression(p_block,p_static); - if (!condition) + if (!condition) { + if (_recover_from_completion()) { + break; + } return; + } cf_else->arguments.push_back(condition); cf_else->cf_type=ControlFlowNode::CF_IF; @@ -1660,8 +1690,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { tokenizer->advance(); Node *condition = _parse_and_reduce_expression(p_block,p_static); - if (!condition) + if (!condition) { + if (_recover_from_completion()) { + break; + } return; + } ControlFlowNode *cf_while = alloc_node(); @@ -1706,8 +1740,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { tokenizer->advance(); Node *container = _parse_and_reduce_expression(p_block,p_static); - if (!container) + if (!container) { + if (_recover_from_completion()) { + break; + } return; + } ControlFlowNode *cf_for = alloc_node(); @@ -1771,8 +1809,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { } else { //expect expression Node *retexpr = _parse_and_reduce_expression(p_block,p_static); - if (!retexpr) + if (!retexpr) { + if (_recover_from_completion()) { + break; + } return; + } cf_return->arguments.push_back(retexpr); p_block->statements.push_back(cf_return); if (!_end_statement()) { @@ -1787,8 +1829,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { tokenizer->advance(); Node *condition = _parse_and_reduce_expression(p_block,p_static); - if (!condition) + if (!condition) { + if (_recover_from_completion()) { + break; + } return; + } AssertNode *an = alloc_node(); an->condition=condition; p_block->statements.push_back(an); @@ -1801,8 +1847,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { default: { Node *expression = _parse_and_reduce_expression(p_block,p_static,false,true); - if (!expression) + if (!expression) { + if (_recover_from_completion()) { + break; + } return; + } p_block->statements.push_back(expression); if (!_end_statement()) { _set_error("Expected end of statement after expression."); @@ -2626,8 +2676,12 @@ void GDParser::_parse_class(ClassNode *p_class) { Node *subexpr=NULL; subexpr = _parse_and_reduce_expression(p_class,false,autoexport); - if (!subexpr) + if (!subexpr) { + if (_recover_from_completion()) { + break; + } return; + } member.expression=subexpr; @@ -2756,8 +2810,12 @@ void GDParser::_parse_class(ClassNode *p_class) { Node *subexpr=NULL; subexpr = _parse_and_reduce_expression(p_class,true,true); - if (!subexpr) + if (!subexpr) { + if (_recover_from_completion()) { + break; + } return; + } if (subexpr->type!=Node::TYPE_CONSTANT) { _set_error("Expected constant expression"); @@ -2852,6 +2910,7 @@ Error GDParser::parse_bytecode(const Vector &p_bytecode,const String& p completion_class=NULL; completion_function=NULL; completion_block=NULL; + completion_found=false; current_block=NULL; current_class=NULL; current_function=NULL; @@ -2874,6 +2933,7 @@ Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_ju completion_class=NULL; completion_function=NULL; completion_block=NULL; + completion_found=false; current_block=NULL; current_class=NULL; @@ -2917,6 +2977,8 @@ void GDParser::clear() { current_block=NULL; current_class=NULL; + completion_found=false; + current_function=NULL; validating=false; diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index fd8a2576f..134279b6d 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -419,10 +419,12 @@ private: BlockNode *completion_block; int completion_line; int completion_argument; + bool completion_found; PropertyInfo current_export; void _set_error(const String& p_error, int p_line=-1, int p_column=-1); + bool _recover_from_completion(); bool _parse_arguments(Node* p_parent, Vector& p_args, bool p_static, bool p_can_codecomplete=false); -- cgit v1.2.3-70-g09d2 From f34c3e249ba7b28aec451d62d5b44f31349eaa29 Mon Sep 17 00:00:00 2001 From: crr0004 Date: Wed, 2 Sep 2015 13:56:51 +1000 Subject: Fixes editor freeze --- modules/gdscript/gd_parser.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'modules/gdscript/gd_parser.cpp') diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 571d34095..9c39051b7 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -1422,11 +1422,15 @@ bool GDParser::_recover_from_completion() { return false; //can't recover if no completion } //skip stuff until newline - while(tokenizer->get_token()!=GDTokenizer::TK_NEWLINE && tokenizer->get_token()!=GDTokenizer::TK_EOF) { + while(tokenizer->get_token()!=GDTokenizer::TK_NEWLINE && tokenizer->get_token()!=GDTokenizer::TK_EOF && tokenizer->get_token()!=GDTokenizer::TK_ERROR) { tokenizer->advance(); } completion_found=false; error_set=false; + if(tokenizer->get_token() == GDTokenizer::TK_ERROR){ + error_set = true; + } + return true; } -- cgit v1.2.3-70-g09d2