Изменение реализации range на InternalRange и IntRange CharRange

Правки в AutoInsertCode.cs

IntRange и CharRange в PABCSystem.pas - аналогично Котлину
This commit is contained in:
Mikhalkovich Stanislav 2020-02-14 19:47:41 +03:00
parent 750654fd9f
commit 228c9f9aac
12 changed files with 248 additions and 23 deletions

View file

@ -321,6 +321,35 @@ namespace PascalABCCompiler.PCU
return base_type.find_in_type(name, CurrentScope, null, no_search_in_extension_methods);
else if (name == compiler_string_consts.deconstruct_method_name)
return SystemLibrary.SystemLibrary.object_type.find_in_type(name, CurrentScope, null, no_search_in_extension_methods);
// SSM перенес из common_type_node (types.cs 2116) - без этого не работали методы расширения последовательностей для типов в pcu, реализующих IEnumerable<T>
if (ImplementingInterfaces != null)
{
Dictionary<definition_node, definition_node> cache = new Dictionary<definition_node, definition_node>();
List<SymbolInfo> props = new List<SymbolInfo>();
foreach (type_node ii_tn in ImplementingInterfaces)
{
List<SymbolInfo> isi = ii_tn.find_in_type(name, CurrentScope);
if (isi != null)
{
if (sil == null)
sil = new List<SymbolInfo>();
foreach (SymbolInfo si in isi)
{
if (!cache.ContainsKey(si.sym_info))
{
if (si.sym_info is function_node && (si.sym_info as function_node).is_extension_method
&& sil.FindIndex(ssi => ssi.sym_info == si.sym_info) == -1) // SSM 12.12.18 - за счёт методов интерфейсов тоже могут добавляться одинаковые - исключаем их
sil.Add(si);
cache.Add(si.sym_info, si.sym_info);
}
}
}
}
if (sil != null && sil.Count == 0)
sil = null;
}
return sil;
}

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "6";
public const string Build = "0";
public const string Revision = "2345";
public const string Revision = "2352";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=6
%REVISION%=2345
%COREVERSION%=0
%REVISION%=2352
%MINOR%=6
%MAJOR%=3

View file

@ -1 +1 @@
3.6.0.2345
3.6.0.2352

View file

@ -1 +1 @@
!define VERSION '3.6.0.2345'
!define VERSION '3.6.0.2352'

View file

@ -33,7 +33,7 @@ namespace SyntaxVisitors.SugarVisitors
el.Add(diap.right, diap.right.source_context);
// Проблема в том, что тут тоже надо перепрошивать Parent!
var mc = method_call.NewP(dot_node.NewP(new ident("PABCSystem", diap.source_context), new ident("Range", diap.source_context), diap.source_context), el, diap.source_context);
var mc = method_call.NewP(dot_node.NewP(new ident("PABCSystem", diap.source_context), new ident("InternalRange", diap.source_context), diap.source_context), el, diap.source_context);
var sug = sugared_addressed_value.NewP(diap, mc, diap.source_context);

View file

@ -2423,6 +2423,73 @@ type
end;
type
/// Тип диапазона целых
IntRange = class(IEnumerable<integer>)
private
l,h: integer;
public
constructor(l,h: integer);
begin
Self.l := l;
Self.h := h;
end;
property Low: integer read l;
property High: integer read h;
static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: IntRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := IntRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
/// Тип диапазона символов
CharRange = class(IEnumerable<char>)
private
l,h: char;
public
constructor(l,h: char);
begin
Self.l := l;
Self.h := h;
end;
property Low: char read l;
property High: char read h;
static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<char> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := CharRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
///--
function InternalRange(l,r: integer): IntRange;
///--
function InternalRange(l,r: char): CharRange;
// -----------------------------------------------------
// Internal procedures for PABCRTL.dll
// -----------------------------------------------------
@ -4884,8 +4951,18 @@ begin
else
begin
_IsPipedRedirectedQuery := True;
_IsPipedRedirected := Console.IsInputRedirected and (CurrentIOSystem.GetType = typeof(IOStandardSystem));
Result := _IsPipedRedirected;
var pi := typeof(Console).GetProperty('IsInputRedirected');
if pi = nil then
begin
_IsPipedRedirected := False; // просто работаем без буфера на старых системах
Result := _IsPipedRedirected;
end
else
begin
var IsInputRedirected := boolean(pi?.GetValue(nil,nil));
_IsPipedRedirected := IsInputRedirected {Console.IsInputRedirected} and (CurrentIOSystem.GetType = typeof(IOStandardSystem));
Result := _IsPipedRedirected;
end;
end;
end;
@ -12404,6 +12481,11 @@ begin
Result := '';
end;
function InternalRange(l,r: integer): IntRange := new IntRange(l,r);
function InternalRange(l,r: char): CharRange := new CharRange(l,r);
//------------------------------------------------------------------------------
//OMP

