This commit is contained in:
Бондарев Иван 2018-09-09 19:10:15 +02:00
parent 7fdcfc0005
commit a281e4b8d5
13 changed files with 163 additions and 4 deletions

View file

@ -216,12 +216,11 @@ function operator implicit(Self: array of (real, real)): array of Point; extensi
Self.Select(t->new Point(t[0],t[1])).ToArray;
function operator implicit(Self: array of (integer, integer)): array of Point; extensionmethod :=
Self.Select(t->new Point(t[0],t[1])).ToArray;
///---- Helpers
procedure SetLeft(Self: UIElement; l: integer); extensionmethod := Canvas.SetLeft(Self,l);
procedure SetTop(Self: UIElement; t: integer); extensionmethod := Canvas.SetTop(Self,t);
var __initialized: boolean;
procedure __InitModule;

View file

@ -0,0 +1,12 @@
type
t0=record end;
t1<T>=class
where T: record;
end;
t2<T>=class(t1<T>) end;
begin
//var a := new t2<t0>;//не обязательно чтоб вызвать ошибку
end.

View file

@ -0,0 +1,12 @@
type
t0=record end;
t1<T>=class
where T: record;
end;
t2<T>=class(t1<T>) where T: class; end;
begin
//var a := new t2<t0>;//не обязательно чтоб вызвать ошибку
end.

View file

@ -0,0 +1,12 @@
type
t0=record end;
t1<T>=class
where T: t0;
end;
t2<T>=class(t1<T>) where T: constructor; end;
begin
//var a := new t2<t0>;//не обязательно чтоб вызвать ошибку
end.

View file

@ -0,0 +1,13 @@
type
t0=record end;
t1<T1>=class
where T1: t0;
a: T1;
end;
t2<T>=class(t1<T>) where T: record; end;
begin
var a := new t2<t0>;
end.

13
TestSuite/where4.pas Normal file
View file

@ -0,0 +1,13 @@
type
t0=record
end;
t1<T>=class
where T: record;
end;
t2<T>=class(t1<T>) where T: record; end;
begin
var a := new t2<t0>;
end.

12
TestSuite/where5.pas Normal file
View file

@ -0,0 +1,12 @@
type
t0=record end;
t1<T1, T2>=class
where T1: record;
end;
t2<T>=class(t1<t0,T>) where T: record; end;
begin
var a := new t2<integer>;
end.

13
TestSuite/where6.pas Normal file
View file

@ -0,0 +1,13 @@
type
t0=record end;
t1<T1>=class
where T1: record;
a: T1;
end;
t2<T>=class(Dictionary<t1<t0>,T>) where T: record; end;
begin
var a := new t2<integer>;
end.

13
TestSuite/where7.pas Normal file
View file

@ -0,0 +1,13 @@
type
t0=record end;
t1<T1>=class
where T1: record;
a: T1;
end;
t2<T>=class(t1<T>) where T: t0; end;
begin
var a := new t2<t0>;
end.

View file

