Add tests & semantic checks
This commit is contained in:
parent
ac5dff7717
commit
dd90bee60e
|
|
@ -111,6 +111,7 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
|
||||
public override void visit(is_pattern_expr isPatternExpr)
|
||||
{
|
||||
// TODO Patterns: convert to compilation error
|
||||
Debug.Assert(GetLocation(isPatternExpr) != PatternLocation.Unknown, "Is-pattern expression is in an unknown context");
|
||||
Debug.Assert(GetAscendant<statement_list>(isPatternExpr) != null, "Couldn't find statement list in upper nodes");
|
||||
|
||||
|
|
@ -357,7 +358,6 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
}
|
||||
}
|
||||
|
||||
// TODO Patterns: convert to compilation error
|
||||
Debug.Assert(definitionsAdded, "Couldn't add definitions");
|
||||
}
|
||||
|
||||
|
|
|
|||
5
TestSuite/errors/err0240.pas
Normal file
5
TestSuite/errors/err0240.pas
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
begin
|
||||
var s: string;
|
||||
if 'asd' is string(s) then
|
||||
Print(1);
|
||||
end.
|
||||
4
TestSuite/patterns-is-in-lambda.pas
Normal file
4
TestSuite/patterns-is-in-lambda.pas
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
begin
|
||||
var res := Arr(object(new List<integer>), object('asd'), object(1), object(2.0)).First(x -> x is string(s));
|
||||
Assert(res = 'asd');
|
||||
end.
|
||||
10
TestSuite/patterns-is-nested-if.pas
Normal file
10
TestSuite/patterns-is-nested-if.pas
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
begin
|
||||
var a:='asd';
|
||||
if (a is string(s)) and (s is string(s1)) then
|
||||
if (s1 is string(s2)) and (s2 is string(s3)) and (s3 = 'asd') then
|
||||
Assert(s3 = 'asd')
|
||||
else
|
||||
Assert(false)
|
||||
else
|
||||
Assert(false);
|
||||
end.
|
||||
20
TestSuite/patterns-is-recursive.pas
Normal file
20
TestSuite/patterns-is-recursive.pas
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
type
|
||||
Pair<T1, T2> = class
|
||||
|
||||
_a: T1; _b: T2;
|
||||
procedure Deconstruct(var a: T1; var b: T2);
|
||||
begin
|
||||
a := _a;
|
||||
b := _b;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
var p := new Pair<integer, string>;
|
||||
p._a := 1;
|
||||
p._b := 'asd';
|
||||
if p is Pair<integer, string>(integer(a), string(b)) then
|
||||
Assert((a = 1) and (b = 'asd'))
|
||||
else
|
||||
Assert(false);
|
||||
end.
|
||||
9
TestSuite/patterns-yield-test.pas
Normal file
9
TestSuite/patterns-yield-test.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
function Y1(): sequence of integer;
|
||||
begin
|
||||
if 1 is integer(i) then
|
||||
yield i;
|
||||
end;
|
||||
|
||||
begin
|
||||
Assert(System.Linq.Enumerable.SequenceEqual(Seq(1), Y1));
|
||||
end.
|
||||
|
|
@ -115,7 +115,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (genericDeduceNeeded && (candidateParameter.is_generic_parameter || candidateParameter.is_generic_type_instance))
|
||||
candidateParameter = InstantiateParameter(candidateParameter, deducedGenerics);
|
||||
|
||||
if (givenParameter != null && !AreTheSameTypes(candidateParameter, givenParameter))
|
||||
if (givenParameter != null && !AreTheSameType(candidateParameter, givenParameter))
|
||||
return false;
|
||||
|
||||
parameterTypes[i] = candidateParameter;
|
||||
|
|
@ -124,7 +124,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool AreTheSameTypes(type_node type1, type_node type2)
|
||||
private bool AreTheSameType(type_node type1, type_node type2)
|
||||
{
|
||||
return convertion_data_and_alghoritms.possible_equal_types(type1, type2);
|
||||
}
|
||||
|
|
@ -146,7 +146,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
function.parameters.Count == 2 &&
|
||||
function.parameters[0].type.is_generic_parameter &&
|
||||
function.parameters[1].type.is_generic_parameter &&
|
||||
AreTheSameTypes(function.parameters[0].type, function.parameters[1].type);
|
||||
AreTheSameType(function.parameters[0].type, function.parameters[1].type);
|
||||
}
|
||||
|
||||
private bool CheckIfParameterListElementsAreTheSame(List<type_node[]> parametersList)
|
||||
|
|
@ -158,7 +158,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
return false;
|
||||
|
||||
for (int j = 0; j < first.Length; j++)
|
||||
if (!AreTheSameTypes(first[j], parametersList[i][j]))
|
||||
if (!AreTheSameType(first[j], parametersList[i][j]))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -181,5 +181,36 @@ namespace PascalABCCompiler.TreeConverter
|
|||
return genericNode as type_node;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<int> GenericParameterIndices(SemanticTree.ITypeNode node)
|
||||
{
|
||||
if (node.is_generic_parameter)
|
||||
yield return (node as type_node).generic_param_index;
|
||||
|
||||
if (node is generic_instance_type_node genericNode)
|
||||
foreach (var index in genericNode.instance_params.Aggregate(
|
||||
Enumerable.Empty<int>(),
|
||||
(indices, nextNode) => indices.Concat(GenericParameterIndices(nextNode)))
|
||||
.Distinct())
|
||||
yield return index;
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
private parameter GetSelfParameter(function_node node) => node.parameters.FirstOrDefault(x => IsSelfParameter(x));
|
||||
|
||||
/// <summary>
|
||||
/// Проводит проверки, общие для экземплярных деконструкторов и расширений
|
||||
/// </summary>
|
||||
/// <param name="deconstructor"></param>
|
||||
private void ExecuteCommonChecks(common_function_node deconstructor)
|
||||
{
|
||||
if (deconstructor.return_value_type != null)
|
||||
AddError(deconstructor.loc, "DECONSTRUCTOR_SOULD_BE_A_PROCEDURE");
|
||||
|
||||
foreach (var parameter in deconstructor.parameters.Where(x => !IsSelfParameter(x)))
|
||||
if (parameter.parameter_type != SemanticTree.parameter_type.var && parameter is common_parameter p)
|
||||
AddError(p.loc, "DECONSTRUCTION_PARAMETERS_SHOULD_HAVE_VAR_MODIFIER");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12171,7 +12171,44 @@ namespace PascalABCCompiler.TreeConverter
|
|||
hard_node_test_and_visit(_procedure_definition.proc_header);
|
||||
}
|
||||
//\lroman//
|
||||
|
||||
|
||||
|
||||
// Patterns
|
||||
|
||||
if (context.top_function != null &&
|
||||
context.top_function is common_namespace_function_node commonNode &&
|
||||
commonNode.name.ToLower() == compiler_string_consts.deconstruct_method_name)
|
||||
{
|
||||
var deconstructor = commonNode;
|
||||
|
||||
// TODO Patterns: add warning for non-extension deconstruct
|
||||
if (!deconstructor.is_extension_method)
|
||||
{
|
||||
//AddWarning();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (deconstructor.is_generic_function &&
|
||||
deconstructor.generic_parameters_count != GenericParameterIndices(GetSelfParameter(deconstructor).type).Count())
|
||||
AddError(get_location(_procedure_definition), "DECONSTRUCTOR_GENERIC_PARAMETERS_SHOULD_BE_DEFINED_BY_SELF_PARAMETER");
|
||||
|
||||
ExecuteCommonChecks(deconstructor);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.top_function != null &&
|
||||
context.top_function is common_method_node methodNode &&
|
||||
methodNode.name.ToLower() == compiler_string_consts.deconstruct_method_name)
|
||||
{
|
||||
var deconstructor = methodNode;
|
||||
|
||||
if (deconstructor.is_generic_function)
|
||||
AddError(get_location(_procedure_definition), "INSTANCE_DECONSTRUCTORS_CANNOT_BE_GENERIC");
|
||||
|
||||
ExecuteCommonChecks(deconstructor);
|
||||
}
|
||||
|
||||
// !Patterns
|
||||
|
||||
//ssyy
|
||||
if (context.converted_template_type != null)
|
||||
|
|
@ -12765,7 +12802,6 @@ namespace PascalABCCompiler.TreeConverter
|
|||
pa.source_context = _procedure_header.source_context;
|
||||
_procedure_header.proc_attributes.proc_attributes.Add(pa);
|
||||
}
|
||||
|
||||
weak_node_test_and_visit(_procedure_header.proc_attributes);
|
||||
with_class_name = false;
|
||||
CheckOverrideOrReintroduceExpectedWarning(get_location(_procedure_header));
|
||||
|
|
|
|||
Loading…
Reference in a new issue