001 /*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.jet.lang.cfg.pseudocode;
018
019 import com.google.common.collect.Lists;
020 import com.google.common.collect.Maps;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.jet.lang.cfg.Label;
023
024 import java.util.*;
025
026 public class NondeterministicJumpInstruction extends InstructionImpl{
027 private Instruction next;
028 private final List<Label> targetLabels;
029 private final Map<Label, Instruction> resolvedTargets;
030
031 public NondeterministicJumpInstruction(List<Label> targetLabels) {
032 this.targetLabels = Lists.newArrayList(targetLabels);
033 resolvedTargets = Maps.newLinkedHashMap();
034 }
035
036 public NondeterministicJumpInstruction(Label targetLabel) {
037 this(Lists.newArrayList(targetLabel));
038 }
039
040 public List<Label> getTargetLabels() {
041 return targetLabels;
042 }
043
044 public Map<Label, Instruction> getResolvedTargets() {
045 return resolvedTargets;
046 }
047
048 public void setResolvedTarget(Label label, Instruction resolvedTarget) {
049 Instruction target = outgoingEdgeTo(resolvedTarget);
050 resolvedTargets.put(label, target);
051 }
052
053 public Instruction getNext() {
054 return next;
055 }
056 public void setNext(Instruction next) {
057 this.next = outgoingEdgeTo(next);
058 }
059
060 @Override
061 public void accept(@NotNull InstructionVisitor visitor) {
062 visitor.visitNondeterministicJump(this);
063 }
064
065 @Override
066 public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
067 return visitor.visitNondeterministicJump(this);
068 }
069
070 @NotNull
071 @Override
072 public Collection<Instruction> getNextInstructions() {
073 List<Instruction> targetInstructions = Lists.newArrayList(getResolvedTargets().values());
074 targetInstructions.add(getNext());
075 return targetInstructions;
076 }
077
078 @Override
079 public String toString() {
080 StringBuilder sb = new StringBuilder();
081 sb.append("jmp?(");
082 for (Iterator<Label> iterator = targetLabels.iterator(); iterator.hasNext(); ) {
083 Label targetLabel = iterator.next();
084 sb.append(targetLabel.getName());
085 if (iterator.hasNext()) {
086 sb.append(", ");
087 }
088 }
089 sb.append(")");
090 return sb.toString();
091 }
092
093 @NotNull
094 @Override
095 protected Instruction createCopy() {
096 return createCopy(getTargetLabels());
097 }
098
099 @NotNull
100 public final Instruction copy(@NotNull List<Label> newTargetLabels) {
101 return updateCopyInfo(createCopy(newTargetLabels));
102 }
103
104 private Instruction createCopy(@NotNull List<Label> newTargetLabels) {
105 return new NondeterministicJumpInstruction(newTargetLabels);
106 }
107 }