Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Рефлектор возвращает приватные поля и методы #1242

Merged
merged 8 commits into from
Jan 12, 2023
80 changes: 50 additions & 30 deletions src/NUnitTests/CompilerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void TestNoSemicolonBeforeEndProcedure()
Возврат
КонецПроцедуры");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -46,7 +46,7 @@ public void TestNoSemicolonBeforeEndFunction()
Возврат 4
КонецФункции");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -57,7 +57,7 @@ public void TestNoSemicolonBeforeEndDo()
Прервать
КонецЦикла");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -72,7 +72,7 @@ ИначеЕсли Истина Тогда
Ф = 3
КонецЕсли");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -85,7 +85,7 @@ public void TestNoSemicolonBeforeExceptionOrEndTry()
ВызватьИсключение
КонецПопытки");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}


Expand All @@ -98,7 +98,7 @@ public void TestNoSemicolonBeforeEndOfText()
КонецПроцедуры
Ф = 0");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
#endregion

Expand All @@ -112,7 +112,7 @@ public void TestSemicolonBeforeEndProcedure()
Возврат;
КонецПроцедуры");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -123,7 +123,7 @@ public void TestSemicolonBeforeEndFunction()
Возврат 4;
КонецФункции");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -134,7 +134,7 @@ public void TestSemicolonBeforeEndDo()
Прервать;
КонецЦикла");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -149,7 +149,7 @@ ИначеЕсли Истина Тогда
Ф = 3;
КонецЕсли");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test]
Expand All @@ -162,7 +162,7 @@ public void TestSemicolonBeforeExceptionOrEndTry()
ВызватьИсключение;
КонецПопытки");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}


Expand All @@ -175,7 +175,7 @@ public void TestSemicolonBeforeEndOfText()
КонецПроцедуры
Ф = 0;");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
#endregion

Expand All @@ -192,7 +192,7 @@ public void TestEndFunctionDoesNotEndIf()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -212,7 +212,7 @@ public void TestEndDoDoesNotEndIf()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -232,7 +232,7 @@ public void TestEndIfDoesNotEndDo()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -251,7 +251,7 @@ public void TestEndFunctionDoesNotEndProcedure()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -271,7 +271,7 @@ Возврат 0
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -291,7 +291,7 @@ public void TestElseifDoesNotEndProcedure()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -311,7 +311,7 @@ public void TestEndTryDoesNotEndProcedure()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand Down Expand Up @@ -339,7 +339,7 @@ Функция Ф1(П1, П2 = Неопределено, П3 = Неопредел
Р = Ф1(,,) + Ф1(,);
");

_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}

[Test(Description = "Не компилируется вызов метода вообще без параметров")]
Expand All @@ -355,7 +355,7 @@ public void TestCantCompileCallWithoutParams()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -374,7 +374,7 @@ public void TestReturnBeforeException()
Исключение
КонецПопытки
КонецПроцедуры");
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}


Expand All @@ -389,7 +389,7 @@ ДобавитьОбработчик ЭтотОбъект.Событие Ина
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -411,7 +411,7 @@ Процедура Проц1()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -434,7 +434,7 @@ Если Истина Тогда
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -457,7 +457,7 @@ Процедура Проц2()
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -479,7 +479,7 @@ Если Ложь Тогда
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -501,7 +501,7 @@ Если Ложь Тогда
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
Expand All @@ -524,13 +524,33 @@ Если Ложь Тогда
bool exceptionThrown = false;
try
{
_ = host.Engine.GetCompilerService().Compile(moduleSource);
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
exceptionThrown = true;
}
Assert.IsTrue(exceptionThrown, "Отсутствует точка с запятой между операторами!");
}
}

[Test]
public void TestLocalExportVar()
{
var moduleSource = host.Engine.Loader.FromString(
@"Процедура Проц1()
Перем Переменная Экспорт;
КонецПроцедуры");

bool exceptionThrown = false;
try
{
host.Engine.GetCompilerService().Compile(moduleSource);
}
catch (CompilerException)
{
exceptionThrown = true;
}
Assert.IsTrue(exceptionThrown, "В теле процедуры или функции не может быть объявлена экспортная переменная!");
}
}
}
20 changes: 14 additions & 6 deletions src/ScriptEngine.HostedScript/Library/Reflector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ private static AnnotationDefinition[] GetAnnotations(IEnumerable<UserAnnotationA
return attributes.Select(x => x.Annotation).ToArray();
}

