|  | // 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.ir; | 
|  |  | 
|  | import com.android.tools.r8.dex.ApplicationReader; | 
|  | import com.android.tools.r8.graph.AppInfo; | 
|  | import com.android.tools.r8.graph.DexApplication; | 
|  | import com.android.tools.r8.graph.DexEncodedMethod; | 
|  | import com.android.tools.r8.ir.code.BasicBlock; | 
|  | import com.android.tools.r8.ir.code.IRCode; | 
|  | import com.android.tools.r8.ir.code.InstructionListIterator; | 
|  | import com.android.tools.r8.ir.code.ValueNumberGenerator; | 
|  | import com.android.tools.r8.smali.SmaliBuilder; | 
|  | import com.android.tools.r8.smali.SmaliBuilder.MethodSignature; | 
|  | import com.android.tools.r8.smali.SmaliTestBase; | 
|  | import com.android.tools.r8.utils.AndroidApp; | 
|  | import com.android.tools.r8.utils.InternalOptions; | 
|  | import com.android.tools.r8.utils.Timing; | 
|  | import com.google.common.collect.ImmutableList; | 
|  | import java.util.List; | 
|  | import java.util.ListIterator; | 
|  | import org.junit.Rule; | 
|  | import org.junit.Test; | 
|  | import org.junit.rules.ExpectedException; | 
|  |  | 
|  | public class BasicBlockIteratorTest extends SmaliTestBase { | 
|  | @Rule | 
|  | public ExpectedException thrown = ExpectedException.none(); | 
|  |  | 
|  | /** | 
|  | * Simple test IR, which has three blocks: | 
|  | * | 
|  | * First block: Argument instructions | 
|  | * Second block: Add instruction | 
|  | * Third block: Return instruction | 
|  | * | 
|  | */ | 
|  | IRCode simpleCode() throws Exception { | 
|  | SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME); | 
|  |  | 
|  | String returnType = "int"; | 
|  | List<String> parameters = ImmutableList.of("int", "int"); | 
|  | MethodSignature signature = builder.addStaticMethod( | 
|  | returnType, | 
|  | DEFAULT_METHOD_NAME, | 
|  | parameters, | 
|  | 1, | 
|  | "    add-int             v0, p0, p1", | 
|  | "    return              p0" | 
|  | ); | 
|  |  | 
|  | AndroidApp application = buildApplication(builder); | 
|  | DexApplication dexApplication = | 
|  | new ApplicationReader( | 
|  | application, new InternalOptions(), new Timing("BasicBlockIteratorTest")) | 
|  | .read(); | 
|  | AppInfo appInfo = new AppInfo(dexApplication); | 
|  |  | 
|  | // Build the code, and split the code into three blocks. | 
|  | ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator(); | 
|  | DexEncodedMethod method = getMethod(application, signature); | 
|  | IRCode code = | 
|  | method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo); | 
|  | ListIterator<BasicBlock> blocks = code.listIterator(); | 
|  | InstructionListIterator iter = blocks.next().listIterator(); | 
|  | iter.nextUntil(i -> !i.isArgument()); | 
|  | iter.previous(); | 
|  | iter.split(code, 1, blocks); | 
|  | return code; | 
|  | } | 
|  |  | 
|  | @Test | 
|  | public void removeBeforeNext() throws Exception { | 
|  | IRCode code = simpleCode(); | 
|  |  | 
|  | ListIterator<BasicBlock> blocks = code.listIterator(); | 
|  | thrown.expect(IllegalStateException.class); | 
|  | blocks.remove(); | 
|  | } | 
|  |  | 
|  | @Test | 
|  | public void removeTwice() throws Exception { | 
|  | IRCode code = simpleCode(); | 
|  |  | 
|  | ListIterator<BasicBlock> blocks = code.listIterator(); | 
|  | blocks.next(); | 
|  | blocks.next(); | 
|  | blocks.remove(); | 
|  | thrown.expect(IllegalStateException.class); | 
|  | blocks.remove(); | 
|  | } | 
|  | } |