@ -3620,6 +3620,7 @@ namespace PascalABCCompiler.TreeConverter
{
context.converted_type.SetBaseType(SemanticRules.ClassBaseType);
}
context.converted_type.is_class = true;
if (_class_definition.body == null &&
(_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0))
@ -11410,11 +11411,13 @@ namespace PascalABCCompiler.TreeConverter
}
if (predefined_generic && cl_def.where_section != null && cl_def.where_section.defs.Count > 0)
AddError(get_location(cl_def.where_section), "WHERE_SECTION_NOT_ALLOWED");
visit_where_list(cl_def.where_section);
CheckWaitedRefTypes(ctn);
is_direct_type_decl = true;
hard_node_test_and_visit(_type_declaration.type_def);
check_where_from_base_class(ctn);
// frninja 28/04/16 - режем мусорные методы хелперы yield
{
var toRemove = ctn.methods.Where(m => m.is_yield_helper).ToArray();
@ -11887,6 +11890,60 @@ namespace PascalABCCompiler.TreeConverter
}
}
private void check_where_from_base_class(common_type_node ctn)
{
if (ctn.base_type != null && ctn.base_type.is_generic_type_instance && ctn.is_generic_type_definition)
{
common_type_node bctn = ctn.base_type.original_generic as common_type_node;
compiled_type_node bctn2 = ctn.base_type.original_generic as compiled_type_node;
Dictionary<string, SemanticTree.ICommonTypeNode> where_cache = new Dictionary<string, SemanticTree.ICommonTypeNode>();
foreach (SemanticTree.ICommonTypeNode t in ctn.generic_params)
{
int ind = ctn.base_type.instance_params.IndexOf(t as type_node);
if (ind != -1)
{
if (bctn != null)
where_cache.Add(bctn.generic_params[ind].name, t);
else
where_cache.Add(bctn2.generic_params[ind].name, t);
}
}
if (bctn != null && bctn.generic_params != null)
{
foreach (SemanticTree.ICommonTypeNode t in bctn.generic_params)
{
SemanticTree.ICommonTypeNode thist = null;
where_cache.TryGetValue(t.name, out thist);
if (thist == null)
continue;
if (t.is_class || t.is_value_type || t.methods.Length > 0 || t.base_type != SystemLibrary.SystemLibrary.object_type)
{
if (thist.is_class != t.is_class || thist.is_value_type != t.is_value_type && !(t.is_value_type && thist.base_type.is_value_type)
|| thist.methods.Length != t.methods.Length ||
t.base_type != thist.base_type && !type_table.is_derived(t.base_type as type_node, thist.base_type as type_node))
AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH");
}
}
}
else if (bctn2 != null && bctn2.generic_params != null)
{
foreach (compiled_type_node t in bctn2.generic_params)
{
SemanticTree.ICommonTypeNode thist = null;
where_cache.TryGetValue(t.name, out thist);
if (thist == null)
continue;
if (t.is_value_type || t.base_type != SystemLibrary.SystemLibrary.object_type)
{
if (thist.is_value_type != t.is_value_type && !(t.is_value_type && thist.base_type.is_value_type) || thist.base_type != t.base_type)
AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH");
}
}
}
}
}
private void visit_where_list(SyntaxTree.where_definition_list where_list)
{
if (where_list == null)

View file

@ -144,6 +144,7 @@ GENERIC_RECORDS_CANNOT_HAVE_EXPLICIT_LAYOUT=Generic-records can not have attribu
ATTRIBUTE_CANNOT_BE_GENERIC=Attributes cannot be generic
EXTERNAL_METHOD_CANNOT_BE_DECLARED_IN_GENERIC_TYPE=external-methods can not be declared in generic type
EXTERNAL_METHOD_CANNOT_BE_GENERIC=external-methods can not be generic
WHERE_SPECIFIER_MISMATCH=where specifier contradicts with where specifier of base class
%PREFIX%=COMPILATIONERROR_
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found
ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}'

View file

@ -139,6 +139,7 @@ GENERIC_RECORDS_CANNOT_HAVE_EXPLICIT_LAYOUT=Генерик-записи не м
ATTRIBUTE_CANNOT_BE_GENERIC=Атрибуты не могут быть генерик-классами
EXTERNAL_METHOD_CANNOT_BE_DECLARED_IN_GENERIC_TYPE=external-методы нельзя описывать в генерик-классах
EXTERNAL_METHOD_CANNOT_BE_GENERIC=external-методы не могут быть генериками
WHERE_SPECIFIER_MISMATCH=Несоответствие спецификатора whеre спецификатору where базового классе​
%PREFIX%=COMPILATIONERROR_
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека
ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'

View file

@ -137,6 +137,7 @@ GENERIC_RECORDS_CANNOT_HAVE_EXPLICIT_LAYOUT=Генерик-записи не м
ATTRIBUTE_CANNOT_BE_GENERIC=Атрибуты не могут быть генерик-классами
EXTERNAL_METHOD_CANNOT_BE_DECLARED_IN_GENERIC_TYPE=external-методы нельзя описывать в генерик-классах
EXTERNAL_METHOD_CANNOT_BE_GENERIC=external-методы не могут быть генериками
WHERE_SPECIFIER_MISMATCH=Несоответствие спецификатора whеre спецификатору where базового классе​
%PREFIX%=COMPILATIONERROR_
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Очікувався модуль, а зустріли бібліотеку
ASSEMBLY_{0}_READING_ERROR=Помилка при читанні збірки '{0}'