private static void FillPropertiesTableForType(TypeTypeValue type, ValueTable.ValueTable result)
private static void FillPropertiesTableForType(TypeTypeValue type, ValueTable.ValueTable result, bool withPrivate = false)
{
var clrType = GetReflectableClrType(type);
var nativeProps = clrType.GetProperties()
Expand All @@ -299,14 +299,19 @@ private static void FillPropertiesTableForType(TypeTypeValue type, ValueTable.Va

if (clrType.BaseType == typeof(ScriptDrivenObject))
{
var nativeFields = clrType.GetFields();
foreach(var field in nativeFields)
var flags = BindingFlags.Public;
if (withPrivate)
flags |= BindingFlags.NonPublic;

var nativeFields = clrType.GetFields(flags);
foreach (var field in nativeFields)
{
var info = new VariableInfo();
info.Type = SymbolType.ContextProperty;
info.Index = indices++;
info.Identifier = field.Name;
info.Annotations = GetAnnotations(field.GetCustomAttributes<UserAnnotationAttribute>());
info.IsExport = field.IsPublic;
infos.Add(info);
}
}
Expand Down Expand Up @@ -365,18 +370,19 @@ private static void FillMethodsTable(ValueTable.ValueTable result, IEnumerable<M
/// Получает таблицу свойств для переданного объекта..
/// </summary>
/// <param name="target">Объект, из которого получаем таблицу свойств.</param>
/// <param name="withPrivate">Включая приватные</param>
/// <returns>Таблица значений с колонками - Имя, Аннотации</returns>
[ContextMethod("ПолучитьТаблицуСвойств", "GetPropertiesTable")]
public ValueTable.ValueTable GetPropertiesTable(IValue target)
public ValueTable.ValueTable GetPropertiesTable(IValue target, bool withPrivate = false)
{
ValueTable.ValueTable result = new ValueTable.ValueTable();

if(target.DataType == DataType.Object)
FillPropertiesTable(result, target.AsObject().GetProperties());
FillPropertiesTable(result, target.AsObject().GetProperties(withPrivate));
else if (target.DataType == DataType.Type)
{
var type = target.GetRawValue() as TypeTypeValue;
FillPropertiesTableForType(type, result);
FillPropertiesTableForType(type, result, withPrivate);
}
else
throw RuntimeException.InvalidArgumentType();
Expand Down Expand Up @@ -422,6 +428,7 @@ private static void FillPropertiesTable(ValueTable.ValueTable result, IEnumerabl
{
var nameColumn = result.Columns.Add("Имя", TypeDescription.StringType(), "Имя");
var annotationsColumn = result.Columns.Add("Аннотации", new TypeDescription(), "Аннотации");
var exportColumn = result.Columns.Add("Экспорт", TypeDescription.BooleanType(), "Экспорт");
var systemVarNames = new string[] { "этотобъект", "thisobject" };

foreach (var propInfo in properties)
Expand All @@ -432,6 +439,7 @@ private static void FillPropertiesTable(ValueTable.ValueTable result, IEnumerabl
new_row.Set(nameColumn, ValueFactory.Create(propInfo.Identifier));

new_row.Set(annotationsColumn, propInfo.AnnotationsCount != 0 ? CreateAnnotationTable(propInfo.Annotations) : EmptyAnnotationsTable());
new_row.Set(exportColumn, ValueFactory.Create(propInfo.IsExport));
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/ScriptEngine/Compiler/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,18 @@ private void BuildVariableDefinitions()
var symbolicName = _lastExtractedLexem.Content;
var annotations = ExtractAnnotations();
var definition = _ctx.DefineVariable(symbolicName);
NextToken();
if (_inMethodScope)
{
if (_isStatementsDefined)
{
throw CompilerException.LateVarDefinition();
}

if(_lastExtractedLexem.Token == Token.Export)
{
throw CompilerException.LocalExportVar();
}
}
else
{
Expand All @@ -346,10 +352,10 @@ private void BuildVariableDefinitions()
Annotations = annotations,
CanGet = true,
CanSet = true,
Index = definition.CodeIndex
Index = definition.CodeIndex,
IsExport = _lastExtractedLexem.Token == Token.Export
});
}
NextToken();
if (_lastExtractedLexem.Token == Token.Export)
{
_module.ExportedProperties.Add(new ExportedSymbol()
Expand Down
Loading