static readonly properties as default parameters

This commit is contained in:
Ivan Bondarev 2023-05-17 21:06:17 +02:00
parent d57df31aec
commit 3ba13285b6
13 changed files with 163 additions and 5 deletions

View file

@ -3470,7 +3470,12 @@ namespace PascalABCCompiler.PCU
{
return new compiled_static_method_call_as_constant(CreateCompiledStaticMethodCall(), null);
}
private common_static_method_call_as_constant CreateCommonStaticMethodCallNodeAsConstant()
{
return new common_static_method_call_as_constant(CreateStaticMethodCall(), null);
}
private common_namespace_function_call_as_constant CreateCommonNamespaceFunctionCallNodeAsConstant()
{
common_namespace_function_call_as_constant cnfcc = new common_namespace_function_call_as_constant((common_namespace_function_call)CreateCommonNamespaceFunctionCall(), null);
@ -3510,6 +3515,8 @@ namespace PascalABCCompiler.PCU
return CreateAsNode();
case semantic_node_type.compiled_static_method_call_node_as_constant:
return CreateCompiledStaticMethodCallNodeAsConstant();
case semantic_node_type.common_static_method_call_node_as_constant:
return CreateCommonStaticMethodCallNodeAsConstant();
case semantic_node_type.common_namespace_function_call_node_as_constant:
return CreateCommonNamespaceFunctionCallNodeAsConstant();
case semantic_node_type.compiled_constructor_call_as_constant:
@ -3734,7 +3741,7 @@ namespace PascalABCCompiler.PCU
return nspr;
}
private expression_node CreateStaticMethodCall()
private common_static_method_call CreateStaticMethodCall()
{
common_method_node meth = GetMethodByOffset();
common_static_method_call cmc = new common_static_method_call(meth,null);

View file

@ -3717,7 +3717,12 @@ namespace PascalABCCompiler.PCU
{
VisitCompiledStaticMethodCall(node.method_call);
}
private void VisitCommonStaticMethodCallNodeAsConstant(common_static_method_call_as_constant node)
{
VisitCommonStaticMethodCall(node.method_call);
}
private void VisitCompiledConstructorCallAsConstant(compiled_constructor_call_as_constant node)
{
VisitCompiledConstructorCall(node.method_call);
@ -3752,6 +3757,8 @@ namespace PascalABCCompiler.PCU
VisitAsNode((as_node)en); break;
case semantic_node_type.compiled_static_method_call_node_as_constant:
VisitCompiledStaticMethodCallNodeAsConstant((compiled_static_method_call_as_constant)en); break;
case semantic_node_type.common_static_method_call_node_as_constant:
VisitCommonStaticMethodCallNodeAsConstant((common_static_method_call_as_constant)en); break;
case semantic_node_type.common_namespace_function_call_node_as_constant:
VisitCommonNamespaceFunctionCallNodeAsConstant((common_namespace_function_call_as_constant)en); break;
case semantic_node_type.compiled_constructor_call_as_constant:

View file

@ -11394,6 +11394,12 @@ namespace PascalABCCompiler.NETGenerator
{
value.MethodCall.visit(this);
}
public override void visit(ICommonStaticMethodCallNodeAsConstant value)
{
value.MethodCall.visit(this);
}
public override void visit(ICompiledConstructorCallAsConstant value)
{
value.MethodCall.visit(this);

View file

@ -655,6 +655,11 @@ namespace PascalABCCompiler.SemanticTree
public virtual void visit(ITypeOfOperatorAsConstant value)
{
}
public virtual void visit(ICommonStaticMethodCallNodeAsConstant value)
{
}
}

View file

@ -303,6 +303,8 @@ namespace PascalABCCompiler.SemanticTree
void visit(IDoubleQuestionColonExpressionNode value);
void visit(ITypeOfOperatorAsConstant value);
void visit(ICommonStaticMethodCallNodeAsConstant value);
}
}

View file

