Skip to content

Commit 6ed6301

Browse files
committed
#16 - update static analysis in SemanticChecker to support 'with' expression and refine visitor return types
1 parent f299f97 commit 6ed6301

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/Application/HydraScript.Application.StaticAnalysis/Visitors/SemanticChecker.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ internal class SemanticChecker : VisitorBase<IAbstractSyntaxTreeNode, Type>,
2626
IVisitor<IdentifierReference, Type>,
2727
IVisitor<Literal, Type>,
2828
IVisitor<ImplicitLiteral, Type>,
29-
IVisitor<ArrayLiteral, Type>,
30-
IVisitor<ObjectLiteral, Type>,
29+
IVisitor<ArrayLiteral, ArrayType>,
30+
IVisitor<ObjectLiteral, ObjectType>,
3131
IVisitor<ConditionalExpression, Type>,
3232
IVisitor<BinaryExpression, Type>,
3333
IVisitor<UnaryExpression, Type>,
@@ -37,6 +37,7 @@ internal class SemanticChecker : VisitorBase<IAbstractSyntaxTreeNode, Type>,
3737
IVisitor<IndexAccess, Type>,
3838
IVisitor<DotAccess, Type>,
3939
IVisitor<CastAsExpression, Type>,
40+
IVisitor<WithExpression, ObjectType>,
4041
IVisitor<CallExpression, Type>,
4142
IVisitor<FunctionDeclaration, Type>,
4243
IVisitor<BlockStatement, Type>,
@@ -163,7 +164,7 @@ public Type Visit(ImplicitLiteral visitable)
163164
return type;
164165
}
165166

166-
public Type Visit(ArrayLiteral visitable)
167+
public ArrayType Visit(ArrayLiteral visitable)
167168
{
168169
if (visitable.Expressions.Count == 0)
169170
return new ArrayType(new Any());
@@ -175,7 +176,7 @@ public Type Visit(ArrayLiteral visitable)
175176
throw new WrongArrayLiteralDeclaration(visitable.Segment, type);
176177
}
177178

178-
public Type Visit(ObjectLiteral visitable)
179+
public ObjectType Visit(ObjectLiteral visitable)
179180
{
180181
var properties = visitable.Properties.AsValueEnumerable().Select(prop =>
181182
{
@@ -398,6 +399,25 @@ public Type Visit(DotAccess visitable)
398399
return visitable.HasNext() ? visitable.Next?.Accept(This) ?? "undefined" : fieldType;
399400
}
400401

402+
public ObjectType Visit(WithExpression visitable)
403+
{
404+
var exprType = visitable.Expression.Accept(This);
405+
406+
if (exprType is not ObjectType supersetObjectType)
407+
throw new UnsupportedOperation(visitable.Segment, exprType, "with");
408+
409+
IVisitor<ObjectLiteral, ObjectType> objectLiteralVisitor = this;
410+
var subsetObjectType = visitable.ObjectLiteral.Accept(objectLiteralVisitor);
411+
412+
if (!supersetObjectType.IsSubsetOf(subsetObjectType))
413+
throw new IncompatibleTypesOfOperands(
414+
visitable.Segment,
415+
left: supersetObjectType,
416+
right: subsetObjectType);
417+
418+
return supersetObjectType;
419+
}
420+
401421
public Type Visit(CastAsExpression visitable)
402422
{
403423
Type undefined = "undefined";

0 commit comments

Comments
 (0)