View file

@ -0,0 +1,5 @@
begin
var ir := InternalRange(2,5);
Assert(ir.Take(1).First = 2);
end.

View file

@ -0,0 +1,12 @@
function f1: byte;
begin
var p: ()->() := ()->
begin
Result := 0;
end;
end;
begin
end.

View file

@ -19545,6 +19545,7 @@ namespace PascalABCCompiler.TreeConverter
{
_function_lambda_definition.return_type = null;
}
else _function_lambda_definition.usedkeyword = 1; // значит, это наверняка функция
}
}

View file

@ -17,7 +17,7 @@ namespace VisualPascalABC
var ta = CurrentCodeFileDocument.TextEditor.ActiveTextAreaControl.TextArea;
var doc = ta.Document;
if (lineNum < doc.TotalNumberOfLines)
return TextUtilities.GetLineAsString(doc, lineNum);
return TextUtilities.GetLineAsString(doc, lineNum);
else return null;
}
@ -99,9 +99,10 @@ namespace VisualPascalABC
int start = TextUtilities.FindPrevWordStart(editor.Document, caret.Offset);
// Нужно, чтобы в Text было последнее слово в строке !!! Исключение - когда в следующей надо сделать просто сдвиг
var Text = editor.Document.GetText(start, caret.Offset - start).TrimEnd();
var TextToLower = Text.ToLower();
//var curStrEnd = TextUtilities.GetLineAsString(editor.Document, caret.Line).Substring(caret.Column);
if (Text.ToLower() == "begin")
if (TextToLower == "begin")
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
@ -116,7 +117,8 @@ namespace VisualPascalABC
// Проанализируем предыдущий оператор по первому слову
var pst = prev?.TrimStart().ToLower();
if (pst != null)
if (pst.StartsWith("if") || pst.StartsWith("for") || pst.StartsWith("loop") || pst.StartsWith("with") || pst.StartsWith("on") || pst.StartsWith("while") || pst.StartsWith("else") || pst.StartsWith("foreach")) // потом улучшу - для нескольких выборов
//if (pst.StartsWith("if") || pst.StartsWith("for") || pst.StartsWith("loop") || pst.StartsWith("with") || pst.StartsWith("on") || pst.StartsWith("while") || pst.StartsWith("else") || pst.StartsWith("foreach")) // потом улучшу - для нескольких выборов
if (Regex.IsMatch(pst, "^(if|else|for|loop|while|foreach|with|on)"))
{
// Надо удалить в текущей строке пробелы чтобы выровнять begin по if
var iprev = Indent(prev);
@ -146,7 +148,7 @@ namespace VisualPascalABC
return true;
}
else if (Text.ToLower() == "repeat") // repeat .. until
else if (TextToLower == "repeat") // repeat .. until
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
@ -164,7 +166,7 @@ namespace VisualPascalABC
return true;
}
else if (Text.ToLower() == "class" || Text.ToLower() == "record") // class .. end, record .. end
else if (Regex.IsMatch(TextToLower,"class|record")) // class .. end, record .. end
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
@ -182,7 +184,7 @@ namespace VisualPascalABC
return true;
}
else if (Text.ToLower() == "of")
else if (TextToLower == "of")
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
@ -200,25 +202,37 @@ namespace VisualPascalABC
return true;
}
else if (Text.ToLower() == "then" || Text.ToLower() == "else" || Text.ToLower() == "do"
|| Text.ToLower() == "try" || Text.ToLower() == "except" || Text.ToLower() == "finally"
|| Text.ToLower() == "var")
else if (Regex.IsMatch(TextToLower, "then|else|do|try|except|finally|var"))
{
if (ta.Caret.Line > 0 && TextToLower == "else")
{
var prevSeg = doc.GetLineSegment(ta.Caret.Line - 1);
var prev = GetLine(ta.Caret.Line - 1).TrimEnd();
if (prev[prev.Length-1] == ';')
{
doc.Replace(prevSeg.Offset + prevSeg.Length - 1, 1, "");
}
}
var cur = GetLine(ta.Caret.Line);
var icur = Indent(cur);
ta.InsertString("\n" + Spaces(icur + 2));
return true;
}
else
else
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
if (ta.Caret.Column >= cur.Length)
{
var prevTrimEnd = prev.TrimEnd();
// если prev заканчивается на then, а cur не начинается с begin, то отступ назад
if ((prev.TrimEnd().EndsWith("then",StringComparison.InvariantCultureIgnoreCase) ||
prev.TrimEnd().EndsWith("else", StringComparison.InvariantCultureIgnoreCase) ||
prev.TrimEnd().EndsWith("do", StringComparison.InvariantCultureIgnoreCase))
if ((prevTrimEnd.EndsWith("then",StringComparison.InvariantCultureIgnoreCase) ||
prevTrimEnd.EndsWith("else", StringComparison.InvariantCultureIgnoreCase) ||
prevTrimEnd.EndsWith("do", StringComparison.InvariantCultureIgnoreCase))
&&
!(cur.TrimStart().StartsWith("begin", StringComparison.InvariantCultureIgnoreCase)))
{

View file

@ -2423,6 +2423,73 @@ type
end;
type
/// Тип диапазона целых
IntRange = class(IEnumerable<integer>)
private
l,h: integer;
public
constructor(l,h: integer);
begin
Self.l := l;
Self.h := h;
end;
property Low: integer read l;
property High: integer read h;
static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: IntRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := IntRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
/// Тип диапазона символов
CharRange = class(IEnumerable<char>)
private
l,h: char;
public
constructor(l,h: char);
begin
Self.l := l;
Self.h := h;
end;
property Low: char read l;
property High: char read h;
static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<char> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := CharRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
///--
function InternalRange(l,r: integer): IntRange;
///--
function InternalRange(l,r: char): CharRange;
// -----------------------------------------------------
// Internal procedures for PABCRTL.dll
// -----------------------------------------------------
@ -4884,8 +4951,18 @@ begin
else
begin
_IsPipedRedirectedQuery := True;
_IsPipedRedirected := Console.IsInputRedirected and (CurrentIOSystem.GetType = typeof(IOStandardSystem));
Result := _IsPipedRedirected;
var pi := typeof(Console).GetProperty('IsInputRedirected');
if pi = nil then
begin
_IsPipedRedirected := False; // просто работаем без буфера на старых системах
Result := _IsPipedRedirected;
end
else
begin
var IsInputRedirected := boolean(pi?.GetValue(nil,nil));
_IsPipedRedirected := IsInputRedirected {Console.IsInputRedirected} and (CurrentIOSystem.GetType = typeof(IOStandardSystem));
Result := _IsPipedRedirected;
end;
end;
end;
@ -12404,6 +12481,11 @@ begin
Result := '';
end;
function InternalRange(l,r: integer): IntRange := new IntRange(l,r);
function InternalRange(l,r: char): CharRange := new CharRange(l,r);
//------------------------------------------------------------------------------
//OMP