@ -1831,7 +1831,15 @@ namespace PascalABCCompiler.SemanticTree
}
}
public interface ICompiledStaticMethodCallNodeAsConstant : IConstantNode
public interface ICommonStaticMethodCallNodeAsConstant : IConstantNode
{
ICommonStaticMethodCallNode MethodCall
{
get;
}
}
public interface ICompiledStaticMethodCallNodeAsConstant : IConstantNode
{
ICompiledStaticMethodCallNode MethodCall
{

View file

@ -0,0 +1,20 @@
type TClass = class
static p: integer = 2;
static function getp: integer := p;
static property x: integer read p;
static property y: integer read getp;
end;
function f(i: integer := TClass.x): integer;
begin
Result := i;
end;
function f2(i: integer := TClass.y): integer;
begin
Result := i;
end;
begin
assert(f = 2);
assert(f2 = 2);
end.

View file

@ -0,0 +1,22 @@
unit u_defaultparams4;
type TClass = class
static p: integer = 2;
static function getp: integer := p;
static property x: integer read p;
static property y: integer read getp;
end;
function f(i: integer := TClass.x): integer;
begin
Result := i;
end;
function f2(i: integer := TClass.y): integer;
begin
Result := i;
end;
begin
assert(f = 2);
assert(f2 = 2);
end.

View file

@ -0,0 +1,5 @@
uses u_defaultparams4;
begin
assert(f = 2);
assert(f2 = 2);
end.

View file

@ -15266,6 +15266,18 @@ namespace PascalABCCompiler.TreeConverter
constant = new default_operator_node_as_constant(expr as default_operator_node, null);
else if (expr is typeof_operator && !is_const_section)
constant = new typeof_operator_as_constant(expr as typeof_operator, null);
else if (expr is common_static_method_call)
{
var csmc = expr as common_static_method_call;
var properties = new List<common_property_node>();
foreach (common_property_node cpn in csmc.function_node.cont_type.properties)
if (cpn.get_function == csmc.function_node && cpn.set_function == null)
{
constant = new common_static_method_call_as_constant(csmc, null);
break;
}
}
else
{
constant = expr as constant_node;
@ -15405,6 +15417,9 @@ namespace PascalABCCompiler.TreeConverter
case semantic_node_type.compiled_static_method_call:
constant = new compiled_static_method_call_as_constant(exprc as compiled_static_method_call, loc);
break;
case semantic_node_type.common_static_method_call:
constant = new common_static_method_call_as_constant(exprc as common_static_method_call, loc);
break;
case semantic_node_type.basic_function_call:
constant = new basic_function_call_as_constant(exprc as basic_function_call, loc);
break;

View file

@ -39,7 +39,7 @@ namespace PascalABCCompiler.TreeRealization
pinvoke_node, basic_function_call_node_as_constant, compiled_static_field_reference_as_constant,
common_namespace_event, indefinite_definition_node, indefinite_type, indefinite_function_call, indefinite_reference,
wrapped_statement, wrapped_expression, default_operator_node_as_constant, double_question_colon_expression,
typeof_operator_as_constant
typeof_operator_as_constant, common_static_method_call_node_as_constant
};
/// <summary>

View file

@ -1019,6 +1019,62 @@ namespace PascalABCCompiler.TreeRealization
}
}
public class common_static_method_call_as_constant : constant_node, SemanticTree.ICommonStaticMethodCallNodeAsConstant
{
private common_static_method_call _method_call;
public common_static_method_call method_call
{
get
{
return _method_call;
}
set
{
_method_call = value;
}
}
public common_static_method_call_as_constant(common_static_method_call method_call, location loc) :
base(method_call.type, loc)
{
_method_call = method_call;
}
SemanticTree.ICommonStaticMethodCallNode SemanticTree.ICommonStaticMethodCallNodeAsConstant.MethodCall
{
get
{
return _method_call;
}
}
public override constant_node get_constant_copy(location loc)
{
return new common_static_method_call_as_constant(this.method_call, loc);
}
/// <summary>
/// Метод для обхода дерева посетителем.
/// </summary>
/// <param name="visitor">Класс - посетитель дерева.</param>
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit(this);
}
/// <summary>
/// Тип узла.
/// </summary>
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.common_static_method_call_node_as_constant;
}
}
}
public class common_namespace_function_call_as_constant : constant_node, SemanticTree.ICommonNamespaceFunctionCallNodeAsConstant
{
private common_namespace_function_call _method_call;

View file

@ -1564,5 +1564,10 @@ namespace VisualPascalABCPlugins
{
throw new System.NotImplementedException();
}
public void visit(ICommonStaticMethodCallNodeAsConstant value)
{
throw new System.NotImplementedException();
}
}
}