Skip to content

Commit bb3bcb1

Browse files
committed
проверка обращений к свойствам и индексам
1 parent 6f12dbd commit bb3bcb1

3 files changed

Lines changed: 74 additions & 46 deletions

File tree

‎src/OneScript.Language/ScriptException.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ public override string Message
104104
ColumnNumber = codeLine.Length;
105105
}
106106

107-
if (ColumnNumber != ErrorPositionInfo.OUT_OF_TEXT)
107+
if (ColumnNumber > 0)
108108
{
109-
sb.Append(codeLine[..ColumnNumber]);
109+
sb.Append(codeLine[..(ColumnNumber - 1)]);
110110
sb.Append("<<?>>");
111-
sb.AppendLine(codeLine[ColumnNumber..]);
111+
sb.AppendLine(codeLine[(ColumnNumber - 1)..]);
112112
}
113113
else
114114
{

‎src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs‎

Lines changed: 64 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,59 +1410,82 @@ private BslSyntaxNode BuildQuestionOperator()
14101410
}
14111411

14121412
return BuildDereference(node);
1413-
}
1413+
}
1414+
1415+
private bool IsDereferenceable(BslSyntaxNode node)
1416+
=> node.Kind switch
1417+
{
1418+
NodeKind.Identifier
1419+
or NodeKind.GlobalCall or NodeKind.MethodCall
1420+
or NodeKind.DereferenceOperation or NodeKind.IndexAccess
1421+
or NodeKind.TernaryOperator
1422+
or NodeKind.NewObject // несовместимо с 1С
1423+
=> true,
1424+
1425+
_ => false
1426+
};
14141427

14151428
private BslSyntaxNode BuildDereference(BslSyntaxNode target)
14161429
{
14171430
var activeTarget = BuildIndexerAccess(target);
1418-
if (_lastExtractedLexem.Token == Token.Dot)
1431+
if (_lastExtractedLexem.Token != Token.Dot)
1432+
{
1433+
return activeTarget;
1434+
}
1435+
1436+
if (!IsDereferenceable(target))
14191437
{
1420-
var dotNode = new NonTerminalNode(NodeKind.DereferenceOperation, _lastExtractedLexem);
1421-
dotNode.AddChild(activeTarget);
1422-
NextLexem();
1423-
if (!LanguageDef.IsValidPropertyName(_lastExtractedLexem))
1424-
{
1425-
return CreateError(LocalizedErrors.IdentifierExpected());
1426-
}
1427-
1428-
var identifier = _lastExtractedLexem;
1429-
NextLexem();
1430-
if (_lastExtractedLexem.Token == Token.OpenPar)
1431-
{
1432-
var ident = new TerminalNode(NodeKind.Identifier, identifier);
1433-
var call = BuildCall(ident, NodeKind.MethodCall);
1434-
dotNode.AddChild(call);
1435-
}
1436-
else
1437-
{
1438-
_lastDereferenceIsWritable = true;
1439-
CreateChild(dotNode, NodeKind.Identifier, identifier);
1440-
}
1441-
1442-
return BuildDereference(dotNode);
1443-
}
1444-
1445-
return activeTarget;
1438+
AddError(LocalizedErrors.ValueIsNotObjectException());
1439+
}
1440+
1441+
var dotNode = new NonTerminalNode(NodeKind.DereferenceOperation, _lastExtractedLexem);
1442+
dotNode.AddChild(activeTarget);
1443+
NextLexem();
1444+
if (!LanguageDef.IsValidPropertyName(_lastExtractedLexem))
1445+
{
1446+
return CreateError(LocalizedErrors.IdentifierExpected());
1447+
}
1448+
1449+
var identifier = _lastExtractedLexem;
1450+
NextLexem();
1451+
if (_lastExtractedLexem.Token == Token.OpenPar)
1452+
{
1453+
var ident = new TerminalNode(NodeKind.Identifier, identifier);
1454+
var call = BuildCall(ident, NodeKind.MethodCall);
1455+
dotNode.AddChild(call);
1456+
}
1457+
else
1458+
{
1459+
_lastDereferenceIsWritable = true;
1460+
CreateChild(dotNode, NodeKind.Identifier, identifier);
1461+
}
1462+
1463+
return BuildDereference(dotNode);
14461464
}
14471465

14481466
private BslSyntaxNode BuildIndexerAccess(BslSyntaxNode target)
14491467
{
1450-
if (_lastExtractedLexem.Token == Token.OpenBracket)
1468+
if (_lastExtractedLexem.Token != Token.OpenBracket)
1469+
{
1470+
return target;
1471+
}
1472+
1473+
if (!IsDereferenceable(target))
14511474
{
1452-
var node = new NonTerminalNode(NodeKind.IndexAccess, _lastExtractedLexem);
1453-
node.AddChild(target);
1454-
NextLexem();
1455-
var expression = BuildExpression(node, Token.CloseBracket);
1456-
if (expression.Kind == NodeKind.Unknown)
1457-
{
1458-
return CreateError(LocalizedErrors.ExpressionSyntax());
1459-
}
1460-
NextLexem();
1461-
_lastDereferenceIsWritable = true;
1462-
return BuildDereference(node);
1475+
AddError(LocalizedErrors.ValueIsNotObjectException());
14631476
}
14641477

1465-
return target;
1478+
var node = new NonTerminalNode(NodeKind.IndexAccess, _lastExtractedLexem);
1479+
node.AddChild(target);
1480+
NextLexem();
1481+
var expression = BuildExpression(node, Token.CloseBracket);
1482+
if (expression.Kind == NodeKind.Unknown)
1483+
{
1484+
return CreateError(LocalizedErrors.ExpressionSyntax());
1485+
}
1486+
NextLexem();
1487+
_lastDereferenceIsWritable = true;
1488+
return BuildDereference(node);
14661489
}
14671490

14681491
private BslSyntaxNode BuildNewObjectCreation()

‎src/OneScript.Language/SyntaxAnalysis/LocalizedErrors.cs‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,10 @@ public static CodeError SymbolNotFound(string symbol) =>
164164

165165
public static CodeError AsyncMethodsNotSupported() =>
166166
Create("Асинхронные методы не поддерживаются", "Async methods aren't supported");
167-
}
168-
}
167+
168+
public static CodeError ValueIsNotObjectException()
169+
{
170+
return Create("Значение не является значением объектного типа", "Value is not of object type");
171+
}
172+
}
173+
}

0 commit comments

Comments
 (0)