@@ -1065,6 +1065,8 @@ class String extends Literal {
10651065
10661066 override string getAPrimaryQlClass ( ) { result = "String" }
10671067
1068+ override PrimitiveType getType ( ) { result .getName ( ) = "string" }
1069+
10681070 /** Gets the string value of this literal. */
10691071 string getValue ( ) {
10701072 exists ( string raw | raw = lit .getChild ( ) .( Generated:: String ) .getValue ( ) |
@@ -1079,6 +1081,8 @@ class Integer extends Literal {
10791081
10801082 override string getAPrimaryQlClass ( ) { result = "Integer" }
10811083
1084+ override PrimitiveType getType ( ) { result .getName ( ) = "int" }
1085+
10821086 /** Gets the integer value of this literal. */
10831087 int getValue ( ) { result = lit .getChild ( ) .( Generated:: Integer ) .getValue ( ) .toInt ( ) }
10841088}
@@ -1089,6 +1093,8 @@ class Float extends Literal {
10891093
10901094 override string getAPrimaryQlClass ( ) { result = "Float" }
10911095
1096+ override PrimitiveType getType ( ) { result .getName ( ) = "float" }
1097+
10921098 /** Gets the float value of this literal. */
10931099 float getValue ( ) { result = lit .getChild ( ) .( Generated:: Float ) .getValue ( ) .toFloat ( ) }
10941100}
@@ -1105,6 +1111,8 @@ class Boolean extends Literal {
11051111 /** Holds if the value is `false` */
11061112 predicate isFalse ( ) { bool .getChild ( ) instanceof Generated:: False }
11071113
1114+ override PrimitiveType getType ( ) { result .getName ( ) = "boolean" }
1115+
11081116 override string getAPrimaryQlClass ( ) { result = "Boolean" }
11091117}
11101118
@@ -1384,11 +1392,17 @@ class HigherOrderFormula extends THigherOrderFormula, Formula {
13841392 }
13851393}
13861394
1395+ class Aggregate extends TAggregate , Expr {
1396+ string getKind ( ) { none ( ) }
1397+
1398+ Generated:: Aggregate getAggregate ( ) { none ( ) }
1399+ }
1400+
13871401/**
13881402 * An aggregate containing an expression.
13891403 * E.g. `min(getAPredicate().getArity())`.
13901404 */
1391- class ExprAggregate extends TExprAggregate , Expr {
1405+ class ExprAggregate extends TExprAggregate , Aggregate {
13921406 Generated:: Aggregate agg ;
13931407 Generated:: ExprAggregateBody body ;
13941408 string kind ;
@@ -1403,7 +1417,9 @@ class ExprAggregate extends TExprAggregate, Expr {
14031417 * Gets the kind of aggregate.
14041418 * E.g. for `min(foo())` the result is "min".
14051419 */
1406- string getKind ( ) { result = kind }
1420+ override string getKind ( ) { result = kind }
1421+
1422+ override Generated:: Aggregate getAggregate ( ) { result = agg }
14071423
14081424 /**
14091425 * Gets the ith "as" expression of this aggregate, if any.
@@ -1449,13 +1465,13 @@ class ExprAggregate extends TExprAggregate, Expr {
14491465}
14501466
14511467/** An aggregate expression, such as `count` or `sum`. */
1452- class Aggregate extends TAggregate , Expr {
1468+ class FullAggregate extends TFullAggregate , Aggregate {
14531469 Generated:: Aggregate agg ;
14541470 string kind ;
14551471 Generated:: FullAggregateBody body ;
14561472
1457- Aggregate ( ) {
1458- this = TAggregate ( agg ) and
1473+ FullAggregate ( ) {
1474+ this = TFullAggregate ( agg ) and
14591475 kind = agg .getChild ( 0 ) .( Generated:: AggId ) .getValue ( ) and
14601476 body = agg .getChild ( _)
14611477 }
@@ -1464,7 +1480,9 @@ class Aggregate extends TAggregate, Expr {
14641480 * Gets the kind of aggregate.
14651481 * E.g. for `min(int i | foo(i))` the result is "foo".
14661482 */
1467- string getKind ( ) { result = kind }
1483+ override string getKind ( ) { result = kind }
1484+
1485+ override Generated:: Aggregate getAggregate ( ) { result = agg }
14681486
14691487 /** Gets the ith declared argument of this quantifier. */
14701488 VarDecl getArgument ( int i ) { toGenerated ( result ) = body .getChild ( i ) }
@@ -1494,18 +1512,18 @@ class Aggregate extends TAggregate, Expr {
14941512 result = body .getOrderBys ( ) .getChild ( i ) .getChild ( 1 ) .( Generated:: Direction ) .getValue ( )
14951513 }
14961514
1497- override string getAPrimaryQlClass ( ) { result = "Aggregate [" + kind + "]" }
1515+ override string getAPrimaryQlClass ( ) { kind != "rank" and result = "FullAggregate [" + kind + "]" }
14981516
14991517 override Type getType ( ) {
15001518 exists ( PrimitiveType prim | prim = result |
1501- kind .regexpMatch ( "(strict)?count|sum|min|max|rank" ) and
1519+ kind .regexpMatch ( "(strict)?( count|sum|min|max|rank) " ) and
15021520 result .getName ( ) = "int"
15031521 or
15041522 kind .regexpMatch ( "(strict)?concat" ) and
15051523 result .getName ( ) = "string"
15061524 )
15071525 or
1508- kind = [ "any" , "min" , "max" ] and
1526+ kind = [ "any" , "min" , "max" , "unique" ] and
15091527 not exists ( getExpr ( _) ) and
15101528 result = getArgument ( 0 ) .getTypeExpr ( ) .getResolvedType ( )
15111529 or
@@ -1532,14 +1550,14 @@ class Aggregate extends TAggregate, Expr {
15321550 * A "rank" expression, such as `rank[4](int i | i = [5 .. 15] | i)`.
15331551 */
15341552class Rank extends Aggregate {
1535- Rank ( ) { kind = "rank" }
1553+ Rank ( ) { this . getKind ( ) = "rank" }
15361554
15371555 override string getAPrimaryQlClass ( ) { result = "Rank" }
15381556
15391557 /**
15401558 * The `i` in `rank[i]( | | )`.
15411559 */
1542- Expr getRankExpr ( ) { toGenerated ( result ) = agg .getChild ( 1 ) }
1560+ Expr getRankExpr ( ) { toGenerated ( result ) = this . getAggregate ( ) .getChild ( 1 ) }
15431561
15441562 override AstNode getAChild ( string pred ) {
15451563 result = super .getAChild ( pred )
@@ -1704,6 +1722,8 @@ class ExprAnnotation extends TExprAnnotation, Expr {
17041722 */
17051723 Expr getExpression ( ) { toGenerated ( result ) = expr_anno .getChild ( ) }
17061724
1725+ override Type getType ( ) { result = this .getExpression ( ) .getType ( ) }
1726+
17071727 override string getAPrimaryQlClass ( ) { result = "ExprAnnotation" }
17081728
17091729 override AstNode getAChild ( string pred ) {
@@ -1744,6 +1764,27 @@ class AddSubExpr extends TAddSubExpr, BinOpExpr {
17441764 /** Gets the operator of the binary expression. */
17451765 FunctionSymbol getOperator ( ) { result = operator }
17461766
1767+ override PrimitiveType getType ( ) {
1768+ // Both operands are the same type
1769+ result = this .getLeftOperand ( ) .getType ( ) and
1770+ result = this .getRightOperand ( ) .getType ( )
1771+ or
1772+ // Both operands are subtypes of `int`
1773+ result .getName ( ) = "int" and
1774+ result = this .getLeftOperand ( ) .getType ( ) .getASuperType * ( ) and
1775+ result = this .getRightOperand ( ) .getType ( ) .getASuperType * ( )
1776+ or
1777+ // Coercion to from `int` to `float`
1778+ exists ( PrimitiveType i | result .getName ( ) = "float" and i .getName ( ) = "int" |
1779+ this .getAnOperand ( ) .getType ( ) = result and
1780+ this .getAnOperand ( ) .getType ( ) .getASuperType * ( ) = i
1781+ )
1782+ or
1783+ // Coercion to `string`
1784+ result .getName ( ) = "string" and
1785+ this .getAnOperand ( ) .getType ( ) = result
1786+ }
1787+
17471788 override AstNode getAChild ( string pred ) {
17481789 result = super .getAChild ( pred )
17491790 or
@@ -1792,6 +1833,23 @@ class MulDivModExpr extends TMulDivModExpr, BinOpExpr {
17921833 /** Gets the operator of the binary expression. */
17931834 FunctionSymbol getOperator ( ) { result = operator }
17941835
1836+ override PrimitiveType getType ( ) {
1837+ // Both operands are of the same type
1838+ this .getLeftOperand ( ) .getType ( ) = result and
1839+ this .getRightOperand ( ) .getType ( ) = result
1840+ or
1841+ // Both operands are subtypes of `int`
1842+ result .getName ( ) = "int" and
1843+ result = this .getLeftOperand ( ) .getType ( ) .getASuperType * ( ) and
1844+ result = this .getRightOperand ( ) .getType ( ) .getASuperType * ( )
1845+ or
1846+ // Coercion from `int` to `float`
1847+ exists ( PrimitiveType i | result .getName ( ) = "float" and i .getName ( ) = "int" |
1848+ this .getAnOperand ( ) .getType ( ) = result and
1849+ this .getAnOperand ( ) .getType ( ) .getASuperType * ( ) = i
1850+ )
1851+ }
1852+
17951853 override AstNode getAChild ( string pred ) {
17961854 result = super .getAChild ( pred )
17971855 or
@@ -1846,6 +1904,8 @@ class Range extends TRange, Expr {
18461904 */
18471905 Expr getHighEndpoint ( ) { toGenerated ( result ) = range .getUpper ( ) }
18481906
1907+ override PrimitiveType getType ( ) { result .getName ( ) = "int" }
1908+
18491909 override string getAPrimaryQlClass ( ) { result = "Range" }
18501910
18511911 override AstNode getAChild ( string pred ) {
@@ -1870,6 +1930,8 @@ class Set extends TSet, Expr {
18701930 */
18711931 Expr getElement ( int i ) { toGenerated ( result ) = set .getChild ( i ) }
18721932
1933+ override Type getType ( ) { result = this .getElement ( 0 ) .getType ( ) }
1934+
18731935 override string getAPrimaryQlClass ( ) { result = "Set" }
18741936
18751937 override AstNode getAChild ( string pred ) {
@@ -1891,6 +1953,8 @@ class UnaryExpr extends TUnaryExpr, Expr {
18911953 /** Gets the operator of the unary expression as a string. */
18921954 FunctionSymbol getOperator ( ) { result = unaryexpr .getChild ( 0 ) .toString ( ) }
18931955
1956+ override Type getType ( ) { result = this .getOperand ( ) .getType ( ) }
1957+
18941958 override string getAPrimaryQlClass ( ) { result = "UnaryExpr" }
18951959
18961960 override AstNode getAChild ( string pred ) {
@@ -1906,6 +1970,8 @@ class DontCare extends TDontCare, Expr {
19061970
19071971 DontCare ( ) { this = TDontCare ( dontcare ) }
19081972
1973+ override DontCareType getType ( ) { any ( ) }
1974+
19091975 override string getAPrimaryQlClass ( ) { result = "DontCare" }
19101976}
19111977
0 commit comments