type_table.cs - изменения к ковариантности

This commit is contained in:
Mikhalkovich Stanislav 2023-02-15 12:10:28 +03:00
parent e3027f6a6a
commit 14b5fd053f
10 changed files with 69 additions and 50 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "8";
public const string Build = "3";
public const string Revision = "3237";
public const string Revision = "3239";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=8
%REVISION%=3237
%REVISION%=3239
%COREVERSION%=3
%MAJOR%=3

View file

@ -1 +1 @@
3.8.3.3237
3.8.3.3239

View file

@ -1 +1 @@
!define VERSION '3.8.3.3237'
!define VERSION '3.8.3.3239'

View file

@ -1804,7 +1804,7 @@ function Min(a, b, c: integer): integer;
function Min(a, b, c, d: integer): integer;
///-function Max(a,b,...: T): T;
/// Возвращает максиимальное из a,b,...
/// Возвращает максимальное из a,b,...
function Max<T>(params a: array of T): T;
///--
//function Max(params a: array of real): real;

View file

@ -84,7 +84,7 @@ function Digits(n: int64; base: integer := 10): List<integer>;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits,
function Refold(ext: List<integer>; base: integer := 10): int64;
function DigitsToInt64(ext: List<integer>; base: integer := 10): int64;
/// Возвращает список делителей натурального числа n
function Divisors(n: integer): List<integer>;
@ -703,7 +703,7 @@ function Digits(Self: int64; base: integer := 10): List<integer>;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits
function Refold(ext: List<integer>; base: integer): int64;
function DigitsToInt64(ext: List<integer>; base: integer): int64;
begin
Result := 0;
var p := int64(1);
@ -714,8 +714,8 @@ begin
end
end;
function ReFold(Self: List<integer>; base: integer := 10): int64;
extensionmethod := Refold(Self, base);
function DigitsToInt64(Self: List<integer>; base: integer := 10): int64;
extensionmethod := DigitsToInt64(Self, base);
{$endregion}

View file

