| // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| package com.android.tools.r8.compatproguard; | |
| import static org.junit.Assert.assertNotEquals; | |
| import static org.junit.Assert.assertTrue; | |
| import com.android.tools.r8.code.ConstClass; | |
| import com.android.tools.r8.code.ConstString; | |
| import com.android.tools.r8.code.InvokeStatic; | |
| import com.android.tools.r8.code.ReturnVoid; | |
| import com.android.tools.r8.graph.DexCode; | |
| import com.android.tools.r8.smali.SmaliBuilder; | |
| import com.android.tools.r8.utils.codeinspector.ClassSubject; | |
| import com.android.tools.r8.utils.codeinspector.CodeInspector; | |
| import com.android.tools.r8.utils.codeinspector.MethodSubject; | |
| import com.google.common.collect.ImmutableList; | |
| import java.util.List; | |
| import org.junit.Test; | |
| public class AtomicFieldUpdaterTest extends CompatProguardSmaliTestBase { | |
| private final String CLASS_NAME = "Example"; | |
| private final static String BOO = "Boo"; | |
| @Test | |
| public void integerFieldUpdater_renamed() throws Exception { | |
| SmaliBuilder builder = new SmaliBuilder(CLASS_NAME); | |
| builder.addMainMethod( | |
| 2, | |
| "const-class v0, LBoo;", | |
| "const-string v1, \"foo\"", | |
| "invoke-static {v0, v1}, " | |
| + "Ljava/util/concurrent/atomic/AtomicIntegerFieldUpdater;" | |
| + "->newUpdater(Ljava/lang/Class;Ljava/lang/String;)" | |
| + "Ljava/util/concurrent/atomic/AtomicIntegerFieldUpdater;", | |
| "return-void"); | |
| builder.addClass(BOO); | |
| builder.addStaticField("foo", "I"); | |
| List<String> pgConfigs = ImmutableList.of( | |
| keepMainProguardConfiguration(CLASS_NAME), | |
| "-dontshrink", | |
| "-dontoptimize"); | |
| CodeInspector inspector = runCompatProguard(builder, pgConfigs); | |
| ClassSubject clazz = inspector.clazz(CLASS_NAME); | |
| assertTrue(clazz.isPresent()); | |
| MethodSubject method = clazz.method(CodeInspector.MAIN); | |
| assertTrue(method.isPresent()); | |
| DexCode code = method.getMethod().getCode().asDexCode(); | |
| assertTrue(code.instructions[0] instanceof ConstClass); | |
| assertTrue(code.instructions[1] instanceof ConstString); | |
| ConstString constString = (ConstString) code.instructions[1]; | |
| assertNotEquals("foo", constString.getString().toString()); | |
| assertTrue(code.instructions[2] instanceof InvokeStatic); | |
| assertTrue(code.instructions[3] instanceof ReturnVoid); | |
| } | |
| @Test | |
| public void longFieldUpdater_renamed() throws Exception { | |
| SmaliBuilder builder = new SmaliBuilder(CLASS_NAME); | |
| builder.addMainMethod( | |
| 2, | |
| "const-class v0, LBoo;", | |
| "const-string v1, \"foo\"", | |
| "invoke-static {v0, v1}, " | |
| + "Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;" | |
| + "->newUpdater(Ljava/lang/Class;Ljava/lang/String;)" | |
| + "Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;", | |
| "return-void"); | |
| builder.addClass(BOO); | |
| builder.addStaticField("foo", "J"); | |
| List<String> pgConfigs = ImmutableList.of( | |
| keepMainProguardConfiguration(CLASS_NAME), | |
| "-dontshrink", | |
| "-dontoptimize"); | |
| CodeInspector inspector = runCompatProguard(builder, pgConfigs); | |
| ClassSubject clazz = inspector.clazz(CLASS_NAME); | |
| assertTrue(clazz.isPresent()); | |
| MethodSubject method = clazz.method(CodeInspector.MAIN); | |
| assertTrue(method.isPresent()); | |
| DexCode code = method.getMethod().getCode().asDexCode(); | |
| assertTrue(code.instructions[0] instanceof ConstClass); | |
| assertTrue(code.instructions[1] instanceof ConstString); | |
| ConstString constString = (ConstString) code.instructions[1]; | |
| assertNotEquals("foo", constString.getString().toString()); | |
| assertTrue(code.instructions[2] instanceof InvokeStatic); | |
| assertTrue(code.instructions[3] instanceof ReturnVoid); | |
| } | |
| @Test | |
| public void referenceFieldUpdater_renamed() throws Exception { | |
| SmaliBuilder builder = new SmaliBuilder(CLASS_NAME); | |
| builder.addMainMethod( | |
| 3, | |
| "const-class v0, LBoo;", | |
| "const-class v1, Ljava/lang/Object;", | |
| "const-string v2, \"foo\"", | |
| "invoke-static {v0, v1, v2}, " | |
| + "Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;" | |
| + "->newUpdater(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;)" | |
| + "Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;", | |
| "return-void"); | |
| builder.addClass(BOO); | |
| builder.addStaticField("foo", "Ljava/lang/Object;"); | |
| List<String> pgConfigs = ImmutableList.of( | |
| keepMainProguardConfiguration(CLASS_NAME), | |
| "-dontshrink", | |
| "-dontoptimize"); | |
| CodeInspector inspector = runCompatProguard(builder, pgConfigs); | |
| ClassSubject clazz = inspector.clazz(CLASS_NAME); | |
| assertTrue(clazz.isPresent()); | |
| MethodSubject method = clazz.method(CodeInspector.MAIN); | |
| assertTrue(method.isPresent()); | |
| DexCode code = method.getMethod().getCode().asDexCode(); | |
| assertTrue(code.instructions[0] instanceof ConstClass); | |
| assertTrue(code.instructions[1] instanceof ConstClass); | |
| assertTrue(code.instructions[2] instanceof ConstString); | |
| ConstString constString = (ConstString) code.instructions[2]; | |
| assertNotEquals("foo", constString.getString().toString()); | |
| assertTrue(code.instructions[3] instanceof InvokeStatic); | |
| assertTrue(code.instructions[4] instanceof ReturnVoid); | |
| } | |
| } |