Store type hint of declared identifiers
This commit is contained in:
parent
b7a00aead0
commit
f7793fc5c9
2 changed files with 78 additions and 19 deletions
|
@ -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;
|
||||||
|
|
|
@ -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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue