@@ -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