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 017package org.jetbrains.jet.lang.cfg.pseudocode; 018 019import com.google.common.collect.Sets; 020import org.jetbrains.annotations.NotNull; 021import org.jetbrains.annotations.Nullable; 022 023import java.util.Collection; 024import java.util.LinkedHashSet; 025 026public abstract class InstructionImpl implements Instruction { 027 private Pseudocode owner; 028 private final Collection<Instruction> previousInstructions = new LinkedHashSet<Instruction>(); 029 private final Collection<Instruction> copies = Sets.newHashSet(); 030 private Instruction original; 031 protected boolean isDead = false; 032 033 protected InstructionImpl() { 034 } 035 036 @Override 037 @NotNull 038 public Pseudocode getOwner() { 039 return owner; 040 } 041 042 @Override 043 public void setOwner(@NotNull Pseudocode owner) { 044 assert this.owner == null || this.owner == owner; 045 this.owner = owner; 046 } 047 048 @NotNull 049 @Override 050 public Collection<Instruction> getPreviousInstructions() { 051 return previousInstructions; 052 } 053 054 @Nullable 055 protected Instruction outgoingEdgeTo(@Nullable Instruction target) { 056 if (target != null) { 057 target.getPreviousInstructions().add(this); 058 } 059 return target; 060 } 061 062 public void die() { 063 isDead = true; 064 } 065 066 public boolean isDead() { 067 return isDead; 068 } 069 070 public final Instruction copy() { 071 return updateCopyInfo(createCopy()); 072 } 073 074 protected abstract Instruction createCopy(); 075 076 @NotNull 077 @Override 078 public Collection<Instruction> getCopies() { 079 if (original != null) { 080 Collection<Instruction> originalCopies = Sets.newHashSet(original.getCopies()); 081 originalCopies.remove(this); 082 originalCopies.add(original); 083 return originalCopies; 084 } 085 return copies; 086 } 087 088 private void addCopy(@NotNull Instruction instruction) { 089 copies.add(instruction); 090 } 091 092 private void setOriginal(@NotNull Instruction original) { 093 assert this.original == null : 094 "Instruction can't have two originals: this.original = " + this.original + "; new original = " + original; 095 this.original = original; 096 } 097 098 protected Instruction updateCopyInfo(@NotNull Instruction instruction) { 099 addCopy(instruction); 100 ((InstructionImpl)instruction).setOriginal(this); 101 return instruction; 102 } 103}