-Fix bugs related to PoolVector crashes

-Added ability to request nodes using $Name in GDScript :)
This commit is contained in:
Juan Linietsky 2017-01-08 02:04:53 -03:00
parent 2ab83e1abb
commit 8b912d1115
5 changed files with 124 additions and 5 deletions

View file

@ -265,6 +265,92 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
tokenizer->advance();
expr=subexpr;
} else if (tokenizer->get_token()==GDTokenizer::TK_DOLLAR) {
tokenizer->advance();
String path;
bool need_identifier=true;
bool done=false;
while(!done) {
switch(tokenizer->get_token()) {
case GDTokenizer::TK_CURSOR: {
completion_cursor=StringName();
completion_type=COMPLETION_GET_NODE;
completion_class=current_class;
completion_function=current_function;
completion_line=tokenizer->get_token_line();
completion_cursor=path;
completion_argument=0;
completion_block=current_block;
completion_found=true;
tokenizer->advance();
} break;
case GDTokenizer::TK_CONSTANT: {
if (!need_identifier)
break;
if (tokenizer->get_token_constant().get_type()!=Variant::STRING) {
_set_error("Expected string constant or identifier after '$' or '/'.");
return NULL;
}
path+=String(tokenizer->get_token_constant());
tokenizer->advance();
} break;
case GDTokenizer::TK_IDENTIFIER: {
if (!need_identifier)
break;
path+=String(tokenizer->get_token_identifier());
tokenizer->advance();
need_identifier=false;
} break;
case GDTokenizer::TK_OP_DIV: {
if (need_identifier)
break;
path+="/";
tokenizer->advance();
need_identifier=true;
} break;
default: {
done=true;
break;
}
}
}
if (path=="") {
_set_error("Path expected after $.");
return NULL;
}
OperatorNode *op = alloc_node<OperatorNode>();
op->op=OperatorNode::OP_CALL;
op->arguments.push_back(alloc_node<SelfNode>());
IdentifierNode *funcname = alloc_node<IdentifierNode>();
funcname->name="get_node";
op->arguments.push_back(funcname);
ConstantNode *nodepath = alloc_node<ConstantNode>();
nodepath->value = NodePath(StringName(path));
op->arguments.push_back(nodepath);
expr=op;
} else if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
tokenizer->advance();
continue; //no point in cursor in the middle of expression

View file

@ -376,6 +376,7 @@ public:
enum CompletionType {
COMPLETION_NONE,
COMPLETION_BUILT_IN_TYPE_CONSTANT,
COMPLETION_GET_NODE,
COMPLETION_FUNCTION,
COMPLETION_IDENTIFIER,
COMPLETION_PARENT_FUNCTION,

View file

@ -460,6 +460,9 @@ void GDTokenizerText::_advance() {
case ':':
_make_token(TK_COLON); //for methods maybe but now useless.
break;
case '$':
_make_token(TK_DOLLAR); //for the get_node() shortener
break;
case '^': {
if (GETCHAR(1)=='=') {
_make_token(TK_OP_ASSIGN_BIT_XOR);

View file

@ -123,6 +123,7 @@ public:
TK_PERIOD,
TK_QUESTION_MARK,
TK_COLON,
TK_DOLLAR,
TK_NEWLINE,
TK_CONST_PI,
TK_ERROR,