Store type hint of declared identifiers

This commit is contained in:
George Marques 2018-05-29 23:16:53 -03:00
parent b7a00aead0
commit f7793fc5c9
No known key found for this signature in database
GPG key ID: 046BD46A3201E43D
2 changed files with 78 additions and 19 deletions

View file

@ -1098,8 +1098,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
return NULL; return NULL;
} }
CastNode *cn = alloc_node<CastNode>(); CastNode *cn = alloc_node<CastNode>();
DataType casttype; if (!_parse_type(cn->cast_type)) {
if (!_parse_type(casttype)) {
_set_error("Expected type after 'as'."); _set_error("Expected type after 'as'.");
return NULL; return NULL;
} }
@ -2510,8 +2509,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
Node *assigned = NULL; Node *assigned = NULL;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) { if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
DataType vartype; if (!_parse_type(lv->datatype)) {
if (!_parse_type(vartype)) {
_set_error("Expected type for variable."); _set_error("Expected type for variable.");
return; return;
} }
@ -3293,6 +3291,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance(); tokenizer->advance();
Vector<StringName> arguments; Vector<StringName> arguments;
Vector<DataType> argument_types;
Vector<Node *> default_values; Vector<Node *> default_values;
int fnline = tokenizer->get_token_line(); int fnline = tokenizer->get_token_line();
@ -3323,13 +3322,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance(); tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
DataType argtype; DataType argtype;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
if (!_parse_type(argtype)) { if (!_parse_type(argtype)) {
_set_error("Expected type for argument."); _set_error("Expected type for argument.");
return; return;
} }
} }
argument_types.push_back(argtype);
if (defaulting && tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) { if (defaulting && tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) {
@ -3438,9 +3438,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} }
} }
DataType return_type;
if (tokenizer->get_token() == GDScriptTokenizer::TK_FORWARD_ARROW) { if (tokenizer->get_token() == GDScriptTokenizer::TK_FORWARD_ARROW) {
DataType rettype;
if (!_parse_type(rettype, true)) { if (!_parse_type(return_type, true)) {
_set_error("Expected return type for function."); _set_error("Expected return type for function.");
return; return;
} }
@ -3454,7 +3455,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
FunctionNode *function = alloc_node<FunctionNode>(); FunctionNode *function = alloc_node<FunctionNode>();
function->name = name; function->name = name;
function->return_type = return_type;
function->arguments = arguments; function->arguments = arguments;
function->argument_types = argument_types;
function->default_values = default_values; function->default_values = default_values;
function->_static = _static; function->_static = _static;
function->line = fnline; function->line = fnline;
@ -4174,8 +4177,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) { if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
DataType vartype; if (!_parse_type(member.data_type)) {
if (!_parse_type(vartype)) {
_set_error("Expected type for class variable."); _set_error("Expected type for class variable.");
return; return;
} }
@ -4341,8 +4343,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance(); tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) { if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
DataType consttype; if (!_parse_type(constant.type)) {
if (!_parse_type(consttype)) {
_set_error("Expected type for class constant."); _set_error("Expected type for class constant.");
return; return;
} }
@ -4464,6 +4465,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
enum_dict[constant.identifier] = cn->value; enum_dict[constant.identifier] = cn->value;
} }
constant.type.has_type = true;
constant.type.kind = DataType::BUILTIN;
constant.type.builtin_type = Variant::INT;
p_class->constant_expressions.push_back(constant); p_class->constant_expressions.push_back(constant);
} }
} }
@ -4473,7 +4477,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
enum_constant.identifier = enum_name; enum_constant.identifier = enum_name;
ConstantNode *cn = alloc_node<ConstantNode>(); ConstantNode *cn = alloc_node<ConstantNode>();
cn->value = enum_dict; cn->value = enum_dict;
cn->datatype.has_type = true;
cn->datatype.kind = DataType::BUILTIN;
cn->datatype.builtin_type = Variant::DICTIONARY;
p_class->constant_expressions.push_back(enum_constant);
enum_constant.expression = cn; enum_constant.expression = cn;
enum_constant.type = cn->datatype;
p_class->constant_expressions.push_back(enum_constant); p_class->constant_expressions.push_back(enum_constant);
} }
@ -4716,15 +4725,23 @@ bool GDScriptParser::_parse_type(DataType &r_type, bool p_can_be_void) {
r_type.has_type = true; r_type.has_type = true;
switch (tokenizer->get_token()) { switch (tokenizer->get_token()) {
case GDScriptTokenizer::TK_IDENTIFIER: {
StringName id = tokenizer->get_token_identifier();
} break;
case GDScriptTokenizer::TK_BUILT_IN_TYPE: {
} break;
case GDScriptTokenizer::TK_PR_VOID: { case GDScriptTokenizer::TK_PR_VOID: {
if (!p_can_be_void) { if (!p_can_be_void) {
return false; return false;
} }
r_type.kind = DataType::BUILTIN;
r_type.builtin_type = Variant::NIL;
} break;
case GDScriptTokenizer::TK_BUILT_IN_TYPE: {
r_type.kind = DataType::BUILTIN;
r_type.builtin_type = tokenizer->get_token_type();
} break;
case GDScriptTokenizer::TK_IDENTIFIER: {
StringName id = tokenizer->get_token_identifier();
if (ClassDB::class_exists(id)) {
r_type.kind = DataType::NATIVE;
r_type.native_type = id;
}
} break; } break;
default: { default: {
return false; return false;

View file

@ -100,7 +100,7 @@ public:
Type type; Type type;
virtual DataType get_datatype() const { return DataType(); } virtual DataType get_datatype() const { return DataType(); }
virtual void set_datatype(DataType p_datatype) {} virtual void set_datatype(const DataType &p_datatype) {}
virtual ~Node() {} virtual ~Node() {}
}; };
@ -124,6 +124,7 @@ public:
Variant default_value; Variant default_value;
#endif #endif
StringName identifier; StringName identifier;
DataType data_type;
StringName setter; StringName setter;
StringName getter; StringName getter;
int line; int line;
@ -133,6 +134,7 @@ public:
struct Constant { struct Constant {
StringName identifier; StringName identifier;
Node *expression; Node *expression;
DataType type;
}; };
struct Signal { struct Signal {
@ -166,10 +168,15 @@ public:
bool _static; bool _static;
MultiplayerAPI::RPCMode rpc_mode; MultiplayerAPI::RPCMode rpc_mode;
StringName name; StringName name;
DataType return_type;
Vector<StringName> arguments; Vector<StringName> arguments;
Vector<DataType> argument_types;
Vector<Node *> default_values; Vector<Node *> default_values;
BlockNode *body; BlockNode *body;
virtual DataType get_datatype() const { return return_type; }
virtual void set_datatype(const DataType &p_datatype) { return_type = p_datatype; }
FunctionNode() { FunctionNode() {
type = TYPE_FUNCTION; type = TYPE_FUNCTION;
_static = false; _static = false;
@ -184,6 +191,7 @@ public:
Map<StringName, int> locals; Map<StringName, int> locals;
List<Node *> statements; List<Node *> statements;
Vector<StringName> variables; Vector<StringName> variables;
Vector<DataType> variable_types;
Vector<int> variable_lines; Vector<int> variable_lines;
Node *if_condition; //tiny hack to improve code completion on if () blocks Node *if_condition; //tiny hack to improve code completion on if () blocks
@ -203,6 +211,9 @@ public:
struct TypeNode : public Node { struct TypeNode : public Node {
Variant::Type vtype; Variant::Type vtype;
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
TypeNode() { type = TYPE_TYPE; } TypeNode() { type = TYPE_TYPE; }
}; };
struct BuiltInFunctionNode : public Node { struct BuiltInFunctionNode : public Node {
@ -213,6 +224,9 @@ public:
struct IdentifierNode : public Node { struct IdentifierNode : public Node {
StringName name; StringName name;
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
IdentifierNode() { type = TYPE_IDENTIFIER; } IdentifierNode() { type = TYPE_IDENTIFIER; }
}; };
@ -220,6 +234,9 @@ public:
StringName name; StringName name;
Node *assign; Node *assign;
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
LocalVarNode() { LocalVarNode() {
type = TYPE_LOCAL_VAR; type = TYPE_LOCAL_VAR;
assign = NULL; assign = NULL;
@ -228,13 +245,24 @@ public:
struct ConstantNode : public Node { struct ConstantNode : public Node {
Variant value; Variant value;
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
ConstantNode() { type = TYPE_CONSTANT; } ConstantNode() { type = TYPE_CONSTANT; }
}; };
struct ArrayNode : public Node { struct ArrayNode : public Node {
Vector<Node *> elements; Vector<Node *> elements;
ArrayNode() { type = TYPE_ARRAY; } DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
ArrayNode() {
type = TYPE_ARRAY;
datatype.has_type = true;
datatype.kind = DataType::BUILTIN;
datatype.builtin_type = Variant::ARRAY;
}
}; };
struct DictionaryNode : public Node { struct DictionaryNode : public Node {
@ -246,7 +274,15 @@ public:
}; };
Vector<Pair> elements; Vector<Pair> elements;
DictionaryNode() { type = TYPE_DICTIONARY; } DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
DictionaryNode() {
type = TYPE_DICTIONARY;
datatype.has_type = true;
datatype.kind = DataType::BUILTIN;
datatype.builtin_type = Variant::DICTIONARY;
}
}; };
struct SelfNode : public Node { struct SelfNode : public Node {
@ -312,6 +348,9 @@ public:
Operator op; Operator op;
Vector<Node *> arguments; Vector<Node *> arguments;
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
OperatorNode() { type = TYPE_OPERATOR; } OperatorNode() { type = TYPE_OPERATOR; }
}; };
@ -381,6 +420,9 @@ public:
struct CastNode : public Node { struct CastNode : public Node {
Node *source_node; Node *source_node;
DataType cast_type;
virtual DataType get_datatype() const { return cast_type; }
virtual void set_datatype(const DataType &p_datatype) { cast_type = p_datatype; }
CastNode() { type = TYPE_CAST; } CastNode() { type = TYPE_CAST; }
}; };