TipPainterTools - исправил возможное падение

operator* в Matrix сделал extension
This commit is contained in:
Mikhalkovich Stanislav 2026-02-16 15:46:15 +03:00
parent 95a1e58952
commit 98fe38141b
8 changed files with 408 additions and 70 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "11";
public const string Build = "1";
public const string Revision = "3751";
public const string Revision = "3753";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=11
%REVISION%=3751
%REVISION%=3753
%COREVERSION%=1
%MAJOR%=3

View file

@ -1 +1 @@
3.11.1.3751
3.11.1.3753

View file

@ -1 +1 @@
!define VERSION '3.11.1.3751'
!define VERSION '3.11.1.3753'

View file

@ -69,22 +69,41 @@ namespace ICSharpCode.TextEditor.Util
var languageIntellisenseSupport = CodeCompletion.CodeCompletionController.CurrentLanguage.LanguageIntellisenseSupport;
int startIndex = basicDescription.IndexOf("(", basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION")) + 1) + 1;
// ИЗМЕНЕНО НАЧАЛО
int extensionIndex = basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION"));
if (extensionIndex == -1)
return;
int paranthesisIndex = languageIntellisenseSupport.FindClosingParenthesis(basicDescription.Substring(startIndex), ')');
int startIndex = basicDescription.IndexOf("(", extensionIndex + 1);
if (startIndex == -1)
return;
startIndex++;
if (startIndex >= basicDescription.Length)
return;
string substringFromStart = basicDescription.Substring(startIndex);
int paranthesisIndex = languageIntellisenseSupport.FindClosingParenthesis(substringFromStart, ')');
if (paranthesisIndex == -1)
return;
int end_sk = paranthesisIndex + startIndex;
if (end_sk > basicDescription.Length)
return;
// ИЗМЕНЕНО КОНЕЦ
if (param_num == 1)
{
// ИЗМЕНЕНО НАЧАЛО
bold_beg = startIndex;
if (bold_beg != 0)
if (bold_beg != 0 && bold_beg < basicDescription.Length)
{
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(bold_beg), 1);
string remainingText = basicDescription.Substring(bold_beg);
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(remainingText, 1);
if (paramDelimIndex == -1)
{
@ -94,25 +113,34 @@ namespace ICSharpCode.TextEditor.Util
{
bold_len = paramDelimIndex;
}
if (bold_len < 0)
bold_len = 0;
}
// ИЗМЕНЕНО КОНЕЦ
}
else
{
// Здесь учтется случай последнего параметра типа params EVA
if (param_num > paramsCount)
{
if (paramsCount == 1)
{
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageIntellisenseSupport.IsParams(paramDescription))
// ИЗМЕНЕНО НАЧАЛО
if (startIndex < basicDescription.Length && paranthesisIndex > 0)
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
}
}
// ИЗМЕНЕНО КОНЕЦ
}
else
{
// ИЗМЕНЕНО НАЧАЛО
string descriptionAfterBracket = basicDescription.Substring(startIndex);
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(descriptionAfterBracket, paramsCount - 1);
@ -121,46 +149,181 @@ namespace ICSharpCode.TextEditor.Util
{
int paramDelimLength = languageIntellisenseSupport.ParameterDelimiter.Length;
// Проверка на всякий случай, чтобы не возникало ошибки с отрицательным length в Substring EVA
if (paranthesisIndex - paramDelimLength < paramDelimLength)
return;
int length = paranthesisIndex - paramDelimIndex - paramDelimLength;
string paramDescription = descriptionAfterBracket.Substring(paramDelimIndex + paramDelimLength, paranthesisIndex - paramDelimIndex - paramDelimLength);
if (languageIntellisenseSupport.IsParams(paramDescription))
if (paramDelimIndex + paramDelimLength <= descriptionAfterBracket.Length &&
length >= 0 &&
paramDelimIndex + paramDelimLength + length <= descriptionAfterBracket.Length)
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
string paramDescription = descriptionAfterBracket.Substring(
paramDelimIndex + paramDelimLength,
length);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
if (bold_len < 0)
bold_len = 0;
}
}
}
// ИЗМЕНЕНО КОНЕЦ
}
}
else
{
// ИЗМЕНЕНО НАЧАЛО
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
{
bold_beg = paramDelimIndex + startIndex + languageIntellisenseSupport.ParameterDelimiter.Length;
int secondParamDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num);
int paramDelimLength = languageIntellisenseSupport.ParameterDelimiter.Length;
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
if (secondParamDelimIndex == -1)
if (bold_beg < basicDescription.Length)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
int secondParamDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
}
if (bold_len < 0)
bold_len = 0;
}
}
// ИЗМЕНЕНО КОНЕЦ
}
}
}
}
}
// btw. I know it's ugly.
public static Rectangle DrawingRectangle1;
/* private static void GetToolipParts(string description, int param_num, int paramsCount, out string basicDescription, out string documentation, out int bold_beg, out int bold_len)
{
basicDescription = null;
documentation = null;
bold_beg = 0;
bold_len = 0;
if (IsVisibleText(description))
{
string[] splitDescription = description.Split(new char[] { '\n' }, 2);
if (splitDescription.Length > 0)
{
if (splitDescription.Length > 1)
{
documentation = splitDescription[1].Trim();
}
basicDescription = splitDescription[0];
if (param_num == -1)
return;
var languageIntellisenseSupport = CodeCompletion.CodeCompletionController.CurrentLanguage.LanguageIntellisenseSupport;
int startIndex = basicDescription.IndexOf("(", basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION")) + 1) + 1;
int paranthesisIndex = languageIntellisenseSupport.FindClosingParenthesis(basicDescription.Substring(startIndex), ')');
if (paranthesisIndex == -1)
return;
int end_sk = paranthesisIndex + startIndex;
if (param_num == 1)
{
bold_beg = startIndex;
if (bold_beg != 0)
{
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(bold_beg), 1);
if (paramDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = paramDelimIndex;
}
}
}
else
{
// Здесь учтется случай последнего параметра типа params EVA
if (param_num > paramsCount)
{
if (paramsCount == 1)
{
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
}
}
else
{
string descriptionAfterBracket = basicDescription.Substring(startIndex);
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(descriptionAfterBracket, paramsCount - 1);
if (paramDelimIndex != -1)
{
int paramDelimLength = languageIntellisenseSupport.ParameterDelimiter.Length;
// Проверка на всякий случай, чтобы не возникало ошибки с отрицательным length в Substring EVA
if (paranthesisIndex - paramDelimLength < paramDelimLength)
return;
string paramDescription = descriptionAfterBracket.Substring(paramDelimIndex + paramDelimLength, paranthesisIndex - paramDelimIndex - paramDelimLength);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
}
}
}
}
else
{
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
{
bold_beg = paramDelimIndex + startIndex + languageIntellisenseSupport.ParameterDelimiter.Length;
int secondParamDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
}
}
}
}
}
}
}*/
// btw. I know it's ugly.
public static Rectangle DrawingRectangle1;
public static Rectangle DrawingRectangle2;
public static Size GetDrawingSizeDrawHelpTip(Control control,

View file

@ -68,22 +68,41 @@ namespace ICSharpCode.TextEditor.Util
var languageIntellisenseSupport = CodeCompletion.CodeCompletionController.CurrentLanguage.LanguageIntellisenseSupport;
int startIndex = basicDescription.IndexOf("(", basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION")) + 1) + 1;
// ИЗМЕНЕНО НАЧАЛО
int extensionIndex = basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION"));
if (extensionIndex == -1)
return;
int paranthesisIndex = languageIntellisenseSupport.FindClosingParenthesis(basicDescription.Substring(startIndex), ')');
int startIndex = basicDescription.IndexOf("(", extensionIndex + 1);
if (startIndex == -1)
return;
startIndex++;
if (startIndex >= basicDescription.Length)
return;
string substringFromStart = basicDescription.Substring(startIndex);
int paranthesisIndex = languageIntellisenseSupport.FindClosingParenthesis(substringFromStart, ')');
if (paranthesisIndex == -1)
return;
int end_sk = paranthesisIndex + startIndex;
if (end_sk > basicDescription.Length)
return;
// ИЗМЕНЕНО КОНЕЦ
if (param_num == 1)
{
// ИЗМЕНЕНО НАЧАЛО
bold_beg = startIndex;
if (bold_beg != 0)
if (bold_beg != 0 && bold_beg < basicDescription.Length)
{
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(bold_beg), 1);
string remainingText = basicDescription.Substring(bold_beg);
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(remainingText, 1);
if (paramDelimIndex == -1)
{
@ -93,25 +112,34 @@ namespace ICSharpCode.TextEditor.Util
{
bold_len = paramDelimIndex;
}
if (bold_len < 0)
bold_len = 0;
}
// ИЗМЕНЕНО КОНЕЦ
}
else
{
// Здесь учтется случай последнего параметра типа params EVA
if (param_num > paramsCount)
{
if (paramsCount == 1)
{
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageIntellisenseSupport.IsParams(paramDescription))
// ИЗМЕНЕНО НАЧАЛО
if (startIndex < basicDescription.Length && paranthesisIndex > 0)
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
}
}
// ИЗМЕНЕНО КОНЕЦ
}
else
{
// ИЗМЕНЕНО НАЧАЛО
string descriptionAfterBracket = basicDescription.Substring(startIndex);
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(descriptionAfterBracket, paramsCount - 1);
@ -120,44 +148,179 @@ namespace ICSharpCode.TextEditor.Util
{
int paramDelimLength = languageIntellisenseSupport.ParameterDelimiter.Length;
// Проверка на всякий случай, чтобы не возникало ошибки с отрицательным length в Substring EVA
if (paranthesisIndex - paramDelimLength < paramDelimLength)
return;
int length = paranthesisIndex - paramDelimIndex - paramDelimLength;
string paramDescription = descriptionAfterBracket.Substring(paramDelimIndex + paramDelimLength, paranthesisIndex - paramDelimIndex - paramDelimLength);
if (languageIntellisenseSupport.IsParams(paramDescription))
if (paramDelimIndex + paramDelimLength <= descriptionAfterBracket.Length &&
length >= 0 &&
paramDelimIndex + paramDelimLength + length <= descriptionAfterBracket.Length)
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
string paramDescription = descriptionAfterBracket.Substring(
paramDelimIndex + paramDelimLength,
length);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
if (bold_len < 0)
bold_len = 0;
}
}
}
// ИЗМЕНЕНО КОНЕЦ
}
}
else
{
// ИЗМЕНЕНО НАЧАЛО
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
{
bold_beg = paramDelimIndex + startIndex + languageIntellisenseSupport.ParameterDelimiter.Length;
int secondParamDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num);
int paramDelimLength = languageIntellisenseSupport.ParameterDelimiter.Length;
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
if (secondParamDelimIndex == -1)
if (bold_beg < basicDescription.Length)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
int secondParamDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
}
if (bold_len < 0)
bold_len = 0;
}
}
// ИЗМЕНЕНО КОНЕЦ
}
}
}
}
}
/* private static void GetToolipParts(string description, int param_num, int paramsCount, out string basicDescription, out string documentation, out int bold_beg, out int bold_len)
{
basicDescription = null;
documentation = null;
bold_beg = 0;
bold_len = 0;
if (IsVisibleText(description))
{
string[] splitDescription = description.Split(new char[] { '\n' }, 2);
if (splitDescription.Length > 0)
{
if (splitDescription.Length > 1)
{
documentation = splitDescription[1].Trim();
}
basicDescription = splitDescription[0];
if (param_num == -1)
return;
var languageIntellisenseSupport = CodeCompletion.CodeCompletionController.CurrentLanguage.LanguageIntellisenseSupport;
int startIndex = basicDescription.IndexOf("(", basicDescription.IndexOf("(" + PascalABCCompiler.StringResources.Get("CODE_COMPLETION_EXTENSION")) + 1) + 1;
int paranthesisIndex = languageIntellisenseSupport.FindClosingParenthesis(basicDescription.Substring(startIndex), ')');
if (paranthesisIndex == -1)
return;
int end_sk = paranthesisIndex + startIndex;
if (param_num == 1)
{
bold_beg = startIndex;
if (bold_beg != 0)
{
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(bold_beg), 1);
if (paramDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = paramDelimIndex;
}
}
}
else
{
// Здесь учтется случай последнего параметра типа params EVA
if (param_num > paramsCount)
{
if (paramsCount == 1)
{
string paramDescription = basicDescription.Substring(startIndex, paranthesisIndex);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = startIndex;
bold_len = paranthesisIndex;
}
}
else
{
string descriptionAfterBracket = basicDescription.Substring(startIndex);
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(descriptionAfterBracket, paramsCount - 1);
if (paramDelimIndex != -1)
{
int paramDelimLength = languageIntellisenseSupport.ParameterDelimiter.Length;
// Проверка на всякий случай, чтобы не возникало ошибки с отрицательным length в Substring EVA
if (paranthesisIndex - paramDelimLength < paramDelimLength)
return;
string paramDescription = descriptionAfterBracket.Substring(paramDelimIndex + paramDelimLength, paranthesisIndex - paramDelimIndex - paramDelimLength);
if (languageIntellisenseSupport.IsParams(paramDescription))
{
bold_beg = paramDelimIndex + startIndex + paramDelimLength;
bold_len = end_sk - bold_beg;
}
}
}
}
else
{
int paramDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num - 1);
if (paramDelimIndex != -1)
{
bold_beg = paramDelimIndex + startIndex + languageIntellisenseSupport.ParameterDelimiter.Length;
int secondParamDelimIndex = languageIntellisenseSupport.FindParamDelim(basicDescription.Substring(startIndex), param_num);
if (secondParamDelimIndex == -1)
{
bold_len = end_sk - bold_beg;
}
else
{
bold_len = secondParamDelimIndex + startIndex - bold_beg;
}
}
}
}
}
}
}*/
// btw. I know it's ugly.
public static Rectangle DrawingRectangle1;
public static Rectangle DrawingRectangle2;