@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@ -568,55 +569,73 @@ namespace PascalABCCompiler.TreeRealization
//implements = tnode.ImplementingInterfaces.Contains(base_class);
implements = false;
// Цикл по всем реализуемым интерфейсам. А если tnode сам является интерфейсом?
foreach (var interf in tnode.ImplementingInterfaces)
{
var ctn = interf as compiled_type_node;
var bcctn = base_class as compiled_type_node;
var cgitn = interf as compiled_generic_instance_type_node;
var bcgitn = base_class as compiled_generic_instance_type_node;
// interf - IEnumerable<Student>, base_class - IEnumerable<Person>
if (interf == base_class)
{
implements = true;
break;
}
// Справка:
// IEnumerable<object> - compiled_type_node
// IEnumerable<Student>, List<Student> - compiled_generic_instance_type_node
// MyIEnumerable<Student>, MyIEnumerable<object> - common_generic_instance_type_node
// Здесь common быть не может поскольку ковариантность у нас - только для откомпилированных NET-типов
// Тут можно проверить на ковариантность
// еще где то надо проверять, что IEnumerable<Derived> -> IEnumerable<Base>, но здесь base_class предполагает,
// что это - класс, и рассматривает все его интерфейсы, упуская ситуацию, когда base_class - это и есть интерфейс
else if (interf is compiled_generic_instance_type_node cgitn && base_class is compiled_generic_instance_type_node bcgitn)
else if (cgitn != null && bcgitn != null)
{
if (cgitn.original_generic != null && cgitn.original_generic == bcgitn.original_generic)
{
var ctcgi = cgitn.original_generic as compiled_type_node;
if (ctcgi != null)
{
// теперь надо проверить параметры на ковариантность - все
var n = bcgitn.instance_params.Count;
var n1 = cgitn.instance_params.Count;
compiled_type_node interf_original_generic = cgitn.original_generic as compiled_type_node;
compiled_type_node base_original_generic = bcgitn.original_generic as compiled_type_node;
List<type_node> interf_instance_params = cgitn.instance_params;
List<type_node> base_instance_params = bcgitn.instance_params;
var impl = true;
if (n != n1)
impl = false;
else
for (int i=0; i<n; i++)
if (interf_original_generic != null && interf_original_generic == base_original_generic)
{
// Нам нужно два original_generic as compiled_type_node и два instance_params
//if (ctcgi != null) // по идее это всегда так! потому что cgitn - compiled - поэтому закомментировал SSM 14/02/23
// теперь надо проверить параметры на ковариантность - все
var n = base_instance_params.Count;
var n1 = interf_instance_params.Count;
// перенес сюда. cgitn точно не null
var interf_compiled_type = interf_original_generic.compiled_type; // Пр: IEnumerable<T>
var impl = true;
if (n != n1)
impl = false;
else
for (int i=0; i<n; i++)
{
// ctcgi.compiled_type - это System.Type
if ((interf_compiled_type.GetGenericArguments()[i].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Covariant) != 0)
{
if ((ctcgi.compiled_type.GetGenericArguments()[i].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Covariant) != 0)
if (is_derived(base_instance_params[i], interf_instance_params[i], false))
{
if (is_derived(bcgitn.instance_params[i], cgitn.instance_params[i], false))
{
// OK
}
}
// Почему то когда это закомментировано, то работает. А так не вызывается ??!
/*else if (bcgitn.instance_params[i] == cgitn.instance_params[i])
{
n = n;
// Тоже OK
}*/
else
{
impl = false;
break;
// OK
}
}
// то есть если все контравариантные или неважно какие, но равные то implements = true иначе false
implements = impl;
}
// Почему то когда это закомментировано, то работает. А так не вызывается ??!
/*else if (base_instance_params[i] == interf_instance_params[i])
{
n = n;
// Тоже OK
}*/
else
{
impl = false;
break;
}
}
// то есть если все контравариантные или неважно какие, но равные то implements = true иначе false
implements = impl;
}
}
else if (interf is compiled_type_node ictn && base_class is compiled_type_node bctn)

View file

@ -1,4 +1,4 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
/// <summary>
@ -59,11 +59,11 @@ function ReadKey: char;
/// </summary>
function KeyPressed: boolean;
/// <summary>
/// Возвращает высоту экрана
/// Возвращает ширину экрана
/// </summary>
function WindowWidth: integer;
/// <summary>
/// Возвращает ширину экрана
/// Возвращает высоту экрана
/// </summary>
/// <returns></returns>
function WindowHeight: integer;

View file

@ -1804,7 +1804,7 @@ function Min(a, b, c: integer): integer;
function Min(a, b, c, d: integer): integer;
///-function Max(a,b,...: T): T;
/// Возвращает максиимальное из a,b,...
/// Возвращает максимальное из a,b,...
function Max<T>(params a: array of T): T;
///--
//function Max(params a: array of real): real;

View file

@ -84,7 +84,7 @@ function Digits(n: int64; base: integer := 10): List<integer>;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits,
function Refold(ext: List<integer>; base: integer := 10): int64;
function DigitsToInt64(ext: List<integer>; base: integer := 10): int64;
/// Возвращает список делителей натурального числа n
function Divisors(n: integer): List<integer>;
@ -703,7 +703,7 @@ function Digits(Self: int64; base: integer := 10): List<integer>;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits
function Refold(ext: List<integer>; base: integer): int64;
function DigitsToInt64(ext: List<integer>; base: integer): int64;
begin
Result := 0;
var p := int64(1);
@ -714,8 +714,8 @@ begin
end
end;
function ReFold(Self: List<integer>; base: integer := 10): int64;
extensionmethod := Refold(Self, base);
function DigitsToInt64(Self: List<integer>; base: integer := 10): int64;
extensionmethod := DigitsToInt64(Self, base);
{$endregion}