This commit is contained in:
Ivan Bondarev 2022-03-20 11:17:00 +01:00
parent 3fcff501b8
commit 759112e495
7 changed files with 84 additions and 13 deletions

View file

@ -0,0 +1,12 @@
//!Нельзя обратиться к нестатическому методу f1 из инициализатора статического поля
type
t1 = class
public function f1 := 0;
public static x := f1;
end;
begin
t1.x.Println;
end.

View file

@ -1947,6 +1947,43 @@ namespace PascalABCCompiler.TreeConverter
return string.Format(StringResources.Get(message, name));
}
}
public class CanNotReferenceToNonStaticFromStaticInitializer : CompilationErrorWithLocation
{
string message = "CAN_NOT_REFERENCE_TO_NONSTATIC_METHOD_{0}_FROM_STATIC_INITIALIZER";
string name;
public CanNotReferenceToNonStaticFromStaticInitializer(definition_node dn, location loc)
: base(loc)
{
string meth_name;
switch (dn.general_node_type)
{
case general_node_type.function_node:
meth_name = (dn as function_node).name;
if (meth_name.Contains(compiler_string_consts.event_add_method_prefix) ||
meth_name.Contains(compiler_string_consts.event_remove_method_prefix))
{
meth_name = meth_name.Replace(compiler_string_consts.event_add_method_prefix, "");
meth_name = meth_name.Replace(compiler_string_consts.event_remove_method_prefix, "");
message = "CAN_NOT_REFERENCE_TO_NONSTATIC_EVENT_{0}_FROM_STATIC_INITIALIZER";
}
break;
case general_node_type.variable_node:
meth_name = (dn as var_definition_node).name;
message = "CAN_NOT_REFERENCE_TO_NONSTATIC_FIELD_{0}_FROM_STATIC_INITIALIZER";
break;
default:
message = "CAN_NOT_REFERENCE_TO_NONSTATIC_{0}_FROM_INITIALIZER";
meth_name = "";
break;
}
name = meth_name;
}
public override string ToString()
{
return string.Format(StringResources.Get(message, name));
}
}
/*->*/
public class CanNotReferenceToNonStaticFieldWithType : CompilationError
{

View file

@ -332,6 +332,7 @@ namespace PascalABCCompiler.TreeConverter
is_order_independed_method_description = false;
_has_nested_functions = false;
finally_blocks_depth = 0;
static_variable_converted = false;
}
public void clear_type_prededinitions()
@ -339,6 +340,8 @@ namespace PascalABCCompiler.TreeConverter
_types_predefined.Clear();
}
public bool static_variable_converted;
public bool inStaticArea()
{
if (converted_type != null && top_function != null)

View file

@ -8949,22 +8949,27 @@ namespace PascalABCCompiler.TreeConverter
if (scope != null)
if (context.WithVariables.ContainsKey(scope))
return context.WithVariables[scope];
else
else
if (context.WithTypes.Contains(scope))
{
switch (dn.semantic_node_type)
{
case semantic_node_type.class_field: if (!(dn as class_field).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field, loc, null)); break;
case semantic_node_type.compiled_variable_definition: if (!(dn as compiled_variable_definition).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field, loc, null)); break;
case semantic_node_type.compiled_property_node:
case semantic_node_type.common_property_node: if ((dn as property_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticPropertyWithType(dn as property_node, loc, null)); break;
case semantic_node_type.compiled_function_node:
case semantic_node_type.common_method_node: if ((dn as function_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticMethodWithType((dn as function_node).name, loc)); break;
}
}
if (context.static_variable_converted)
{
switch (dn.semantic_node_type)
{
case semantic_node_type.class_field : if (!(dn as class_field).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field,loc,null)); break;
case semantic_node_type.compiled_variable_definition : if (!(dn as compiled_variable_definition).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field,loc,null)); break;
case semantic_node_type.compiled_property_node:
case semantic_node_type.common_property_node : if ((dn as property_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticPropertyWithType(dn as property_node,loc,null)); break;
case semantic_node_type.compiled_function_node:
case semantic_node_type.common_method_node: if ((dn as function_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticMethodWithType((dn as function_node).name,loc)); break;
}
AddError(new CanNotReferenceToNonStaticFromStaticInitializer(dn, loc));
return null;
}
if (context.inStaticArea())
else if (context.inStaticArea())
{
AddError(new CanNotReferenceToNonStaticFromStatic(dn,loc));
AddError(new CanNotReferenceToNonStaticFromStatic(dn, loc));
return null;
}
else
@ -16775,6 +16780,7 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(SyntaxTree.var_def_statement _var_def_statement)
{
var_def_statement_converting = true;
if (_var_def_statement.vars_type != null && _var_def_statement.vars_type is procedure_header)
{
var ph = _var_def_statement.vars_type as procedure_header;
@ -16786,7 +16792,7 @@ namespace PascalABCCompiler.TreeConverter
}
}
context.static_variable_converted = _var_def_statement.var_attr == SyntaxTree.definition_attribute.Static ? true : false;
if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.function_lambda_definition fld)
{
if (fld.formal_parameters != null && fld.formal_parameters.params_list.Select(x => x.vars_type).Any(x=>x is lambda_inferred_type))
@ -16963,6 +16969,7 @@ namespace PascalABCCompiler.TreeConverter
if (context.converted_type != null && context.converting_block() == block_type.type_block && context.converted_type.IsStatic && _var_def_statement.var_attr != definition_attribute.Static)
AddError(get_location(_var_def_statement), "STATIC_CLASSES_CANNOT_NON_STATIC_MEMBERS");
var_def_statement_converting = false;
context.static_variable_converted = false;
if (is_event) return;
context.save_var_definitions();

View file

@ -39,6 +39,10 @@ CAN_NOT_REFERENCE_TO_NONSTATIC_METHOD_{0}_FROM_STATIC_METHOD=An object reference
CAN_NOT_REFERENCE_TO_NONSTATIC_EVENT_{0}_FROM_STATIC_METHOD=An object reference is required for the nonstatic event '{0}'
CAN_NOT_REFERENCE_TO_NONSTATIC_FIELD_{0}_FROM_STATIC_METHOD=An object reference is required for the nonstatic field '{0}'
CAN_NOT_REFERENCE_TO_NONSTATIC_{0}_FROM_STATIC=An object reference is required for the nonstatic field, method, or property '{0}'
CAN_NOT_REFERENCE_TO_NONSTATIC_METHOD_{0}_FROM_STATIC_INITIALIZER=An object reference is required for the nonstatic method '{0}'
CAN_NOT_REFERENCE_TO_NONSTATIC_EVENT_{0}_FROM_STATIC_INITIALIZER=An object reference is required for the nonstatic event '{0}'
CAN_NOT_REFERENCE_TO_NONSTATIC_FIELD_{0}_FROM_STATIC_INITIALIZER=An object reference is required for the nonstatic field '{0}'
CAN_NOT_REFERENCE_TO_NONSTATIC_{0}_FROM_STATIC_INITIALIZER=An object reference is required for the nonstatic field, method, or property '{0}'
LEFT_SIDE_CANNOT_BE_ASSIGNED_TO=Left side cannot be assigned to
STATEMENT_EXPECTED=Statement expected
EXPRESSION_IN_LOCK_STATEMENT_RETURNED_NOT_A_REFERENCE_TYPE=The type of expression is not a reference type as required by the lock statement

View file

@ -39,6 +39,10 @@ CAN_NOT_REFERENCE_TO_NONSTATIC_METHOD_{0}_FROM_STATIC_METHOD=Нельзя обр
CAN_NOT_REFERENCE_TO_NONSTATIC_EVENT_{0}_FROM_STATIC_METHOD=Нельзя обратиться к нестатическому событию {0} из статического метода
CAN_NOT_REFERENCE_TO_NONSTATIC_FIELD_{0}_FROM_STATIC_METHOD=Нельзя обратиться к нестатическому полю {0} из статического метода
CAN_NOT_REFERENCE_TO_NONSTATIC_{0}_FROM_STATIC=Нельзя обратиться к нестатическому определению {0} из статического метода
CAN_NOT_REFERENCE_TO_NONSTATIC_METHOD_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому методу {0} из инициализатора статического поля
CAN_NOT_REFERENCE_TO_NONSTATIC_EVENT_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому событию {0} из инициализатора статического поля
CAN_NOT_REFERENCE_TO_NONSTATIC_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому определению {0} из инициализатора статического поля
CAN_NOT_REFERENCE_TO_NONSTATIC_FIELD_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому полю {0} из инициализатора статического поля
LEFT_SIDE_CANNOT_BE_ASSIGNED_TO=Нельзя присвоить левой части
STATEMENT_EXPECTED=Ожидался оператор
EXPRESSION_IN_LOCK_STATEMENT_RETURNED_NOT_A_REFERENCE_TYPE=Выражение должно возвращать ссылочный тип, как того требует оператор lock

View file

@ -39,6 +39,10 @@ CAN_NOT_REFERENCE_TO_NONSTATIC_METHOD_{0}_FROM_STATIC_METHOD=Не можна з
CAN_NOT_REFERENCE_TO_NONSTATIC_EVENT_{0}_FROM_STATIC_METHOD=Не можна звернутися до нестатичної події {0} з статичного методу
CAN_NOT_REFERENCE_TO_NONSTATIC_FIELD_{0}_FROM_STATIC_METHOD=Не можна звернутися до нестатичного поля {0} з статичного методу
CAN_NOT_REFERENCE_TO_NONSTATIC_{0}_FROM_STATIC=Не можна звернутися до нестатичного визначення {0} з статичного методу
CAN_NOT_REFERENCE_TO_NONSTATIC_METHOD_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому методу {0} из инициализатора статического поля
CAN_NOT_REFERENCE_TO_NONSTATIC_EVENT_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому событию {0} из инициализатора статического поля
CAN_NOT_REFERENCE_TO_NONSTATIC_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому определению {0} из инициализатора статического поля
CAN_NOT_REFERENCE_TO_NONSTATIC_FIELD_{0}_FROM_STATIC_INITIALIZER=Нельзя обратиться к нестатическому полю {0} из инициализатора статического поля
LEFT_SIDE_CANNOT_BE_ASSIGNED_TO=Не можна присвоїти лівій частині
STATEMENT_EXPECTED=Очікувався оператор
EXPRESSION_IN_LOCK_STATEMENT_RETURNED_NOT_A_REFERENCE_TYPE=Вираз повинен повертати тип посилання, як того вимагає оператор lock