View file

@ -127,8 +127,8 @@ type
static function operator *(A: Matrix; x: Vector): Vector;
static function operator *(A, B: Matrix): Matrix;
static function operator *(alpha: real; A: Matrix): Matrix;
static function operator *(A: Matrix; alpha: real): Matrix;
//static function operator *(alpha: real; A: Matrix): Matrix;
//static function operator *(A: Matrix; alpha: real): Matrix;
// ---------- in-place operators ----------
static function operator +=(A, B: Matrix): Matrix;
@ -784,12 +784,7 @@ begin
Result.data[i, j] := A.data[i, j] - B.data[i, j];
end;
static function Matrix.operator *(alpha: real; A: Matrix): Matrix;
begin
Result := A * alpha;
end;
static function Matrix.operator *(A: Matrix; alpha: real): Matrix;
function operator *(A: Matrix; alpha: real): Matrix; extensionmethod;
begin
Result := new Matrix(A.Rows, A.Cols);
for var i := 0 to A.Rows - 1 do
@ -797,6 +792,23 @@ begin
Result.data[i, j] := alpha * A.data[i, j];
end;
function operator *(alpha: real; A: Matrix): Matrix; extensionmethod;
begin
Result := A * alpha;
end;
function operator *(A: Matrix; alpha: integer): Matrix; extensionmethod;
begin
Result := A * real(alpha);
end;
function operator *(alpha: integer; A: Matrix): Matrix; extensionmethod;
begin
Result := real(alpha) * A;
end;
static function Matrix.operator *(A: Matrix; x: Vector): Vector;
begin
CheckVecSize(A, x);

View file

@ -330,9 +330,9 @@ type
{$endregion Pipeline}
{$region Transformers}
/// Стандартизирует признаки: вычитает среднее
/// и делит на стандартное отклонение по каждому столбцу.
/// Используется для приведения признаков к сопоставимому масштабу.
/// Стандартизирует признаки: вычитает среднее
/// и делит на стандартное отклонение по каждому столбцу.
/// Используется для приведения признаков к сопоставимому масштабу.
StandardScaler = class(ITransformer)
private
fMean: Vector;