1bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon/* 2bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * Copyright 2016 Google Inc. All Rights Reserved. 3bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * 4bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * Licensed under the Apache License, Version 2.0 (the "License"); 5bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * you may not use this file except in compliance with the License. 6bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * You may obtain a copy of the License at 7bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * 8bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * http://www.apache.org/licenses/LICENSE-2.0 9bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * 10bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * Unless required by applicable law or agreed to in writing, software 11bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * distributed under the License is distributed on an "AS IS" BASIS, 12bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * See the License for the specific language governing permissions and 14bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon * limitations under the License. 15bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon */ 16bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 17bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonpackage com.google.turbine.binder; 18bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 19e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport static com.google.common.base.Preconditions.checkNotNull; 20bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 214d51bb2c21dffcb267e9b3a3538117adc6009e57cushonimport com.google.common.collect.ImmutableList; 224d51bb2c21dffcb267e9b3a3538117adc6009e57cushonimport com.google.common.collect.ImmutableMap; 235a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushonimport com.google.common.collect.Iterables; 2405878b6cb86f32245891d6e4504a8b1e7fcd2155cushonimport com.google.turbine.binder.bound.AnnotationValue; 2505878b6cb86f32245891d6e4504a8b1e7fcd2155cushonimport com.google.turbine.binder.bound.ClassValue; 2605878b6cb86f32245891d6e4504a8b1e7fcd2155cushonimport com.google.turbine.binder.bound.EnumConstantValue; 27bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.bound.SourceTypeBoundClass; 28bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.bound.TypeBoundClass; 29bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.bound.TypeBoundClass.FieldInfo; 304d51bb2c21dffcb267e9b3a3538117adc6009e57cushonimport com.google.turbine.binder.bound.TypeBoundClass.MethodInfo; 31bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.env.CompoundEnv; 32bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.env.Env; 3316d4fb60dd03fe84f50a96d42db6180a286fc3dbcushonimport com.google.turbine.binder.lookup.CompoundScope; 34bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.lookup.LookupKey; 35bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.lookup.LookupResult; 36bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.sym.ClassSymbol; 37bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.binder.sym.FieldSymbol; 38b0445ae9c37a1fab07fb5f234653e8ea072bf9fccushonimport com.google.turbine.diag.TurbineError; 39b25a536a58cfc542d70a118aebc30d3a9dea5654cushonimport com.google.turbine.diag.TurbineError.ErrorKind; 40bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.model.Const; 41aa81f608f1790015683a9368bc15924fc9c89767cushonimport com.google.turbine.model.Const.Value; 42e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport com.google.turbine.model.TurbineConstantTypeKind; 43bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.model.TurbineFlag; 44bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.tree.Tree; 453088f83b806b82d866d119e344da274105f42821cushonimport com.google.turbine.tree.Tree.ArrayInit; 46e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport com.google.turbine.tree.Tree.Binary; 47c38ee7ae0239899e7f9d0d5243d8bed77836891ccushonimport com.google.turbine.tree.Tree.ClassLiteral; 48e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport com.google.turbine.tree.Tree.ClassTy; 49e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport com.google.turbine.tree.Tree.Conditional; 50bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.tree.Tree.ConstVarName; 51e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport com.google.turbine.tree.Tree.Expression; 52c38ee7ae0239899e7f9d0d5243d8bed77836891ccushonimport com.google.turbine.tree.Tree.PrimTy; 53e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport com.google.turbine.tree.Tree.TypeCast; 54e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushonimport com.google.turbine.tree.Tree.Unary; 5505878b6cb86f32245891d6e4504a8b1e7fcd2155cushonimport com.google.turbine.type.AnnoInfo; 56bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushonimport com.google.turbine.type.Type; 5716d4fb60dd03fe84f50a96d42db6180a286fc3dbcushonimport java.util.ArrayDeque; 585a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushonimport java.util.Iterator; 594d51bb2c21dffcb267e9b3a3538117adc6009e57cushonimport java.util.LinkedHashMap; 604d51bb2c21dffcb267e9b3a3538117adc6009e57cushonimport java.util.Map; 61bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 625f9257de4904d710941a3f434de0e0c3618a4e75cushon/** 635f9257de4904d710941a3f434de0e0c3618a4e75cushon * Constant expression evaluation. 645f9257de4904d710941a3f434de0e0c3618a4e75cushon * 655f9257de4904d710941a3f434de0e0c3618a4e75cushon * <p>JLS §15.4 requires this class to be strictfp. 665f9257de4904d710941a3f434de0e0c3618a4e75cushon */ 675f9257de4904d710941a3f434de0e0c3618a4e75cushonpublic strictfp class ConstEvaluator { 68bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 693de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon /** The symbol of the originating class, for visibility checks. */ 703de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon private final ClassSymbol origin; 713de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon 723de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon /** The symbol of the enclosing class, for lexical field lookups. */ 73c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon private final ClassSymbol owner; 74bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 75bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon /** The bound node of the enclosing class. */ 76c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon private final SourceTypeBoundClass base; 77bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 78bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon /** The constant variable environment. */ 79bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon private final Env<FieldSymbol, Const.Value> values; 80bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 81bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon /** The class environment. */ 82bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon private final CompoundEnv<ClassSymbol, TypeBoundClass> env; 83bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 8416d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon private final CompoundScope scope; 8516d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon 86bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon public ConstEvaluator( 873de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon ClassSymbol origin, 88c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon ClassSymbol owner, 89c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon SourceTypeBoundClass base, 9016d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon CompoundScope scope, 91bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon Env<FieldSymbol, Const.Value> values, 92bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon CompoundEnv<ClassSymbol, TypeBoundClass> env) { 93bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 943de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon this.origin = origin; 95bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon this.owner = owner; 96c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon this.base = base; 97bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon this.values = values; 98bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon this.env = env; 9916d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon this.scope = scope; 100bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 101bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 102bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon /** Evaluates the given expression's value. */ 1033088f83b806b82d866d119e344da274105f42821cushon public Const eval(Tree t) { 104bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon switch (t.kind()) { 105bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case LITERAL: 106bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon { 107bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon Const.Value a = (Const.Value) ((Tree.Literal) t).value(); 108bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon if (a == null) { 109bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return null; 110bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 111bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon switch (a.constantTypeKind()) { 112bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case CHAR: 113bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return new Const.CharValue(((com.google.turbine.model.Const.CharValue) a).value()); 114bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case INT: 115bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return new Const.IntValue(((com.google.turbine.model.Const.IntValue) a).value()); 116bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case LONG: 117bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return new Const.LongValue(((com.google.turbine.model.Const.LongValue) a).value()); 118bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case FLOAT: 119bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return new Const.FloatValue(((com.google.turbine.model.Const.FloatValue) a).value()); 120bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case DOUBLE: 121bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return new Const.DoubleValue( 122bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon ((com.google.turbine.model.Const.DoubleValue) a).value()); 123bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case BOOLEAN: 124bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return new Const.BooleanValue( 125bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon ((com.google.turbine.model.Const.BooleanValue) a).value()); 126bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case STRING: 127bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return new Const.StringValue( 128bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon ((com.google.turbine.model.Const.StringValue) a).value()); 129bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case SHORT: 130bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case BYTE: 131bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case NULL: 132bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon default: 133bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon throw new AssertionError(a.constantTypeKind()); 134bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 135bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 136bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case VOID_TY: 137bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon throw new AssertionError(t.kind()); 138bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case CONST_VAR_NAME: 139bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return evalConstVar((ConstVarName) t); 140c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon case CLASS_LITERAL: 141c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon return evalClassLiteral((ClassLiteral) t); 142bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case BINARY: 143e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return evalBinary((Binary) t); 144bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case TYPE_CAST: 145e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return evalCast((TypeCast) t); 146bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case UNARY: 147e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return evalUnary((Unary) t); 148bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case CONDITIONAL: 149e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return evalConditional((Conditional) t); 150bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon case ARRAY_INIT: 1513088f83b806b82d866d119e344da274105f42821cushon return evalArrayInit((ArrayInit) t); 15283d53bb2e7f30a1c344f4aaa4320668f9dbc12f4cushon case ANNO_EXPR: 15383d53bb2e7f30a1c344f4aaa4320668f9dbc12f4cushon return evalAnno(((Tree.AnnoExpr) t).value()); 154bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon default: 155bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon throw new AssertionError(t.kind()); 156bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 157bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 158bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 159c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon /** Evaluates a class literal. */ 160c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon Const evalClassLiteral(ClassLiteral t) { 161c4b9629cb88f39fb5a648e2081f43afbb2685766cushon return new ClassValue(evalClassLiteralType(t.type())); 162c4b9629cb88f39fb5a648e2081f43afbb2685766cushon } 163c4b9629cb88f39fb5a648e2081f43afbb2685766cushon 164c4b9629cb88f39fb5a648e2081f43afbb2685766cushon private Type evalClassLiteralType(Tree.Type type) { 165c4b9629cb88f39fb5a648e2081f43afbb2685766cushon switch (type.kind()) { 166c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon case PRIM_TY: 167c4b9629cb88f39fb5a648e2081f43afbb2685766cushon return new Type.PrimTy(((PrimTy) type).tykind(), ImmutableList.of()); 168c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon case VOID_TY: 169c4b9629cb88f39fb5a648e2081f43afbb2685766cushon return Type.VOID; 170c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon case CLASS_TY: 171c4b9629cb88f39fb5a648e2081f43afbb2685766cushon return Type.ClassTy.asNonParametricClassTy(resolveClass((ClassTy) type)); 172c4b9629cb88f39fb5a648e2081f43afbb2685766cushon case ARR_TY: 173c4b9629cb88f39fb5a648e2081f43afbb2685766cushon return new Type.ArrayTy( 174c4b9629cb88f39fb5a648e2081f43afbb2685766cushon evalClassLiteralType(((Tree.ArrTy) type).elem()), ImmutableList.of()); 175c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon default: 176c4b9629cb88f39fb5a648e2081f43afbb2685766cushon throw new AssertionError(type.kind()); 177c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon } 178c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon } 179c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon 18016d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon /** 18116d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon * Resolves the {@link ClassSymbol} for the given {@link Tree.ClassTy}, with handling for 18216d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon * non-canonical qualified type names. 18316d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon * 18416d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon * <p>Similar to {@link HierarchyBinder#resolveClass}, except we can't unconditionally consider 18516d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon * members of the current class (e.g. when binding constants inside annotations on that class), 18616d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon * and when we do want to consider members we can rely on them being in the current scope (it 18716d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon * isn't completed during the hierarchy phase). 18816d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon */ 18916d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon private ClassSymbol resolveClass(ClassTy classTy) { 19016d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon ArrayDeque<String> flat = new ArrayDeque<>(); 19116d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon for (ClassTy curr = classTy; curr != null; curr = curr.base().orNull()) { 19216d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon flat.addFirst(curr.name()); 19316d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon } 19416d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon LookupResult result = scope.lookup(new LookupKey(flat)); 19516d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon if (result == null) { 196b25a536a58cfc542d70a118aebc30d3a9dea5654cushon throw error(classTy.position(), ErrorKind.SYMBOL_NOT_FOUND, flat.peekFirst()); 19716d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon } 19816d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon ClassSymbol classSym = (ClassSymbol) result.sym(); 19916d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon for (String bit : result.remaining()) { 2003de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon classSym = Resolve.resolve(env, origin, classSym, bit); 20116d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon if (classSym == null) { 202b25a536a58cfc542d70a118aebc30d3a9dea5654cushon throw error(classTy.position(), ErrorKind.SYMBOL_NOT_FOUND, bit); 20316d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon } 20416d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon } 20516d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon return classSym; 20616d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon } 20716d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon 208c38ee7ae0239899e7f9d0d5243d8bed77836891ccushon /** Evaluates a reference to another constant variable. */ 209bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon Const evalConstVar(ConstVarName t) { 2105a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon FieldInfo field = resolveField(t); 211a086f7ddb24d35d1c45a3524520d8bffbf1f213bcushon if (field == null) { 212a086f7ddb24d35d1c45a3524520d8bffbf1f213bcushon return null; 213a086f7ddb24d35d1c45a3524520d8bffbf1f213bcushon } 2145a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon if ((field.access() & TurbineFlag.ACC_ENUM) == TurbineFlag.ACC_ENUM) { 21505878b6cb86f32245891d6e4504a8b1e7fcd2155cushon return new EnumConstantValue(field.sym()); 216bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 21710cea422ebb6f3c02cc0e1a744bd3b1515e1891ecushon if (field.value() != null) { 21810cea422ebb6f3c02cc0e1a744bd3b1515e1891ecushon return field.value(); 21910cea422ebb6f3c02cc0e1a744bd3b1515e1891ecushon } 2205a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon return values.get(field.sym()); 2215a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon } 2225a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon 2235a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon FieldInfo resolveField(ConstVarName t) { 2245a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon String simpleName = t.name().get(0); 225c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon FieldInfo field = lexicalField(env, owner, simpleName); 2265a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon if (field != null) { 2275a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon return field; 228bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 229125eca769fc3038f6466b6f1139b56945bf86ca9cushon field = resolveQualifiedField(t); 230125eca769fc3038f6466b6f1139b56945bf86ca9cushon if (field != null) { 231125eca769fc3038f6466b6f1139b56945bf86ca9cushon return field; 232bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 233c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon ClassSymbol classSymbol = base.memberImports().singleMemberImport(simpleName); 23475946a85fe655bafc006b96e4ddf01990d5f2f7ccushon if (classSymbol != null) { 2353de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon field = Resolve.resolveField(env, origin, classSymbol, simpleName); 23675946a85fe655bafc006b96e4ddf01990d5f2f7ccushon if (field != null) { 23775946a85fe655bafc006b96e4ddf01990d5f2f7ccushon return field; 23875946a85fe655bafc006b96e4ddf01990d5f2f7ccushon } 239bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 240c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon Iterator<ClassSymbol> it = base.memberImports().onDemandImports(); 2415a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon while (it.hasNext()) { 2423de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon field = Resolve.resolveField(env, origin, it.next(), simpleName); 2432f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon if (field == null) { 2442f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon continue; 2455a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon } 2462f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon // resolve handles visibility of inherited members; on-demand imports of private members are 2472f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon // a special case 2482f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon if ((field.access() & TurbineFlag.ACC_PRIVATE) == TurbineFlag.ACC_PRIVATE) { 2492f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon continue; 2502f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon } 2512f66fb86c5de3e13b58b1a521ffc307c8cef1f50cushon return field; 252bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 2535a010f8e1f9613af8a23aaab28a64d6c83eb48fbcushon return null; 254bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 255bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 256125eca769fc3038f6466b6f1139b56945bf86ca9cushon private FieldInfo resolveQualifiedField(ConstVarName t) { 257125eca769fc3038f6466b6f1139b56945bf86ca9cushon if (t.name().size() <= 1) { 258125eca769fc3038f6466b6f1139b56945bf86ca9cushon return null; 259125eca769fc3038f6466b6f1139b56945bf86ca9cushon } 260125eca769fc3038f6466b6f1139b56945bf86ca9cushon LookupResult result = scope.lookup(new LookupKey(t.name())); 261125eca769fc3038f6466b6f1139b56945bf86ca9cushon if (result == null) { 262125eca769fc3038f6466b6f1139b56945bf86ca9cushon return null; 263125eca769fc3038f6466b6f1139b56945bf86ca9cushon } 264125eca769fc3038f6466b6f1139b56945bf86ca9cushon ClassSymbol sym = (ClassSymbol) result.sym(); 265125eca769fc3038f6466b6f1139b56945bf86ca9cushon for (int i = 0; i < result.remaining().size() - 1; i++) { 266125eca769fc3038f6466b6f1139b56945bf86ca9cushon sym = Resolve.resolve(env, sym, sym, result.remaining().get(i)); 267125eca769fc3038f6466b6f1139b56945bf86ca9cushon if (sym == null) { 268125eca769fc3038f6466b6f1139b56945bf86ca9cushon return null; 269125eca769fc3038f6466b6f1139b56945bf86ca9cushon } 270125eca769fc3038f6466b6f1139b56945bf86ca9cushon } 2713de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon return Resolve.resolveField(env, origin, sym, Iterables.getLast(result.remaining())); 272125eca769fc3038f6466b6f1139b56945bf86ca9cushon } 273125eca769fc3038f6466b6f1139b56945bf86ca9cushon 274bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon /** Search for constant variables in lexically enclosing scopes. */ 275c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon private FieldInfo lexicalField( 276bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon Env<ClassSymbol, TypeBoundClass> env, ClassSymbol sym, String name) { 277bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon while (sym != null) { 278bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon TypeBoundClass info = env.get(sym); 2793de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon FieldInfo field = Resolve.resolveField(env, origin, sym, name); 280bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon if (field != null) { 281bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return field; 282bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 283bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon sym = info.owner(); 284bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 285bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon return null; 286bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 287bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon 288bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon /** Casts the value to the given type. */ 289e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const cast(Type ty, Const value) { 290e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon checkNotNull(value); 291e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (ty.tyKind()) { 292e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case CLASS_TY: 293e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case TY_VAR: 294e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value; 295e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case PRIM_TY: 296e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return coerce((Const.Value) value, ((Type.PrimTy) ty).primkind()); 297e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 298e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(ty.tyKind()); 299e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 300e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 301e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 302e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private static Const.Value coerce(Const.Value value, TurbineConstantTypeKind kind) { 303e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (kind) { 304e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BOOLEAN: 305e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asBoolean(); 306e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case STRING: 307e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asString(); 308e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 309e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asLong(); 310e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 311e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asInteger(); 312e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BYTE: 313e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asByte(); 314e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case CHAR: 315e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asChar(); 316e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case SHORT: 317e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asShort(); 318e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 319e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asDouble(); 320e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 321e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return value.asFloat(); 322e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 323e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(kind); 324e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 325e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 326e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 327e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private Const.Value evalValue(Expression tree) { 328b622e5e85b83090ebec0aa9601c1348e91d20095cushon Const result = eval(tree); 329b622e5e85b83090ebec0aa9601c1348e91d20095cushon // TODO(cushon): consider distinguishing between constant field and annotation values, 330b622e5e85b83090ebec0aa9601c1348e91d20095cushon // and only allowing class literals / enum constants in the latter 331b622e5e85b83090ebec0aa9601c1348e91d20095cushon return (result instanceof Const.Value) ? (Const.Value) result : null; 332e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 333e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 334e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private Const.Value evalConditional(Conditional t) { 335806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon Const.Value condition = evalValue(t.cond()); 336806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon if (condition == null) { 337806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon return null; 338806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon } 339806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon return condition.asBoolean().value() ? evalValue(t.iftrue()) : evalValue(t.iffalse()); 340e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 341e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 342e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private Const.Value evalUnary(Unary t) { 343e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon Const.Value expr = evalValue(t.expr()); 344806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon if (expr == null) { 345806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon return null; 346806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon } 347e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (t.op()) { 348e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case NOT: 349aa81f608f1790015683a9368bc15924fc9c89767cushon return unaryNegate(expr); 350e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BITWISE_COMP: 351aa81f608f1790015683a9368bc15924fc9c89767cushon return bitwiseComp(expr); 352e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case UNARY_PLUS: 353aa81f608f1790015683a9368bc15924fc9c89767cushon return unaryPlus(expr); 354e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case NEG: 355aa81f608f1790015683a9368bc15924fc9c89767cushon return unaryMinus(expr); 356e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 357e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(t.op()); 358e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 359e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 360e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 361aa81f608f1790015683a9368bc15924fc9c89767cushon private Value unaryNegate(Value expr) { 362aa81f608f1790015683a9368bc15924fc9c89767cushon switch (expr.constantTypeKind()) { 363aa81f608f1790015683a9368bc15924fc9c89767cushon case BOOLEAN: 364aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.BooleanValue(!expr.asBoolean().value()); 365aa81f608f1790015683a9368bc15924fc9c89767cushon default: 366aa81f608f1790015683a9368bc15924fc9c89767cushon throw new AssertionError(expr.constantTypeKind()); 367aa81f608f1790015683a9368bc15924fc9c89767cushon } 368aa81f608f1790015683a9368bc15924fc9c89767cushon } 369aa81f608f1790015683a9368bc15924fc9c89767cushon 370aa81f608f1790015683a9368bc15924fc9c89767cushon private Value bitwiseComp(Value expr) { 371aa81f608f1790015683a9368bc15924fc9c89767cushon expr = promoteUnary(expr); 372aa81f608f1790015683a9368bc15924fc9c89767cushon switch (expr.constantTypeKind()) { 373aa81f608f1790015683a9368bc15924fc9c89767cushon case INT: 374aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.IntValue(~expr.asInteger().value()); 375aa81f608f1790015683a9368bc15924fc9c89767cushon case LONG: 376aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.LongValue(~expr.asLong().value()); 377aa81f608f1790015683a9368bc15924fc9c89767cushon default: 378aa81f608f1790015683a9368bc15924fc9c89767cushon throw new AssertionError(expr.constantTypeKind()); 379aa81f608f1790015683a9368bc15924fc9c89767cushon } 380aa81f608f1790015683a9368bc15924fc9c89767cushon } 381aa81f608f1790015683a9368bc15924fc9c89767cushon 382aa81f608f1790015683a9368bc15924fc9c89767cushon private Value unaryPlus(Value expr) { 383aa81f608f1790015683a9368bc15924fc9c89767cushon expr = promoteUnary(expr); 384aa81f608f1790015683a9368bc15924fc9c89767cushon switch (expr.constantTypeKind()) { 385aa81f608f1790015683a9368bc15924fc9c89767cushon case INT: 386aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.IntValue(+expr.asInteger().value()); 387aa81f608f1790015683a9368bc15924fc9c89767cushon case LONG: 388aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.LongValue(+expr.asLong().value()); 389aa81f608f1790015683a9368bc15924fc9c89767cushon case FLOAT: 390aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.FloatValue(+expr.asFloat().value()); 391aa81f608f1790015683a9368bc15924fc9c89767cushon case DOUBLE: 392aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.DoubleValue(+expr.asDouble().value()); 393aa81f608f1790015683a9368bc15924fc9c89767cushon default: 394aa81f608f1790015683a9368bc15924fc9c89767cushon throw new AssertionError(expr.constantTypeKind()); 395aa81f608f1790015683a9368bc15924fc9c89767cushon } 396aa81f608f1790015683a9368bc15924fc9c89767cushon } 397aa81f608f1790015683a9368bc15924fc9c89767cushon 398aa81f608f1790015683a9368bc15924fc9c89767cushon private Value unaryMinus(Value expr) { 399aa81f608f1790015683a9368bc15924fc9c89767cushon expr = promoteUnary(expr); 400aa81f608f1790015683a9368bc15924fc9c89767cushon switch (expr.constantTypeKind()) { 401aa81f608f1790015683a9368bc15924fc9c89767cushon case INT: 402aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.IntValue(-expr.asInteger().value()); 403aa81f608f1790015683a9368bc15924fc9c89767cushon case LONG: 404aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.LongValue(-expr.asLong().value()); 405aa81f608f1790015683a9368bc15924fc9c89767cushon case FLOAT: 406aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.FloatValue(-expr.asFloat().value()); 407aa81f608f1790015683a9368bc15924fc9c89767cushon case DOUBLE: 408aa81f608f1790015683a9368bc15924fc9c89767cushon return new Const.DoubleValue(-expr.asDouble().value()); 409aa81f608f1790015683a9368bc15924fc9c89767cushon default: 410aa81f608f1790015683a9368bc15924fc9c89767cushon throw new AssertionError(expr.constantTypeKind()); 411aa81f608f1790015683a9368bc15924fc9c89767cushon } 412aa81f608f1790015683a9368bc15924fc9c89767cushon } 4133de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon 414e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private Const.Value evalCast(TypeCast t) { 415e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon Const.Value expr = evalValue(t.expr()); 416806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon if (expr == null) { 417806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon return null; 418806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon } 419e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (t.ty().kind()) { 420e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case PRIM_TY: 421e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return coerce(expr, ((Tree.PrimTy) t.ty()).tykind()); 422e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case CLASS_TY: 423e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon { 424e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon ClassTy classTy = (ClassTy) t.ty(); 425e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon // TODO(cushon): check package? 426e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon if (!classTy.name().equals("String")) { 427e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(classTy); 428e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 429e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return expr.asString(); 430e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 431e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 432e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(t.ty().kind()); 433e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 434e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 435e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 436e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value add(Const.Value a, Const.Value b) { 437e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon if (a.constantTypeKind() == TurbineConstantTypeKind.STRING 438e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon || b.constantTypeKind() == TurbineConstantTypeKind.STRING) { 439e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.StringValue(a.asString().value() + b.asString().value()); 440e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 441e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 442e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 443e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 444e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 445e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 446e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() + b.asInteger().value()); 447e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 448e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() + b.asLong().value()); 449e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 450e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.FloatValue(a.asFloat().value() + b.asFloat().value()); 451e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 452e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.DoubleValue(a.asDouble().value() + b.asDouble().value()); 453e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 454e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 455e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 456e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 457e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 458e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value subtract(Const.Value a, Const.Value b) { 459e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 460e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 461e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 462e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 463e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 464e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() - b.asInteger().value()); 465e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 466e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() - b.asLong().value()); 467e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 468e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.FloatValue(a.asFloat().value() - b.asFloat().value()); 469e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 470e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.DoubleValue(a.asDouble().value() - b.asDouble().value()); 471e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 472e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 473e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 474e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 475e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 476e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value mult(Const.Value a, Const.Value b) { 477e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 478e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 479e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 480e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 481e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 482e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() * b.asInteger().value()); 483e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 484e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() * b.asLong().value()); 485e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 486e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.FloatValue(a.asFloat().value() * b.asFloat().value()); 487e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 488e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.DoubleValue(a.asDouble().value() * b.asDouble().value()); 489e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 490e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 491e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 492e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 493e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 494e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value divide(Const.Value a, Const.Value b) { 495e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 496e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 497e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 498e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 499e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 500e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() / b.asInteger().value()); 501e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 502e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() / b.asLong().value()); 503e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 504e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.FloatValue(a.asFloat().value() / b.asFloat().value()); 505e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 506e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.DoubleValue(a.asDouble().value() / b.asDouble().value()); 507e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 508e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 509e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 510e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 511e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 512e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value mod(Const.Value a, Const.Value b) { 513e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 514e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 515e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 516e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 517e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 518e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() % b.asInteger().value()); 519e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 520e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() % b.asLong().value()); 521e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 522e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.FloatValue(a.asFloat().value() % b.asFloat().value()); 523e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 524e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.DoubleValue(a.asDouble().value() % b.asDouble().value()); 525e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 526e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 527e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 528e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 529e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 530e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static final int INT_SHIFT_MASK = 0b11111; 531e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 532e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static final int LONG_SHIFT_MASK = 0b111111; 533e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 534e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value shiftLeft(Const.Value a, Const.Value b) { 535e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = promoteUnary(a); 536e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = promoteUnary(b); 537e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 538e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 539e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue( 540e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a.asInteger().value() << (b.asInteger().value() & INT_SHIFT_MASK)); 541e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 542e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() << (b.asInteger().value() & LONG_SHIFT_MASK)); 543e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 544e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(a.constantTypeKind()); 545e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 546e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 547e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 548e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value shiftRight(Const.Value a, Const.Value b) { 549e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = promoteUnary(a); 550e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = promoteUnary(b); 551e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 552e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 553e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue( 554e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a.asInteger().value() >> (b.asInteger().value() & INT_SHIFT_MASK)); 555e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 556e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() >> (b.asInteger().value() & LONG_SHIFT_MASK)); 557e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 558e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(a.constantTypeKind()); 559e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 560e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 561e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 562e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value unsignedShiftRight(Const.Value a, Const.Value b) { 563e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = promoteUnary(a); 564e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = promoteUnary(b); 565e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 566e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 567e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue( 568e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a.asInteger().value() >>> (b.asInteger().value() & INT_SHIFT_MASK)); 569e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 570e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue( 571e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a.asLong().value() >>> (b.asInteger().value() & LONG_SHIFT_MASK)); 572e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 573e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(a.constantTypeKind()); 574e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 575e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 576e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 577e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value lessThan(Const.Value a, Const.Value b) { 578e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 579e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 580e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 581e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 582e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 583e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asInteger().value() < b.asInteger().value()); 584e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 585e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asLong().value() < b.asLong().value()); 586e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 587e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asFloat().value() < b.asFloat().value()); 588e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 589e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asDouble().value() < b.asDouble().value()); 590e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 591e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 592e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 593e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 594e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 595e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value lessThanEqual(Const.Value a, Const.Value b) { 596e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 597e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 598e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 599e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 600e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 601e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asInteger().value() <= b.asInteger().value()); 602e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 603e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asLong().value() <= b.asLong().value()); 604e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 605e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asFloat().value() <= b.asFloat().value()); 606e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 607e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asDouble().value() <= b.asDouble().value()); 608e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 609e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 610e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 611e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 612e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 613e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value greaterThan(Const.Value a, Const.Value b) { 614e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 615e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 616e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 617e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 618e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 619e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asInteger().value() > b.asInteger().value()); 620e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 621e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asLong().value() > b.asLong().value()); 622e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 623e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asFloat().value() > b.asFloat().value()); 624e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 625e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asDouble().value() > b.asDouble().value()); 626e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 627e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 628e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 629e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 630e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 631e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value greaterThanEqual(Const.Value a, Const.Value b) { 632e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 633e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 634e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 635e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 636e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 637e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asInteger().value() >= b.asInteger().value()); 638e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 639e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asLong().value() >= b.asLong().value()); 640e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 641e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asFloat().value() >= b.asFloat().value()); 642e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 643e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asDouble().value() >= b.asDouble().value()); 644e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 645e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 646e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 647e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 648e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 649e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value equal(Const.Value a, Const.Value b) { 650e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 651e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case STRING: 652e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asString().value().equals(b.asString().value())); 653e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BOOLEAN: 654e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asBoolean().value() == b.asBoolean().value()); 655e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 656e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon break; 657e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 658e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 659e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 660e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 661e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 662e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 663e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asInteger().value() == b.asInteger().value()); 664e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 665e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asLong().value() == b.asLong().value()); 666e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 667e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asFloat().value() == b.asFloat().value()); 668e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 669e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asDouble().value() == b.asDouble().value()); 670e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 671e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 672e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 673e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 674e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 675e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value notEqual(Const.Value a, Const.Value b) { 676e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 677e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case STRING: 678e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(!a.asString().value().equals(b.asString().value())); 679e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BOOLEAN: 680e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asBoolean().value() != b.asBoolean().value()); 681e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 682e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon break; 683e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 684e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 685e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 686e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 687e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 688e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 689e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asInteger().value() != b.asInteger().value()); 690e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 691e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asLong().value() != b.asLong().value()); 692e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 693e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asFloat().value() != b.asFloat().value()); 694e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 695e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asDouble().value() != b.asDouble().value()); 696e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 697e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 698e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 699e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 700e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 701e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value bitwiseAnd(Const.Value a, Const.Value b) { 702e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 703e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BOOLEAN: 704e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asBoolean().value() & b.asBoolean().value()); 705e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 706e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon break; 707e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 708e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 709e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 710e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 711e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 712e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 713e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() & b.asInteger().value()); 714e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 715e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() & b.asLong().value()); 716e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 717e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 718e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 719e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 720e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 721e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value bitwiseOr(Const.Value a, Const.Value b) { 722e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 723e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BOOLEAN: 724e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asBoolean().value() | b.asBoolean().value()); 725e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 726e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon break; 727e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 728e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 729e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 730e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 731e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 732e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 733e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() | b.asInteger().value()); 734e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 735e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() | b.asLong().value()); 736e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 737e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 738e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 739e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 740e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 741e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon static Const.Value bitwiseXor(Const.Value a, Const.Value b) { 742e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 743e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BOOLEAN: 744e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(a.asBoolean().value() ^ b.asBoolean().value()); 745e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 746e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon break; 747e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 748e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon TurbineConstantTypeKind type = promoteBinary(a, b); 749e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = coerce(a, type); 750e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = coerce(b, type); 751e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (type) { 752e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 753e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.IntValue(a.asInteger().value() ^ b.asInteger().value()); 754e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 755e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.LongValue(a.asLong().value() ^ b.asLong().value()); 756e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 757e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(type); 758e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 759e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 760e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 761e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private Const.Value evalBinary(Binary t) { 762e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon Const.Value lhs = evalValue(t.lhs()); 763e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon Const.Value rhs = evalValue(t.rhs()); 764806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon if (lhs == null || rhs == null) { 765806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon return null; 766806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon } 767e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (t.op()) { 768e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case PLUS: 769e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return add(lhs, rhs); 770e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case MINUS: 771e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return subtract(lhs, rhs); 772e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case MULT: 773e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return mult(lhs, rhs); 774e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DIVIDE: 775e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return divide(lhs, rhs); 776e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case MODULO: 777e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return mod(lhs, rhs); 778e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case SHIFT_LEFT: 779e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return shiftLeft(lhs, rhs); 780e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case SHIFT_RIGHT: 781e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return shiftRight(lhs, rhs); 782e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case UNSIGNED_SHIFT_RIGHT: 783e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return unsignedShiftRight(lhs, rhs); 784e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LESS_THAN: 785e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return lessThan(lhs, rhs); 786e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case GREATER_THAN: 787e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return greaterThan(lhs, rhs); 788e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LESS_THAN_EQ: 789e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return lessThanEqual(lhs, rhs); 790e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case GREATER_THAN_EQ: 791e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return greaterThanEqual(lhs, rhs); 792e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case EQUAL: 793e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return equal(lhs, rhs); 794e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case NOT_EQUAL: 795e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return notEqual(lhs, rhs); 796e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case AND: 797e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(lhs.asBoolean().value() && rhs.asBoolean().value()); 798e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case OR: 799e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return new Const.BooleanValue(lhs.asBoolean().value() || rhs.asBoolean().value()); 800e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BITWISE_AND: 801e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return bitwiseAnd(lhs, rhs); 802e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BITWISE_XOR: 803e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return bitwiseXor(lhs, rhs); 804e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BITWISE_OR: 805e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return bitwiseOr(lhs, rhs); 806e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 807e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(t.op()); 808e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 809e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 810e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 811e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private static Const.Value promoteUnary(Const.Value v) { 812e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (v.constantTypeKind()) { 813e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case CHAR: 814e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case SHORT: 815e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case BYTE: 816e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return v.asInteger(); 817e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 818e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 819e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 820e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 821e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return v; 822e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 823e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(v.constantTypeKind()); 824e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 825e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 826e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon 827e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon private static TurbineConstantTypeKind promoteBinary(Const.Value a, Const.Value b) { 828e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon a = promoteUnary(a); 829e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon b = promoteUnary(b); 830e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (a.constantTypeKind()) { 831e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 832e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (b.constantTypeKind()) { 833e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 834e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 835e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 836e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 837e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return b.constantTypeKind(); 838e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 839e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(b.constantTypeKind()); 840e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 841e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 842e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (b.constantTypeKind()) { 843e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 844e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return TurbineConstantTypeKind.LONG; 845e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 846e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 847e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 848e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return b.constantTypeKind(); 849e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 850e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(b.constantTypeKind()); 851e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 852e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 853e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (b.constantTypeKind()) { 854e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 855e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 856e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 857e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return TurbineConstantTypeKind.FLOAT; 858e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 859e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return TurbineConstantTypeKind.DOUBLE; 860e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 861e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(b.constantTypeKind()); 862e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 863e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 864e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon switch (b.constantTypeKind()) { 865e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case INT: 866e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case LONG: 867e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case FLOAT: 868e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon case DOUBLE: 869e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon return TurbineConstantTypeKind.DOUBLE; 870e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 871e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(b.constantTypeKind()); 872e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 873e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon default: 874e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon throw new AssertionError(a.constantTypeKind()); 875e00c9907c7a2be5cac0133c972a3037c9a02d6a5cushon } 876bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon } 8774d51bb2c21dffcb267e9b3a3538117adc6009e57cushon 878cdefacdcf613684b385797d2d4340f3fa7dcce2dcushon ImmutableList<AnnoInfo> evaluateAnnotations(ImmutableList<AnnoInfo> annotations) { 879cdefacdcf613684b385797d2d4340f3fa7dcce2dcushon ImmutableList.Builder<AnnoInfo> result = ImmutableList.builder(); 880cdefacdcf613684b385797d2d4340f3fa7dcce2dcushon for (AnnoInfo annotation : annotations) { 88133e253bd3b1ce0d4939345229e78523063527eebcushon result.add(evaluateAnnotation(annotation)); 882cdefacdcf613684b385797d2d4340f3fa7dcce2dcushon } 883cdefacdcf613684b385797d2d4340f3fa7dcce2dcushon return result.build(); 884cdefacdcf613684b385797d2d4340f3fa7dcce2dcushon } 885cdefacdcf613684b385797d2d4340f3fa7dcce2dcushon 8864d51bb2c21dffcb267e9b3a3538117adc6009e57cushon /** 8874d51bb2c21dffcb267e9b3a3538117adc6009e57cushon * Evaluates annotation arguments given the symbol of the annotation declaration and a list of 8884d51bb2c21dffcb267e9b3a3538117adc6009e57cushon * expression trees. 8894d51bb2c21dffcb267e9b3a3538117adc6009e57cushon */ 89033e253bd3b1ce0d4939345229e78523063527eebcushon AnnoInfo evaluateAnnotation(AnnoInfo info) { 8914d51bb2c21dffcb267e9b3a3538117adc6009e57cushon Map<String, Type> template = new LinkedHashMap<>(); 89233e253bd3b1ce0d4939345229e78523063527eebcushon for (MethodInfo method : env.get(info.sym()).methods()) { 8934d51bb2c21dffcb267e9b3a3538117adc6009e57cushon template.put(method.name(), method.returnType()); 8944d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 8954d51bb2c21dffcb267e9b3a3538117adc6009e57cushon 8964d51bb2c21dffcb267e9b3a3538117adc6009e57cushon ImmutableMap.Builder<String, Const> values = ImmutableMap.builder(); 89733e253bd3b1ce0d4939345229e78523063527eebcushon for (Expression arg : info.args()) { 8984d51bb2c21dffcb267e9b3a3538117adc6009e57cushon Expression expr; 8994d51bb2c21dffcb267e9b3a3538117adc6009e57cushon String key; 9004d51bb2c21dffcb267e9b3a3538117adc6009e57cushon if (arg.kind() == Tree.Kind.ASSIGN) { 9014d51bb2c21dffcb267e9b3a3538117adc6009e57cushon Tree.Assign assign = (Tree.Assign) arg; 9024d51bb2c21dffcb267e9b3a3538117adc6009e57cushon key = assign.name(); 9034d51bb2c21dffcb267e9b3a3538117adc6009e57cushon expr = assign.expr(); 9044d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } else { 9054d51bb2c21dffcb267e9b3a3538117adc6009e57cushon // expand the implicit 'value' name; `@Foo(42)` is sugar for `@Foo(value=42)` 9064d51bb2c21dffcb267e9b3a3538117adc6009e57cushon key = "value"; 9074d51bb2c21dffcb267e9b3a3538117adc6009e57cushon expr = arg; 9084d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 9094d51bb2c21dffcb267e9b3a3538117adc6009e57cushon Type ty = template.get(key); 910b0445ae9c37a1fab07fb5f234653e8ea072bf9fccushon if (ty == null) { 911b25a536a58cfc542d70a118aebc30d3a9dea5654cushon throw error(arg.position(), ErrorKind.CANNOT_RESOLVE, key); 912b0445ae9c37a1fab07fb5f234653e8ea072bf9fccushon } 9134d51bb2c21dffcb267e9b3a3538117adc6009e57cushon Const value = evalAnnotationValue(expr, ty); 9143de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon if (value == null) { 9153de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon throw error(expr.position(), ErrorKind.EXPRESSION_ERROR); 9163de8ed9a49a939e11961146bf5b6a41c20dc7f79cushon } 9174d51bb2c21dffcb267e9b3a3538117adc6009e57cushon values.put(key, value); 9184d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 91933e253bd3b1ce0d4939345229e78523063527eebcushon return info.withValues(values.build()); 9204d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 9214d51bb2c21dffcb267e9b3a3538117adc6009e57cushon 92205878b6cb86f32245891d6e4504a8b1e7fcd2155cushon private AnnotationValue evalAnno(Tree.Anno t) { 92316d4fb60dd03fe84f50a96d42db6180a286fc3dbcushon LookupResult result = scope.lookup(new LookupKey(t.name())); 9243088f83b806b82d866d119e344da274105f42821cushon ClassSymbol sym = (ClassSymbol) result.sym(); 9253088f83b806b82d866d119e344da274105f42821cushon for (String name : result.remaining()) { 926c4fcb03ad72af457d0448f4207085c2a60b4ae52cushon sym = Resolve.resolve(env, sym, sym, name); 9273088f83b806b82d866d119e344da274105f42821cushon } 92833e253bd3b1ce0d4939345229e78523063527eebcushon AnnoInfo annoInfo = evaluateAnnotation(new AnnoInfo(base.source(), sym, t, null)); 92905878b6cb86f32245891d6e4504a8b1e7fcd2155cushon return new AnnotationValue(annoInfo.sym(), annoInfo.values()); 9303088f83b806b82d866d119e344da274105f42821cushon } 9313088f83b806b82d866d119e344da274105f42821cushon 9323088f83b806b82d866d119e344da274105f42821cushon private Const.ArrayInitValue evalArrayInit(ArrayInit t) { 9333088f83b806b82d866d119e344da274105f42821cushon ImmutableList.Builder<Const> elements = ImmutableList.builder(); 9343088f83b806b82d866d119e344da274105f42821cushon for (Expression e : t.exprs()) { 935806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon Const arg = eval(e); 936806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon if (arg == null) { 937806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon return null; 938806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon } 939806d6a5f4a319f2c00baf2334732024c5bdcacb5cushon elements.add(arg); 9404d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 9413088f83b806b82d866d119e344da274105f42821cushon return new Const.ArrayInitValue(elements.build()); 9424d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 9434d51bb2c21dffcb267e9b3a3538117adc6009e57cushon 9443088f83b806b82d866d119e344da274105f42821cushon Const evalAnnotationValue(Tree tree, Type ty) { 945b0445ae9c37a1fab07fb5f234653e8ea072bf9fccushon if (ty == null) { 946b25a536a58cfc542d70a118aebc30d3a9dea5654cushon throw error(tree.position(), ErrorKind.EXPRESSION_ERROR); 947b0445ae9c37a1fab07fb5f234653e8ea072bf9fccushon } 9484d51bb2c21dffcb267e9b3a3538117adc6009e57cushon Const value = eval(tree); 949a5453051f0c8b71a833f6dc73caaea43bd24a0dbcushon if (value == null) { 950a5453051f0c8b71a833f6dc73caaea43bd24a0dbcushon throw error(tree.position(), ErrorKind.EXPRESSION_ERROR); 951a5453051f0c8b71a833f6dc73caaea43bd24a0dbcushon } 9524d51bb2c21dffcb267e9b3a3538117adc6009e57cushon switch (ty.tyKind()) { 9534d51bb2c21dffcb267e9b3a3538117adc6009e57cushon case PRIM_TY: 9544d51bb2c21dffcb267e9b3a3538117adc6009e57cushon return coerce((Const.Value) value, ((Type.PrimTy) ty).primkind()); 9554d51bb2c21dffcb267e9b3a3538117adc6009e57cushon case CLASS_TY: 9564d51bb2c21dffcb267e9b3a3538117adc6009e57cushon case TY_VAR: 9574d51bb2c21dffcb267e9b3a3538117adc6009e57cushon return value; 9584d51bb2c21dffcb267e9b3a3538117adc6009e57cushon case ARRAY_TY: 9594d51bb2c21dffcb267e9b3a3538117adc6009e57cushon { 960d161fb6fcbd2e8ab64abf467823920398ad34b63cushon Type elementType = ((Type.ArrayTy) ty).elementType(); 961d161fb6fcbd2e8ab64abf467823920398ad34b63cushon ImmutableList<Const> elements = 962d161fb6fcbd2e8ab64abf467823920398ad34b63cushon value.kind() == Const.Kind.ARRAY 963d161fb6fcbd2e8ab64abf467823920398ad34b63cushon ? ((Const.ArrayInitValue) value).elements() 964d161fb6fcbd2e8ab64abf467823920398ad34b63cushon : ImmutableList.of(value); 965d161fb6fcbd2e8ab64abf467823920398ad34b63cushon ImmutableList.Builder<Const> coerced = ImmutableList.builder(); 966d161fb6fcbd2e8ab64abf467823920398ad34b63cushon for (Const element : elements) { 967d161fb6fcbd2e8ab64abf467823920398ad34b63cushon coerced.add(cast(elementType, element)); 9684d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 969d161fb6fcbd2e8ab64abf467823920398ad34b63cushon return new Const.ArrayInitValue(coerced.build()); 9704d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 9714d51bb2c21dffcb267e9b3a3538117adc6009e57cushon default: 9724d51bb2c21dffcb267e9b3a3538117adc6009e57cushon throw new AssertionError(ty.tyKind()); 9734d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 9744d51bb2c21dffcb267e9b3a3538117adc6009e57cushon } 975b0445ae9c37a1fab07fb5f234653e8ea072bf9fccushon 976b25a536a58cfc542d70a118aebc30d3a9dea5654cushon private TurbineError error(int position, ErrorKind kind, Object... args) { 977b25a536a58cfc542d70a118aebc30d3a9dea5654cushon return TurbineError.format(base.source(), position, kind, args); 978b0445ae9c37a1fab07fb5f234653e8ea072bf9fccushon } 9799f3e44c5390f7c1845078865d0ef07357e949080cushon 9809f3e44c5390f7c1845078865d0ef07357e949080cushon public Const.Value evalFieldInitializer(Expression expression, Type type) { 9819f3e44c5390f7c1845078865d0ef07357e949080cushon Const value = eval(expression); 9829f3e44c5390f7c1845078865d0ef07357e949080cushon if (value == null || value.kind() != Const.Kind.PRIMITIVE) { 9839f3e44c5390f7c1845078865d0ef07357e949080cushon return null; 9849f3e44c5390f7c1845078865d0ef07357e949080cushon } 9859f3e44c5390f7c1845078865d0ef07357e949080cushon return (Const.Value) cast(type, value); 9869f3e44c5390f7c1845078865d0ef07357e949080cushon } 987bd2b29bb7fd05aed8481ef8342c09c4e88492c88cushon} 988