Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
raw.compiler.rql2.antlr4.RawSnapiVisitor.scala Maven / Gradle / Ivy
/*
* Copyright 2024 RAW Labs S.A.
*
* Use of this software is governed by the Business Source License
* included in the file licenses/BSL.txt.
*
* As of the Change Date specified in that file, in accordance with
* the Business Source License, use of this software will be governed
* by the Apache License, Version 2.0, included in the file
* licenses/APL.txt.
*/
package raw.compiler.rql2.antlr4
import jakarta.xml.bind.DatatypeConverter
import org.antlr.v4.runtime.ParserRuleContext
import org.bitbucket.inkytonik.kiama.util.{Positions, Source}
import raw.client.api.{ErrorMessage, ErrorPosition, ErrorRange}
import raw.compiler.base.source.Type
import raw.compiler.common.source._
import raw.compiler.rql2.builtin.{ListPackageBuilder, RecordPackageBuilder}
import raw.compiler.rql2.generated.{SnapiParser, SnapiParserBaseVisitor}
import raw.compiler.rql2.source.{LetDecl, _}
import raw.utils.RawUtils
import scala.collection.JavaConverters._
import scala.util.Try
class RawSnapiVisitor(
positions: Positions,
private val source: Source,
isFrontend: Boolean,
private val errors: RawVisitorParseErrors
) extends SnapiParserBaseVisitor[SourceNode] {
private val positionsWrapper = new RawPositions(positions, source)
private val assertionMessage = "This is a helper (better grammar readability) node, should never visit it"
private def defaultProps: Set[Rql2TypeProperty] =
if (isFrontend) Set(Rql2IsTryableTypeProperty(), Rql2IsNullableTypeProperty())
else Set.empty
private def getBrokenTypeCompletion(t: Option[Type], context: ParserRuleContext): Option[Type] = {
if (t.isEmpty && context.getText.trim.last == ':' && !context.getText.contains("`")) {
Option(ErrorType().asInstanceOf[Type])
} else t
}
// An extension method to extract the identifier from a token (removes the backticks)
implicit class IdentExtension(ctx: SnapiParser.IdentContext) {
def getValue: String = Option(ctx)
.map { identContext =>
val result = Option(visit(identContext)).getOrElse(StringConst("")).asInstanceOf[StringConst].value
positionsWrapper.setPosition(identContext, result)
result
}
.getOrElse("")
}
override def visitProg(ctx: SnapiParser.ProgContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.stat))
.flatMap(statContext => Option(visit(statContext)))
.getOrElse(Rql2Program(Vector.empty, Option.empty))
override def visitFunDecStat(ctx: SnapiParser.FunDecStatContext): SourceNode = Option(ctx)
.map { context =>
val methods = Option(context.method_dec())
.map(m =>
m.asScala.map(md =>
Option(md)
.flatMap(mdContext => Option(visit(mdContext)))
.getOrElse(Rql2Method(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())), IdnDef("")))
.asInstanceOf[Rql2Method]
)
)
.getOrElse(Vector.empty)
.toVector
val result = Rql2Program(methods, Option.empty)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(Rql2Program(Vector.empty, Option.empty))
override def visitFunDecExprStat(ctx: SnapiParser.FunDecExprStatContext): SourceNode = Option(ctx)
.map { context =>
val methods = Option(context.method_dec())
.map(m =>
m.asScala.map(md =>
Option(md)
.flatMap(mdContext => Option(visit(mdContext)))
.getOrElse(Rql2Method(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())), IdnDef("")))
.asInstanceOf[Rql2Method]
)
)
.getOrElse(Vector.empty)
.toVector
val me = Option(context.expr).map(expContext => Option(visit(expContext)).getOrElse(ErrorExp()).asInstanceOf[Exp])
val result = Rql2Program(methods, me)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(Rql2Program(Vector.empty, Option.empty))
override def visitFun_proto(ctx: SnapiParser.Fun_protoContext): SourceNode = Option(ctx)
.map { context =>
val ps = Option(context.fun_param())
.map(p =>
p.asScala
.map(pr =>
Option(pr)
.flatMap(prr => Option(visit(prr)))
.getOrElse(FunParam(IdnDef(""), Option.empty, Option.empty))
.asInstanceOf[FunParam]
)
.toVector
)
.getOrElse(Vector.empty)
val funBody = Option(context.expr)
.map { expContext =>
val exp = Option(visit(expContext)).getOrElse(ErrorExp()).asInstanceOf[Exp]
val funBody = FunBody(exp)
positionsWrapper.setPosition(expContext, funBody)
funBody
}
.getOrElse(FunBody(ErrorExp()))
val result = FunProto(
ps,
Option(context.tipe()).map(tipeContext => Option(visit(tipeContext)).getOrElse(ErrorType()).asInstanceOf[Type]),
funBody
)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())))
override def visitFunProtoLambdaMultiParam(ctx: SnapiParser.FunProtoLambdaMultiParamContext): SourceNode = Option(ctx)
.map { context =>
val ps = Option(context.fun_param())
.map(params =>
params.asScala.map { paramsContext =>
Option(paramsContext)
.flatMap(paramItemContext => Option(visit(paramItemContext)))
.getOrElse(FunParam(IdnDef(""), Option.empty, Option.empty))
.asInstanceOf[FunParam]
}.toVector
)
.getOrElse(Vector.empty)
val funBody = Option(context.expr)
.map { expContext =>
val exp = Option(visit(expContext)).getOrElse(ErrorExp()).asInstanceOf[Exp]
val funBody = FunBody(exp)
positionsWrapper.setPosition(expContext, funBody)
funBody
}
.getOrElse(FunBody(ErrorExp()))
val result = FunProto(
ps,
Option(context.tipe()).map(tipeContext => Option(visit(tipeContext)).getOrElse(ErrorType()).asInstanceOf[Type]),
funBody
)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())))
override def visitFunProtoLambdaSingleParam(ctx: SnapiParser.FunProtoLambdaSingleParamContext): SourceNode =
Option(ctx)
.map { context =>
val ps = Option(context.attr())
.map { attContext =>
val idnDef = Option(attContext.ident())
.map(idnContext => {
val result = IdnDef(idnContext.getValue)
positionsWrapper.setPosition(idnContext, result)
result
})
.getOrElse(IdnDef(""))
val tipe = {
val t = Option(attContext.tipe())
.map(attTipeContext => Option(visit(attTipeContext)).getOrElse(ErrorType()).asInstanceOf[Type])
getBrokenTypeCompletion(t, attContext)
}
val funParam = FunParam(idnDef, tipe, Option.empty)
positionsWrapper.setPosition(attContext, funParam)
Vector(funParam)
}
.getOrElse(Vector.empty)
val funBody = Option(context.expr)
.map { expContext =>
val exp = Option(visit(expContext)).getOrElse(ErrorExp()).asInstanceOf[Exp]
val funBody = FunBody(exp)
positionsWrapper.setPosition(expContext, funBody)
funBody
}
.getOrElse(FunBody(ErrorExp()))
val result = FunProto(
ps,
Option(context.tipe())
.map(tipeContext => Option(visit(tipeContext)).getOrElse(ErrorType()).asInstanceOf[Type]),
funBody
)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())))
override def visitMethodDec(ctx: SnapiParser.MethodDecContext): SourceNode = Option(ctx)
.map { context =>
val funProto = Option(context.fun_proto())
.flatMap(funProtoContext => Option(visit(funProtoContext)))
.getOrElse(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())))
.asInstanceOf[FunProto]
val idnDef = Option(context.ident)
.map { idnContext =>
val res = IdnDef(idnContext.getValue)
positionsWrapper.setPosition(idnContext, res)
res
}
.getOrElse(IdnDef(""))
val result = Rql2Method(funProto, idnDef)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(Rql2Method(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())), IdnDef("")))
override def visitNormalFun(ctx: SnapiParser.NormalFunContext): SourceNode = Option(ctx)
.map { context =>
val funProto = Option(context.fun_proto())
.flatMap(funProtoContext => Option(visit(funProtoContext)))
.getOrElse(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())))
.asInstanceOf[FunProto]
val idnDef = Option(context.ident)
.map { idnContext =>
val res = IdnDef(idnContext.getValue)
positionsWrapper.setPosition(idnContext, res)
res
}
.getOrElse(IdnDef(""))
val result: LetFun = LetFun(funProto, idnDef)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(LetFun(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())), IdnDef("")))
override def visitRecFun(ctx: SnapiParser.RecFunContext): SourceNode = Option(ctx)
.map { context =>
val funProto = Option(context.fun_proto())
.flatMap(funProtoContext => Option(visit(funProtoContext)))
.getOrElse(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())))
.asInstanceOf[FunProto]
val idnDef = Option(context.ident)
.map { idnContext =>
val res = IdnDef(idnContext.getValue)
positionsWrapper.setPosition(idnContext, res)
res
}
.getOrElse(IdnDef(""))
val result = LetFunRec(idnDef, funProto)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(LetFunRec(IdnDef(""), FunProto(Vector.empty, Option.empty, FunBody(ErrorExp()))))
override def visitFunParamAttr(ctx: SnapiParser.FunParamAttrContext): SourceNode = Option(ctx)
.map { context =>
val result = Option(context.attr)
.map { attrContext =>
val idnDef = Option(attrContext.ident)
.map { idnContext =>
val res = IdnDef(idnContext.getValue)
positionsWrapper.setPosition(idnContext, res)
res
}
.getOrElse(IdnDef(""))
val tipe = {
val t = Option(attrContext.tipe)
.map(attrTipeContext => Option(visit(attrTipeContext)).getOrElse(ErrorType()).asInstanceOf[Type])
getBrokenTypeCompletion(t, attrContext)
}
val result = FunParam(
idnDef,
tipe,
Option.empty
)
positionsWrapper.setPosition(attrContext, result)
result
}
.getOrElse(FunParam(IdnDef(""), Option.empty, Option.empty))
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunParam(IdnDef(""), Option.empty, Option.empty))
override def visitFunParamAttrExpr(ctx: SnapiParser.FunParamAttrExprContext): SourceNode = Option(ctx)
.map { context =>
val tupple = Option(context.attr)
.map { attrContext =>
val idnDef = Option(attrContext.ident)
.map { idnContext =>
val res = IdnDef(idnContext.getValue)
positionsWrapper.setPosition(idnContext, res)
res
}
.getOrElse(IdnDef(""))
val tipe = Option(attrContext.tipe)
.map(attrTipeContext => Option(visit(attrTipeContext)).getOrElse(ErrorType).asInstanceOf[Type])
(idnDef, tipe)
}
.getOrElse((IdnDef(""), Option.empty))
val exp =
Option(context.expr()).map(exprContext => Option(visit(exprContext)).getOrElse(ErrorExp).asInstanceOf[Exp])
val result = FunParam(
tupple._1,
tupple._2,
exp
)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunParam(IdnDef(""), Option.empty, Option.empty))
override def visitType_attr(ctx: SnapiParser.Type_attrContext): SourceNode = Option(ctx)
.map { context =>
val ident = Option(context.ident()).map(identContext => identContext.getValue).getOrElse("")
val tipe = Option(context.tipe())
.map(tipeContext => Option(visit(tipeContext)).getOrElse(ErrorType()).asInstanceOf[Type])
.getOrElse(ErrorType())
val result = Rql2AttrType(ident, tipe)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(Rql2AttrType("", ErrorType()))
override def visitFunArgExpr(ctx: SnapiParser.FunArgExprContext): SourceNode = Option(ctx)
.flatMap { context =>
Option(context.expr()).map { exprContext =>
val result: FunAppArg =
FunAppArg(Option(visit(exprContext)).getOrElse(ErrorExp).asInstanceOf[Exp], Option.empty)
positionsWrapper.setPosition(context, result)
result
}
}
.getOrElse(FunAppArg(ErrorExp(), Option.empty))
override def visitNamedFunArgExpr(ctx: SnapiParser.NamedFunArgExprContext): SourceNode = Option(ctx)
.map { context =>
val exp = Option(context.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val ident = Option(context.ident()).map { identContext =>
val result = identContext.getValue
positionsWrapper.setPosition(identContext, result)
result
}
val result = FunAppArg(exp, ident)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunAppArg(ErrorExp(), Option.empty))
override def visitFunAbs(ctx: SnapiParser.FunAbsContext): SourceNode = Option(ctx)
.flatMap { context =>
Option(context.fun_proto_lambda()).map { funProtoLambdaContext =>
val funProto = Option(visit(funProtoLambdaContext))
.getOrElse(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())))
.asInstanceOf[FunProto]
val result = FunAbs(funProto)
positionsWrapper.setPosition(context, result)
result
}
}
.getOrElse(FunAbs(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp()))))
override def visitFunAbsUnnamed(ctx: SnapiParser.FunAbsUnnamedContext): SourceNode = Option(ctx)
.map { context =>
val funParam = Option(context.ident())
.map { identContext =>
val idnDef = IdnDef(identContext.getValue)
positionsWrapper.setPosition(identContext, idnDef)
val funParam = FunParam(idnDef, Option.empty, Option.empty)
positionsWrapper.setPosition(identContext, funParam)
funParam
}
.getOrElse(FunParam(IdnDef(""), Option.empty, Option.empty))
val funBody = Option(context.expr())
.map { exprContext =>
val funBody = FunBody(Option(visit(exprContext)).getOrElse(ErrorExp()).asInstanceOf[Exp])
positionsWrapper.setPosition(exprContext, funBody)
funBody
}
.getOrElse(FunBody(ErrorExp()))
val funProto = FunProto(Vector(funParam), Option.empty, funBody)
positionsWrapper.setPosition(context, funProto)
val result = FunAbs(funProto)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunAbs(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp()))))
override def visitFunTypeWithParamsType(ctx: SnapiParser.FunTypeWithParamsTypeContext): SourceNode = Option(ctx)
.map { context =>
val ms = Option(context.param_list())
.flatMap { paramListContext =>
Option(
paramListContext
.tipe()
).map(typeList =>
typeList.asScala
.map(tctx =>
Option(tctx)
.flatMap(tctxContext => Option(visit(tctxContext)))
.getOrElse(ErrorType)
.asInstanceOf[Type]
)
.toVector
)
}
.getOrElse(Vector.empty)
val os = Option(context.param_list())
.flatMap { paramListContext =>
Option(
paramListContext
.attr()
).map(listOfAttrs =>
listOfAttrs.asScala.map { attrCtx =>
Option(attrCtx)
.map { a =>
val ident = Option(a.ident()).map(_.getValue).getOrElse("")
val tipe = Option(a.tipe())
.flatMap(aTipeContext => Option(visit(aTipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val funOptTypeParam = FunOptTypeParam(ident, tipe)
positionsWrapper.setPosition(a, funOptTypeParam)
funOptTypeParam
}
.getOrElse(FunOptTypeParam("", ErrorType()))
}.toVector
)
}
.getOrElse(Vector.empty)
val rType = Option(context.tipe())
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val result: FunType = FunType(
ms,
os,
rType,
defaultProps
)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(FunType(Vector.empty, Vector.empty, ErrorType(), defaultProps))
override def visitOrTypeType(ctx: SnapiParser.OrTypeTypeContext): SourceNode = Option(ctx)
.map { context =>
val tipes = Option(context.tipe())
.map(tipeContext => Vector(Option(visit(tipeContext)).getOrElse(ErrorType()).asInstanceOf[Type]))
.getOrElse(Vector.empty)
val orType = Option(context.or_type())
.flatMap(orTypeContext => Option(visit(orTypeContext)))
.getOrElse(Rql2OrType(Vector(ErrorType())))
.asInstanceOf[Rql2OrType]
val combinedTypes = tipes ++ orType.tipes
val result = Rql2OrType(combinedTypes, defaultProps)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(Rql2OrType(Vector(ErrorType())))
// this one is helper, it doesn't need to set position (basically an accumulator for or_type)
override def visitOr_type(ctx: SnapiParser.Or_typeContext): SourceNode = Option(ctx)
.map { context =>
val tipe = Option(context.tipe())
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val orType = Option(context.or_type())
.flatMap(orTypeContext => Option(visit(orTypeContext)))
.getOrElse(Rql2OrType(Vector.empty))
.asInstanceOf[Rql2OrType]
Rql2OrType(Vector(tipe) ++ orType.tipes, defaultProps)
}
.getOrElse(ErrorType())
override def visitOrTypeFunType(ctx: SnapiParser.OrTypeFunTypeContext): SourceNode = Option(ctx)
.map { context =>
val types = Option(context.tipe(0))
.map(tipeContext => Vector(Option(visit(tipeContext)).getOrElse(ErrorType()).asInstanceOf[Type]))
.getOrElse(Vector.empty)
val orType = Option(context.or_type())
.flatMap(orTypeContext => Option(visit(orTypeContext)))
.getOrElse(Rql2OrType(Vector.empty))
.asInstanceOf[Rql2OrType]
val combinedTypes = types ++ orType.tipes
val domainOrType = Rql2OrType(combinedTypes, defaultProps)
val rType = Option(context.tipe(1))
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val funType = FunType(
Vector(domainOrType),
Vector.empty,
rType,
defaultProps
)
positionsWrapper.setPosition(context, funType)
funType
}
.getOrElse(ErrorType())
override def visitRecordTypeType(ctx: SnapiParser.RecordTypeTypeContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.record_type).flatMap(recordTypeContext => Option(visit(recordTypeContext))))
.getOrElse(ErrorType())
.asInstanceOf[Rql2RecordType]
override def visitIterableTypeType(ctx: SnapiParser.IterableTypeTypeContext): SourceNode = Option(ctx)
.flatMap(context =>
Option(context.iterable_type).flatMap(iterableTypeContext => Option(visit(iterableTypeContext)))
)
.getOrElse(ErrorType())
.asInstanceOf[Rql2IterableType]
override def visitTypeWithParenType(ctx: SnapiParser.TypeWithParenTypeContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.tipe()).flatMap(tipeContext => Option(visit(tipeContext))))
.getOrElse(ErrorType())
override def visitListTypeType(ctx: SnapiParser.ListTypeTypeContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.list_type).flatMap(tipeContext => Option(visit(tipeContext))))
.getOrElse(ErrorType())
override def visitPrimitiveTypeType(ctx: SnapiParser.PrimitiveTypeTypeContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.primitive_types).flatMap(premTypesContext => Option(visit(premTypesContext))))
.getOrElse(ErrorType())
override def visitPrimitive_types(ctx: SnapiParser.Primitive_typesContext): SourceNode = Option(ctx)
.map { context =>
val result =
if (context.BOOL_TOKEN != null) Rql2BoolType(defaultProps)
else if (context.STRING_TOKEN != null) Rql2StringType(defaultProps)
else if (context.LOCATION_TOKEN != null) Rql2LocationType(defaultProps)
else if (context.BINARY_TOKEN != null) Rql2BinaryType(defaultProps)
else if (context.DATE_TOKEN != null) Rql2DateType(defaultProps)
else if (context.TIME_TOKEN != null) Rql2TimeType(defaultProps)
else if (context.INTERVAL_TOKEN != null) Rql2IntervalType(defaultProps)
else if (context.TIMESTAMP_TOKEN != null) Rql2TimestampType(defaultProps)
else if (context.BYTE_TOKEN != null) Rql2ByteType(defaultProps)
else if (context.SHORT_TOKEN != null) Rql2ShortType(defaultProps)
else if (context.INT_TOKEN != null) Rql2IntType(defaultProps)
else if (context.LONG_TOKEN != null) Rql2LongType(defaultProps)
else if (context.FLOAT_TOKEN != null) Rql2FloatType(defaultProps)
else if (context.DOUBLE_TOKEN != null) Rql2DoubleType(defaultProps)
else if (context.DECIMAL_TOKEN != null) Rql2DecimalType(defaultProps)
else if (context.UNDEFINED_TOKEN != null) Rql2UndefinedType(defaultProps)
else throw new AssertionError("Unknown primitive type")
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorType())
override def visitTypeAliasType(ctx: SnapiParser.TypeAliasTypeContext): SourceNode = Option(ctx)
.flatMap { context =>
Option(context.ident()).map { ident =>
val idnUse = IdnUse(ident.getValue)
val result = TypeAliasType(idnUse)
positionsWrapper.setPosition(context, idnUse)
positionsWrapper.setPosition(context, result)
result
}
}
.getOrElse(ErrorType())
override def visitFunTypeType(ctx: SnapiParser.FunTypeTypeContext): SourceNode = Option(ctx)
.map { context =>
val ms = Option(context.tipe(0))
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val r = Option(context.tipe(1))
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val funType = FunType(
Vector(ms),
Vector.empty,
r,
defaultProps
)
positionsWrapper.setPosition(context, funType)
funType
}
.getOrElse(ErrorType())
override def visitExprTypeExpr(ctx: SnapiParser.ExprTypeExprContext): SourceNode = Option(ctx)
.map { context =>
val exp = Option(context.expr_type())
.flatMap(exprTypeContext => Option(visit(exprTypeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val result = TypeExp(exp)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitRecord_type(ctx: SnapiParser.Record_typeContext): SourceNode = {
Option(ctx)
.map { context =>
val atts = Option(context.record_attr_list())
.flatMap { attrListContext =>
Option(attrListContext.type_attr()).map(listOfAttr =>
listOfAttr.asScala
.map(a =>
Option(a)
.flatMap(aContext => Option(visit(aContext)))
.getOrElse(Rql2AttrType("", ErrorType()))
.asInstanceOf[Rql2AttrType]
)
.toVector
)
}
.getOrElse(Vector.empty)
val result = Rql2RecordType(atts, defaultProps)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorType())
}
override def visitIterable_type(ctx: SnapiParser.Iterable_typeContext): SourceNode = Option(ctx)
.map { context =>
val tipe = Option(context.tipe())
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val result = Rql2IterableType(tipe, defaultProps)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorType())
override def visitList_type(ctx: SnapiParser.List_typeContext): SourceNode = Option(ctx)
.map { context =>
val tipe = Option(context.tipe())
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val result = Rql2ListType(tipe, defaultProps)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorType())
override def visitExpr_type(ctx: SnapiParser.Expr_typeContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.tipe()).flatMap(tipeContext => Option(visit(tipeContext))))
.getOrElse(ErrorType())
override def visitPackageEntryTypeType(ctx: SnapiParser.PackageEntryTypeTypeContext): SourceNode = Option(ctx)
.flatMap(context =>
Option(context.string_literal()).map { stringLiteralContext =>
val packageName = {
val packName = Option(stringLiteralContext.get(0))
.flatMap(strLiteralContext => Option(visit(strLiteralContext)))
.getOrElse(StringConst(""))
.asInstanceOf[StringConst]
positionsWrapper.setPosition(stringLiteralContext.get(0), packName)
packName
}.value
val entryName = {
val entName = Option(stringLiteralContext.get(1))
.flatMap(strLiteralContext => Option(visit(strLiteralContext)))
.getOrElse(StringConst(""))
.asInstanceOf[StringConst]
positionsWrapper.setPosition(stringLiteralContext.get(1), entName)
entName
}.value
val result = PackageEntryType(packageName, entryName)
positionsWrapper.setPosition(context, result)
result
}
)
.getOrElse(ErrorType())
override def visitPackageTypeType(ctx: SnapiParser.PackageTypeTypeContext): SourceNode = Option(ctx)
.map { context =>
val packageName = Option(context.string_literal())
.flatMap { stringLiteralContext =>
Option(visit(stringLiteralContext)).map { stringLitNode =>
positionsWrapper.setPosition(stringLiteralContext, stringLitNode)
stringLitNode
}
}
.getOrElse(StringConst(""))
.asInstanceOf[StringConst]
val result = PackageType(packageName.value)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorType())
override def visitIdentExpr(ctx: SnapiParser.IdentExprContext): SourceNode = Option(ctx)
.map { context =>
val idnUse = Option(context.ident()).map(identContext => IdnUse(identContext.getValue)).getOrElse(IdnUse(""))
val result = IdnExp(idnUse)
positionsWrapper.setPosition(context, idnUse)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitProjectionExpr(ctx: SnapiParser.ProjectionExprContext): SourceNode = Option(ctx)
.map { context =>
val ident = Option(context.ident()).map(identContext => identContext.getValue).getOrElse("")
val expr = Option(context.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val proj = Proj(expr, ident)
val result = Option(context.fun_ar())
.map(funArContext => {
// The projection with the function call
val args = Option(funArContext.fun_args)
.flatMap(ar =>
Option(ar.fun_arg)
.map(arg =>
arg.asScala
.map(a =>
Option(a)
.flatMap(aContext => Option(visit(aContext)))
.getOrElse(FunAppArg(ErrorExp(), Option.empty))
.asInstanceOf[FunAppArg]
)
.toVector
)
)
.getOrElse(Vector.empty)
positionsWrapper.setPosition(
context.getStart,
Option(context.ident()).map(identContext => identContext.getStop).getOrElse(context.getStart),
proj
)
FunApp(proj, args)
})
.getOrElse(proj)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitLetExpr(ctx: SnapiParser.LetExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.let()).flatMap(letContext => Option(visit(letContext))))
.getOrElse(ErrorExp())
override def visitFunAbsExpr(ctx: SnapiParser.FunAbsExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.fun_abs()).flatMap(funAbsContext => Option(visit(funAbsContext))))
.getOrElse(ErrorExp())
override def visitFunAppExpr(ctx: SnapiParser.FunAppExprContext): SourceNode = {
Option(ctx)
.map { context =>
val args = Option(context.fun_ar())
.flatMap { funArContext =>
Option(funArContext.fun_args()).flatMap { funArgsContext =>
Option(funArgsContext.fun_arg())
.map { funArgContext =>
funArgContext.asScala
.map(a =>
Option(a)
.flatMap(aContext => Option(visit(aContext)))
.getOrElse(FunAppArg(ErrorExp(), Option.empty))
.asInstanceOf[FunAppArg]
)
.toVector
}
}
}
.getOrElse(Vector.empty)
val exp = Option(context.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = FunApp(exp, args)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
}
override def visitIfThenElseExpr(ctx: SnapiParser.IfThenElseExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.if_then_else()).flatMap(ifThenElseContext => Option(visit(ifThenElseContext))))
.getOrElse(ErrorExp())
override def visitExprTypeType(ctx: SnapiParser.ExprTypeTypeContext): SourceNode = Option(ctx)
.map { context =>
val expType = Option(context.expr_type())
.flatMap(exprTypeContext => Option(visit(exprTypeContext)))
.getOrElse(ErrorType())
.asInstanceOf[Type]
val result = ExpType(expType)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorType())
override def visitListExpr(ctx: SnapiParser.ListExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.lists()).flatMap(listContext => Option(visit(listContext))))
.getOrElse(ErrorExp())
// Unary expressions
override def visitNotExpr(ctx: SnapiParser.NotExprContext): SourceNode = Option(ctx)
.map { context =>
val not = Not()
positionsWrapper.setPosition(context.NOT_TOKEN.getSymbol, not)
val expr = Option(context.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = UnaryExp(not, expr)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitMinusUnaryExpr(ctx: SnapiParser.MinusUnaryExprContext): SourceNode = Option(ctx)
.map { context =>
val neg = Neg()
positionsWrapper.setPosition(context.MINUS_TOKEN.getSymbol, neg)
val expr = Option(context.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = UnaryExp(neg, expr)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitPlusUnaryExpr(ctx: SnapiParser.PlusUnaryExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.expr()).flatMap(exprContext => Option(visit(exprContext))))
.getOrElse(ErrorExp())
// Binary expressions
override def visitCompareExpr(ctx: SnapiParser.CompareExprContext): SourceNode = Option(ctx)
.map { context =>
// arbitrarily adding eq because we don't know which token is messing
val compareToken = Option(context.compare_tokens)
.flatMap(compareTokenContext => Option(visit(compareTokenContext)))
.getOrElse(Eq())
.asInstanceOf[ComparableOp]
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(compareToken, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitCompare_tokens(ctx: SnapiParser.Compare_tokensContext): SourceNode = Option(ctx)
.map { context =>
val result =
if (context.EQ_TOKEN != null) Eq()
else if (context.NEQ_TOKEN != null) Neq()
else if (context.GT_TOKEN != null) Gt()
else if (context.GE_TOKEN != null) Ge()
else if (context.LT_TOKEN != null) Lt()
else if (context.LE_TOKEN != null) Le()
else throw new AssertionError("Unknown comparable operator")
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(Eq())
override def visitOrExpr(ctx: SnapiParser.OrExprContext): SourceNode = Option(ctx)
.map { context =>
val or = Or()
positionsWrapper.setPosition(context.OR_TOKEN.getSymbol, or)
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(or, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitAndExpr(ctx: SnapiParser.AndExprContext): SourceNode = Option(ctx)
.map { context =>
val and = And()
positionsWrapper.setPosition(context.AND_TOKEN.getSymbol, and)
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(and, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitMulExpr(ctx: SnapiParser.MulExprContext): SourceNode = Option(ctx)
.map { context =>
val mult = Mult()
positionsWrapper.setPosition(context.MUL_TOKEN().getSymbol, mult)
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(mult, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitDivExpr(ctx: SnapiParser.DivExprContext): SourceNode = Option(ctx)
.map { context =>
val div: Div = Div()
positionsWrapper.setPosition(context.DIV_TOKEN().getSymbol, div)
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(div, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitModExpr(ctx: SnapiParser.ModExprContext): SourceNode = Option(ctx)
.map { context =>
val mod: Mod = Mod()
positionsWrapper.setPosition(context.MOD_TOKEN().getSymbol, mod)
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(mod, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitPlusExpr(ctx: SnapiParser.PlusExprContext): SourceNode = Option(ctx)
.map { context =>
val plus: Plus = Plus()
positionsWrapper.setPosition(context.PLUS_TOKEN().getSymbol, plus)
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(plus, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitMinusExpr(ctx: SnapiParser.MinusExprContext): SourceNode = Option(ctx)
.map { context =>
val sub: Sub = Sub()
positionsWrapper.setPosition(context.MINUS_TOKEN().getSymbol, sub)
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = BinaryExp(sub, expr1, expr2)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitParenExpr(ctx: SnapiParser.ParenExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.expr()).flatMap(exprContext => Option(visit(exprContext))))
.getOrElse(ErrorExp())
override def visitRecordExpr(ctx: SnapiParser.RecordExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.records()).flatMap(recordsContext => Option(visit(recordsContext))))
.getOrElse(ErrorExp())
override def visitLet(ctx: SnapiParser.LetContext): SourceNode = Option(ctx)
.map { context =>
val decls = Option(context.let_left())
.flatMap(letLeftExpr =>
Option(letLeftExpr.let_decl()).map(letDecl =>
letDecl.asScala
.map(letDeclContext =>
Option(visit(letDeclContext))
.getOrElse(LetBind(ErrorExp(), IdnDef(""), Option.empty))
.asInstanceOf[LetDecl]
)
.toVector
)
)
.getOrElse(Vector.empty)
val expr = Option(context.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = Let(decls, expr)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitLetBind(ctx: SnapiParser.LetBindContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.let_bind()).flatMap(letBindContext => Option(visit(letBindContext))))
.getOrElse(LetBind(ErrorExp(), IdnDef(""), Option.empty))
override def visitLetFunDec(ctx: SnapiParser.LetFunDecContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.fun_dec()).flatMap(funDecContext => Option(visit(funDecContext))))
.getOrElse(LetFun(FunProto(Vector.empty, Option.empty, FunBody(ErrorExp())), IdnDef("")))
override def visitLet_bind(ctx: SnapiParser.Let_bindContext): SourceNode = Option(ctx)
.map { context =>
val tipe = {
val t =
Option(context.tipe).map(tipeContext => Option(visit(tipeContext)).getOrElse(ErrorType()).asInstanceOf[Type])
getBrokenTypeCompletion(t, context)
}
val idnDef = IdnDef(context.ident.getValue)
positionsWrapper.setPosition(context.ident, idnDef)
val exp = Option(context.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = LetBind(exp, idnDef, tipe)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(LetBind(ErrorExp(), IdnDef(""), Option.empty))
override def visitIf_then_else(ctx: SnapiParser.If_then_elseContext): SourceNode = Option(ctx)
.map { context =>
val expr1 = Option(context.expr(0))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr2 = Option(context.expr(1))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val expr3 = Option(context.expr(2))
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
val result = IfThenElse(expr1, expr2, expr3)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitLists(ctx: SnapiParser.ListsContext): SourceNode = Option(ctx)
.map { context =>
Option(context.lists_element()).flatMap(listElementContext => Option(visit(listElementContext))).getOrElse {
val result = ListPackageBuilder.Build()
positionsWrapper.setPosition(context, result)
result
}
}
.getOrElse(ErrorExp())
override def visitLists_element(ctx: SnapiParser.Lists_elementContext): SourceNode = Option(ctx)
.map { context =>
val exprs = Option(context.expr)
.map(exprContext =>
exprContext.asScala
.map(e => Option(e).flatMap(eContext => Option(visit(eContext))).getOrElse(ErrorExp()).asInstanceOf[Exp])
.toVector
)
.getOrElse(Vector.empty)
val result = ListPackageBuilder.Build(exprs: _*)
positionsWrapper.setPosition(context.parent.asInstanceOf[ParserRuleContext], result)
result
}
.getOrElse(ErrorExp())
override def visitRecords(ctx: SnapiParser.RecordsContext): SourceNode = Option(ctx)
.map { context =>
Option(context.record_elements())
.flatMap(recordElementsContext => Option(visit(recordElementsContext)))
.getOrElse {
val result = RecordPackageBuilder.Build()
positionsWrapper.setPosition(context, result)
result
}
}
.getOrElse(ErrorExp())
override def visitRecord_elements(ctx: SnapiParser.Record_elementsContext): SourceNode = Option(ctx)
.map { context =>
val tuples = Option(context.record_element())
.map(recordElemntContext =>
recordElemntContext.asScala.zipWithIndex.map {
case (e, idx) => Option(e)
.map { eContext =>
val exp = Option(eContext.expr())
.flatMap(exprContext => Option(visit(exprContext)))
.getOrElse(ErrorExp())
.asInstanceOf[Exp]
Option(eContext.ident()).map(i => (i.getValue, exp)).getOrElse {
exp match {
case proj: Proj => (proj.i, exp)
case _ => ("_" + (idx + 1), exp)
}
}
}
.getOrElse(("", ErrorExp()))
}.toVector
)
.getOrElse(Vector.empty)
val result: Exp = RecordPackageBuilder.Build(tuples)
positionsWrapper.setPosition(context.parent.asInstanceOf[ParserRuleContext], result)
result
}
.getOrElse(ErrorExp())
// Constants
override def visitStringLiteralExpr(ctx: SnapiParser.StringLiteralExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.string_literal()).flatMap(stringLitContext => Option(visit(stringLitContext))))
.getOrElse(ErrorExp())
override def visitString_literal(ctx: SnapiParser.String_literalContext): SourceNode = {
Option(ctx)
.map { context =>
Option(context.STRING())
.map { stringConst =>
val result = StringConst(
RawUtils.escape(
stringConst.getText
.substring(1, context.STRING.getText.length - 1)
)
)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse {
Option(context.triple_string_literal())
.flatMap(strLitContext => Option(visit(strLitContext)))
.getOrElse(ErrorExp())
}
}
.getOrElse(ErrorExp())
}
override def visitTriple_string_literal(ctx: SnapiParser.Triple_string_literalContext): SourceNode = Option(ctx)
.map { context =>
val result = TripleQuotedStringConst(context.getText.drop(3).dropRight(3))
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitBoolConstExpr(ctx: SnapiParser.BoolConstExprContext): SourceNode = Option(ctx)
.map { context =>
val result = BoolConst(context.bool_const.FALSE_TOKEN == null)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitNullExpr(ctx: SnapiParser.NullExprContext): SourceNode = Option(ctx)
.map { context =>
val result = NullConst()
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
override def visitSignedNumberExpr(ctx: SnapiParser.SignedNumberExprContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.signed_number()).flatMap(signedNumber => Option(visit(signedNumber))))
.getOrElse(ErrorExp())
override def visitSigned_number(ctx: SnapiParser.Signed_numberContext): SourceNode = Option(ctx)
.map { context =>
val sign = Option(context.MINUS_TOKEN()).map(_ => "-").getOrElse("")
val result =
if (context.number.BYTE != null) ByteConst(sign + context.number.BYTE.getText.toLowerCase.replace("b", ""))
else if (context.number.SHORT != null)
ShortConst(sign + context.number.SHORT.getText.toLowerCase.replace("s", ""))
else if (context.number.INTEGER != null) {
val intText = sign + context.number.INTEGER.getText.toLowerCase
val intTry = Try(intText.toInt)
if (intTry.isSuccess) IntConst(intText)
else {
val longTry = Try(intText.toLong)
if (longTry.isSuccess) LongConst(intText)
else DoubleConst(intText)
}
} else if (context.number.LONG != null)
LongConst(sign + context.number.LONG.getText.toLowerCase.replace("l", ""))
else if (context.number.FLOAT != null)
FloatConst(sign + context.number.FLOAT.getText.toLowerCase.replace("f", ""))
else if (context.number.DOUBLE != null)
DoubleConst(sign + context.number.DOUBLE.getText.toLowerCase.replace("d", ""))
else if (context.number.DECIMAL != null)
DecimalConst(sign + context.number.DECIMAL.getText.toLowerCase.replace("q", ""))
else throw new AssertionError("Unknown number type")
val posContext = if (context.PLUS_TOKEN() != null) context.number() else context
positionsWrapper.setPosition(posContext, result)
result
}
.getOrElse(ErrorExp())
override def visitNumber(ctx: SnapiParser.NumberContext): SourceNode = Option(ctx)
.map(context => {
if (context.BYTE != null) ByteConst(context.BYTE.getText.toLowerCase.replace("b", ""))
else if (context.SHORT != null) ShortConst(context.SHORT.getText.toLowerCase.replace("s", ""))
else if (context.INTEGER != null) {
val intText = context.INTEGER.getText.toLowerCase
val intTry = Try(intText.toInt)
if (intTry.isSuccess) IntConst(intText)
else {
val longTry = Try(intText.toLong)
if (longTry.isSuccess) LongConst(intText)
else DoubleConst(intText)
}
} else if (context.LONG != null) LongConst(context.LONG.getText.toLowerCase.replace("l", ""))
else if (context.FLOAT != null) FloatConst(context.FLOAT.getText.toLowerCase.replace("f", ""))
else if (context.DOUBLE != null) DoubleConst(context.DOUBLE.getText.toLowerCase.replace("d", ""))
else if (context.DECIMAL != null) DecimalConst(context.DECIMAL.getText.toLowerCase.replace("q", ""))
else throw new AssertionError("Unknown number type")
})
.getOrElse(ErrorExp())
override def visitBinaryConstExpr(ctx: SnapiParser.BinaryConstExprContext): SourceNode = {
if (isFrontend) {
notFrontendError(ctx)
} else {
Option(ctx)
.flatMap { context =>
Option(context.BINARY_CONST())
.map(bContext =>
Try(BinaryConst(DatatypeConverter.parseHexBinary(bContext.getText.drop(2)))).getOrElse {
errors.addError(
ErrorMessage(
"Invalid binary literal",
List(
ErrorRange(
ErrorPosition(context.getStart.getLine, context.getStart.getCharPositionInLine + 1),
ErrorPosition(context.getStop.getLine, context.getStop.getCharPositionInLine + 1)
)
),
ParserErrors.ParserErrorCode
)
)
ErrorExp()
}
)
}
.getOrElse(ErrorExp())
}
}
override def visitIdent(ctx: SnapiParser.IdentContext): SourceNode = Option(ctx)
.map { context =>
Option(context.ESC_IDENTIFIER)
.map(_ => StringConst(context.getText.drop(1).dropRight(1))) // Escaped identifier
.getOrElse(StringConst(context.getText)) // Regular identifier
}
.getOrElse(ErrorExp())
// Nullable tryable
private def notFrontendError(ctx: ParserRuleContext): SourceNode = {
Option(ctx).foreach { context =>
errors.addError(
ErrorMessage(
"Not supported in frontend",
List(
ErrorRange(
ErrorPosition(context.getStart.getLine, context.getStart.getCharPositionInLine + 1),
ErrorPosition(context.getStop.getLine, context.getStop.getCharPositionInLine + 1)
)
),
ParserErrors.ParserErrorCode
)
)
}
ErrorExp()
}
override def visitNullableTryableType(ctx: SnapiParser.NullableTryableTypeContext): SourceNode = {
if (isFrontend) {
notFrontendError(ctx)
} else {
Option(ctx)
.map { context =>
val tipe = Option(context.tipe)
.flatMap(tipeContext => Option(visit(tipeContext)))
.getOrElse(ErrorType())
tipe match {
case rql2TypeWithProperties: Rql2TypeWithProperties => Option(context.nullable_tryable())
.map { nullableTryable =>
val withoutNullable = Option(nullableTryable.NULLABLE_TOKEN())
.map(_ =>
rql2TypeWithProperties
.cloneAndAddProp(Rql2IsNullableTypeProperty())
.asInstanceOf[Rql2TypeWithProperties]
)
.getOrElse(rql2TypeWithProperties)
Option(nullableTryable.TRYABLE_TOKEN())
.map(_ =>
withoutNullable.cloneAndAddProp(Rql2IsTryableTypeProperty()).asInstanceOf[Rql2TypeWithProperties]
)
.getOrElse(withoutNullable)
}
.getOrElse(tipe)
case _ => tipe
}
}
.getOrElse(ErrorType())
}
}
override def visitPackage_idn_exp(ctx: SnapiParser.Package_idn_expContext): SourceNode = {
if (isFrontend) {
notFrontendError(ctx)
} else {
Option(ctx)
.map { context =>
val stringLiteral = Option(context.string_literal())
.flatMap(stringLitContext => Option(visit(stringLitContext)))
.getOrElse(ErrorExp())
val str = stringLiteral match {
case StringConst(s) => s
case TripleQuotedStringConst(s) => s
case ErrorExp() => ""
case _ => throw new AssertionError("Unexpected string literal")
}
val result = PackageIdnExp(str)
positionsWrapper.setPosition(context, result)
result
}
.getOrElse(ErrorExp())
}
}
override def visitPackageIdnExp(ctx: SnapiParser.PackageIdnExpContext): SourceNode = Option(ctx)
.flatMap(context => Option(context.package_idn_exp()))
.flatMap(packageIdnContext => Option(visit(packageIdnContext)))
.getOrElse(ErrorExp())
// Nodes to ignore, they are not part of the AST and should never be visited
override def visitBool_const(ctx: SnapiParser.Bool_constContext): SourceNode =
throw new AssertionError(assertionMessage)
override def visitRecord_element(ctx: SnapiParser.Record_elementContext): SourceNode =
throw new AssertionError(assertionMessage)
override def visitLet_left(ctx: SnapiParser.Let_leftContext): SourceNode = throw new AssertionError(assertionMessage)
override def visitAttr(ctx: SnapiParser.AttrContext): SourceNode = throw new AssertionError(assertionMessage)
override def visitFun_ar(ctx: SnapiParser.Fun_arContext): SourceNode = throw new AssertionError(assertionMessage)
override def visitFun_args(ctx: SnapiParser.Fun_argsContext): SourceNode = throw new AssertionError(assertionMessage)
override def visitNullable_tryable(ctx: SnapiParser.Nullable_tryableContext): SourceNode =
throw new AssertionError(assertionMessage)
override def visitParam_list(ctx: SnapiParser.Param_listContext): SourceNode =
throw new AssertionError(assertionMessage)
override def visitRecord_attr_list(ctx: SnapiParser.Record_attr_listContext): SourceNode =
throw new AssertionError(assertionMessage)
}