4
4
5
5
import java
6
6
private import semmle.code.java.frameworks.android.Compose
7
+ private import semmle.code.java.Constants
7
8
8
9
/** A common super-class that represents all kinds of expressions. */
9
10
class Expr extends ExprParent , @expr {
@@ -208,71 +209,7 @@ class CompileTimeConstantExpr extends Expr {
208
209
// Literal value.
209
210
result = this .( BooleanLiteral ) .getBooleanValue ( )
210
211
or
211
- // No casts relevant to booleans.
212
- // `!` is the only unary operator that evaluates to a boolean.
213
- result = this .( LogNotExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) .booleanNot ( )
214
- or
215
- // Handle binary expressions that have integer operands and a boolean result.
216
- exists ( BinaryExpr b , int left , int right |
217
- b = this and
218
- left = b .getLeftOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) and
219
- right = b .getRightOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
220
- |
221
- (
222
- b instanceof LTExpr and
223
- if left < right then result = true else result = false
224
- )
225
- or
226
- (
227
- b instanceof LEExpr and
228
- if left <= right then result = true else result = false
229
- )
230
- or
231
- (
232
- b instanceof GTExpr and
233
- if left > right then result = true else result = false
234
- )
235
- or
236
- (
237
- b instanceof GEExpr and
238
- if left >= right then result = true else result = false
239
- )
240
- or
241
- (
242
- b instanceof ValueOrReferenceEqualsExpr and
243
- if left = right then result = true else result = false
244
- )
245
- or
246
- (
247
- b instanceof ValueOrReferenceNotEqualsExpr and
248
- if left != right then result = true else result = false
249
- )
250
- )
251
- or
252
- // Handle binary expressions that have boolean operands and a boolean result.
253
- exists ( BinaryExpr b , boolean left , boolean right |
254
- b = this and
255
- left = b .getLeftOperand ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) and
256
- right = b .getRightOperand ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( )
257
- |
258
- (
259
- b instanceof ValueOrReferenceEqualsExpr and
260
- if left = right then result = true else result = false
261
- )
262
- or
263
- (
264
- b instanceof ValueOrReferenceNotEqualsExpr and
265
- if left != right then result = true else result = false
266
- )
267
- or
268
- ( b instanceof AndBitwiseExpr or b instanceof AndLogicalExpr ) and
269
- result = left .booleanAnd ( right )
270
- or
271
- ( b instanceof OrBitwiseExpr or b instanceof OrLogicalExpr ) and
272
- result = left .booleanOr ( right )
273
- or
274
- b instanceof XorBitwiseExpr and result = left .booleanXor ( right )
275
- )
212
+ result = CalcCompileTimeConstants:: calculateBooleanValue ( this )
276
213
or
277
214
// Handle binary expressions that have `String` operands and a boolean result.
278
215
exists ( BinaryExpr b , string left , string right |
@@ -300,18 +237,6 @@ class CompileTimeConstantExpr extends Expr {
300
237
)
301
238
or
302
239
// Note: no `getFloatValue()`, so we cannot support binary expressions with float or double operands.
303
- // Ternary expressions, where the `true` and `false` expressions are boolean compile-time constants.
304
- exists ( ConditionalExpr ce , boolean condition |
305
- ce = this and
306
- condition = ce .getCondition ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) and
307
- result = ce .getBranchExpr ( condition ) .( CompileTimeConstantExpr ) .getBooleanValue ( )
308
- )
309
- or
310
- // Simple or qualified names where the variable is final and the initializer is a constant.
311
- exists ( Variable v | this = v .getAnAccess ( ) |
312
- result = v .getInitializer ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( )
313
- )
314
- or
315
240
result = this .( LiveLiteral ) .getValue ( ) .getBooleanValue ( )
316
241
}
317
242
@@ -329,75 +254,20 @@ class CompileTimeConstantExpr extends Expr {
329
254
result = this .( IntegerLiteral ) .getIntValue ( )
330
255
or
331
256
result = this .( CharacterLiteral ) .getCodePointValue ( )
332
- or
333
- exists ( CastingExpr cast , int val |
334
- cast = this and val = cast .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
335
- |
336
- if cast .getType ( ) .hasName ( "byte" )
337
- then result = ( val + 128 ) .bitAnd ( 255 ) - 128
338
- else
339
- if cast .getType ( ) .hasName ( "short" )
340
- then result = ( val + 32768 ) .bitAnd ( 65535 ) - 32768
341
- else
342
- if cast .getType ( ) .hasName ( "char" )
343
- then result = val .bitAnd ( 65535 )
344
- else result = val
345
- )
346
- or
347
- result = this .( PlusExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
348
- or
349
- result = - this .( MinusExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
350
- or
351
- result = this .( BitNotExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) .bitNot ( )
352
- or
353
- // No `int` value for `LogNotExpr`.
354
- exists ( BinaryExpr b , int v1 , int v2 |
355
- b = this and
356
- v1 = b .getLeftOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) and
357
- v2 = b .getRightOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
358
- |
359
- b instanceof MulExpr and result = v1 * v2
360
- or
361
- b instanceof DivExpr and result = v1 / v2
362
- or
363
- b instanceof RemExpr and result = v1 % v2
364
- or
365
- b instanceof AddExpr and result = v1 + v2
366
- or
367
- b instanceof SubExpr and result = v1 - v2
368
- or
369
- b instanceof LeftShiftExpr and result = v1 .bitShiftLeft ( v2 )
370
- or
371
- b instanceof RightShiftExpr and result = v1 .bitShiftRightSigned ( v2 )
372
- or
373
- b instanceof UnsignedRightShiftExpr and result = v1 .bitShiftRight ( v2 )
374
- or
375
- b instanceof AndBitwiseExpr and result = v1 .bitAnd ( v2 )
376
- or
377
- b instanceof OrBitwiseExpr and result = v1 .bitOr ( v2 )
378
- or
379
- b instanceof XorBitwiseExpr and result = v1 .bitXor ( v2 )
380
- // No `int` value for `AndLogicalExpr` or `OrLogicalExpr`.
381
- // No `int` value for `LTExpr`, `GTExpr`, `LEExpr`, `GEExpr`, `ValueOrReferenceEqualsExpr` or `ValueOrReferenceNotEqualsExpr`.
382
- )
383
- or
384
- // Ternary conditional, with compile-time constant condition.
385
- exists ( ConditionalExpr ce , boolean condition |
386
- ce = this and
387
- condition = ce .getCondition ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) and
388
- result = ce .getBranchExpr ( condition ) .( CompileTimeConstantExpr ) .getIntValue ( )
389
- )
390
- or
391
- // If a `Variable` is a `CompileTimeConstantExpr`, its value is its initializer.
392
- exists ( Variable v | this = v .getAnAccess ( ) |
393
- result = v .getInitializer ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
394
- )
395
257
)
396
258
or
259
+ result = CalcCompileTimeConstants:: calculateIntValue ( this )
260
+ or
397
261
result = this .( LiveLiteral ) .getValue ( ) .getIntValue ( )
398
262
}
399
263
}
400
264
265
+ private boolean getBoolValue ( Expr e ) { result = e .( CompileTimeConstantExpr ) .getBooleanValue ( ) }
266
+
267
+ private int getIntValue ( Expr e ) { result = e .( CompileTimeConstantExpr ) .getIntValue ( ) }
268
+
269
+ private module CalcCompileTimeConstants = CalculateConstants< getBoolValue / 1 , getIntValue / 1 > ;
270
+
401
271
/** An expression parent is an element that may have an expression as its child. */
402
272
class ExprParent extends @exprparent, Top { }
403
273
0 commit comments