fix #1063
This commit is contained in:
parent
7fdcfc0005
commit
a281e4b8d5
|
|
@ -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;
|
||||
|
|
|
|||
12
TestSuite/errors/err0263.pas
Normal file
12
TestSuite/errors/err0263.pas
Normal 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.
|
||||
12
TestSuite/errors/err0264.pas
Normal file
12
TestSuite/errors/err0264.pas
Normal 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.
|
||||
12
TestSuite/errors/err0265.pas
Normal file
12
TestSuite/errors/err0265.pas
Normal 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.
|
||||
13
TestSuite/errors/err0266.pas
Normal file
13
TestSuite/errors/err0266.pas
Normal 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
13
TestSuite/where4.pas
Normal 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
12
TestSuite/where5.pas
Normal 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
13
TestSuite/where6.pas
Normal 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
13
TestSuite/where7.pas
Normal 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.
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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}'
|
||||
|
|
|
|||
|
|
@ -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}'
|
||||
|
|
|
|||
|
|
@ -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}'
|
||||
|
|
|
|||
Loading…
Reference in a new issue