Pseudocode: Translate instruction classes to Kotlin

This commit is contained in:
Alexey Sedunov
2014-06-03 14:26:10 +04:00
parent 145358654b
commit eabe2fcc8a
63 changed files with 1385 additions and 1741 deletions

View File

@@ -1,4 +1,13 @@
<root>
<item name='com.google.common.collect.Lists java.util.ArrayList&lt;E&gt; newArrayList(E...)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.google.common.collect.Lists java.util.ArrayList&lt;E&gt; newArrayList(java.lang.Iterable&lt;? extends E&gt;)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.google.common.collect.Maps java.util.LinkedHashMap&lt;K,V&gt; newLinkedHashMap()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.google.common.collect.Multimap java.util.Set&lt;K&gt; keySet()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
@@ -9,4 +18,7 @@
name='com.google.common.collect.Sets com.google.common.collect.Sets.SetView&lt;E&gt; intersection(java.util.Set&lt;E&gt;, java.util.Set&lt;?&gt;)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.google.common.collect.Sets java.util.HashSet&lt;E&gt; newHashSet(java.lang.Iterable&lt;? extends E&gt;)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -16,6 +16,9 @@
package org.jetbrains.jet.lang.cfg;
import org.jetbrains.annotations.NotNull;
public interface Label {
@NotNull
String getName();
}

View File

@@ -27,7 +27,7 @@ fun Pseudocode.traverse(
val instructions = getInstructions(traversalOrder)
for (instruction in instructions) {
if (instruction is LocalFunctionDeclarationInstruction) {
instruction.getBody().traverse(traversalOrder, analyzeInstruction)
instruction.body.traverse(traversalOrder, analyzeInstruction)
}
analyzeInstruction(instruction)
}
@@ -41,7 +41,7 @@ fun <D> Pseudocode.traverse(
val instructions = getInstructions(traversalOrder)
for (instruction in instructions) {
if (instruction is LocalFunctionDeclarationInstruction) {
instruction.getBody().traverse(traversalOrder, edgesMap, analyzeInstruction)
instruction.body.traverse(traversalOrder, edgesMap, analyzeInstruction)
}
val edges = edgesMap.get(instruction)
if (edges != null) {
@@ -81,7 +81,7 @@ private fun <D> Pseudocode.initializeEdgesMap(
for (instruction in instructions) {
edgesMap.put(instruction, initialEdge)
if (instruction is LocalFunctionDeclarationInstruction) {
instruction.getBody().initializeEdgesMap(edgesMap, initialDataValue)
instruction.body.initializeEdgesMap(edgesMap, initialDataValue)
}
}
}
@@ -126,7 +126,7 @@ private fun <D> Pseudocode.collectDataFromSubgraph(
}
if (instruction is LocalFunctionDeclarationInstruction) {
val subroutinePseudocode = instruction.getBody()
val subroutinePseudocode = instruction.body
val previous = if (mergeDataWithLocalDeclarations) previousInstructions else Collections.emptyList()
subroutinePseudocode.collectDataFromSubgraph(
traversalOrder, mergeDataWithLocalDeclarations,
@@ -208,10 +208,10 @@ fun Pseudocode.getInstructions(traversalOrder: TraversalOrder): MutableList<Inst
if (traversalOrder == FORWARD) getInstructions() else getReversedInstructions()
fun Instruction.getNextInstructions(traversalOrder: TraversalOrder): Collection<Instruction> =
if (traversalOrder == FORWARD) getNextInstructions() else getPreviousInstructions()
if (traversalOrder == FORWARD) nextInstructions else previousInstructions
fun Instruction.getPreviousInstructions(traversalOrder: TraversalOrder): Collection<Instruction> =
if (traversalOrder == FORWARD) getPreviousInstructions() else getNextInstructions()
if (traversalOrder == FORWARD) previousInstructions else nextInstructions
fun Instruction.isStartInstruction(traversalOrder: TraversalOrder): Boolean =
if (traversalOrder == FORWARD) this is SubroutineEnterInstruction else this is SubroutineSinkInstruction

View File

@@ -60,8 +60,8 @@ public class PseudocodeVariableDataCollector(
data: Map<VariableDescriptor, D>
): Map<VariableDescriptor, D> {
// If an edge goes from deeper lexical scope to a less deep one, this means that it points outside of the deeper scope.
val toDepth = to.getLexicalScope().depth
if (toDepth >= from.getLexicalScope().depth) return data
val toDepth = to.lexicalScope.depth
if (toDepth >= from.lexicalScope.depth) return data
// Variables declared in an inner (deeper) scope can't be accessed from an outer scope.
// Thus they can be filtered out upon leaving the inner scope.
@@ -77,14 +77,14 @@ public class PseudocodeVariableDataCollector(
val lexicalScopeVariableInfo = LexicalScopeVariableInfoImpl()
pseudocode.traverse(TraversalOrder.FORWARD, { instruction ->
if (instruction is VariableDeclarationInstruction) {
val variableDeclarationElement = instruction.getVariableDeclarationElement()
val variableDeclarationElement = instruction.variableDeclarationElement
val descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement)
if (descriptor != null) {
assert(descriptor is VariableDescriptor,
"Variable descriptor should correspond to the instruction for ${instruction.getElement().getText()}.\n" +
"Variable descriptor should correspond to the instruction for ${instruction.element.getText()}.\n" +
"Descriptor : $descriptor")
lexicalScopeVariableInfo.registerVariableDeclaredInScope(
descriptor as VariableDescriptor, instruction.getLexicalScope())
descriptor as VariableDescriptor, instruction.lexicalScope)
}
}
})

View File

@@ -36,37 +36,37 @@ public class TailRecursionDetector extends InstructionVisitorWithResult<Boolean>
}
@Override
public Boolean visitInstruction(Instruction instruction) {
public Boolean visitInstruction(@NotNull Instruction instruction) {
return false;
}
@Override
public Boolean visitSubroutineExit(SubroutineExitInstruction instruction) {
return !instruction.isError() && instruction.getSubroutine() == subroutine;
public Boolean visitSubroutineExit(@NotNull SubroutineExitInstruction instruction) {
return !instruction.getIsError() && instruction.getSubroutine() == subroutine;
}
@Override
public Boolean visitSubroutineSink(SubroutineSinkInstruction instruction) {
public Boolean visitSubroutineSink(@NotNull SubroutineSinkInstruction instruction) {
return instruction.getSubroutine() == subroutine;
}
@Override
public Boolean visitJump(AbstractJumpInstruction instruction) {
public Boolean visitJump(@NotNull AbstractJumpInstruction instruction) {
return true;
}
@Override
public Boolean visitThrowExceptionInstruction(ThrowExceptionInstruction instruction) {
public Boolean visitThrowExceptionInstruction(@NotNull ThrowExceptionInstruction instruction) {
return false;
}
@Override
public Boolean visitMarkInstruction(MarkInstruction instruction) {
public Boolean visitMarkInstruction(@NotNull MarkInstruction instruction) {
return true;
}
@Override
public Boolean visitMagic(MagicInstruction instruction) {
public Boolean visitMagic(@NotNull MagicInstruction instruction) {
return instruction.getSynthetic();
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.Collection;
import java.util.Collections;
public abstract class AbstractJumpInstruction extends JetElementInstructionImpl implements JumpInstruction {
private final Label targetLabel;
private Instruction resolvedTarget;
public AbstractJumpInstruction(@NotNull JetElement element, Label targetLabel, LexicalScope lexicalScope) {
super(element, lexicalScope);
this.targetLabel = targetLabel;
}
public Label getTargetLabel() {
return targetLabel;
}
public Instruction getResolvedTarget() {
return resolvedTarget;
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
return Collections.singleton(getResolvedTarget());
}
public void setResolvedTarget(Instruction resolvedTarget) {
this.resolvedTarget = outgoingEdgeTo(resolvedTarget);
}
protected abstract AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope);
final public Instruction copy(@NotNull Label newLabel) {
return updateCopyInfo(createCopy(newLabel, lexicalScope));
}
@NotNull
@Override
protected Instruction createCopy() {
return createCopy(targetLabel, lexicalScope);
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.cfg.Label
import org.jetbrains.jet.lang.psi.JetElement
import java.util.Collections
public abstract class AbstractJumpInstruction(
element: JetElement,
public val targetLabel: Label,
lexicalScope: LexicalScope
) : JetElementInstructionImpl(element, lexicalScope), JumpInstruction {
public var resolvedTarget: Instruction? = null
set(value: Instruction?) {
$resolvedTarget = outgoingEdgeTo(value)
}
protected abstract fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction
public fun copy(newLabel: Label): Instruction {
return updateCopyInfo(createCopy(newLabel, lexicalScope))
}
override fun createCopy(): InstructionImpl {
return createCopy(targetLabel, lexicalScope)
}
override val nextInstructions: Collection<Instruction> get() = Collections.singleton(resolvedTarget)
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
public class CompilationErrorInstruction(
element: JetElement,
lexicalScope: LexicalScope,
val message: String
) : InstructionWithNext(element, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitCompilationErrorInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitCompilationErrorInstruction(this)
}
override fun createCopy() = CompilationErrorInstruction(element, lexicalScope, message)
override fun toString() = "error(${render(element)}, $message)"
}

View File

@@ -1,98 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ConditionalJumpInstruction extends AbstractJumpInstruction {
private final boolean onTrue;
private Instruction nextOnTrue;
private Instruction nextOnFalse;
private final PseudoValue conditionValue;
public ConditionalJumpInstruction(
@NotNull JetElement element,
boolean onTrue,
LexicalScope lexicalScope,
Label targetLabel,
PseudoValue conditionValue) {
super(element, targetLabel, lexicalScope);
this.onTrue = onTrue;
this.conditionValue = conditionValue;
}
@NotNull
@Override
public List<PseudoValue> getInputValues() {
return ContainerUtil.createMaybeSingletonList(conditionValue);
}
public boolean onTrue() {
return onTrue;
}
public Instruction getNextOnTrue() {
return nextOnTrue;
}
public void setNextOnTrue(Instruction nextOnTrue) {
this.nextOnTrue = outgoingEdgeTo(nextOnTrue);
}
public Instruction getNextOnFalse() {
return nextOnFalse;
}
public void setNextOnFalse(Instruction nextOnFalse) {
this.nextOnFalse = outgoingEdgeTo(nextOnFalse);
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
return Arrays.asList(getNextOnFalse(), getNextOnTrue());
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitConditionalJump(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitConditionalJump(this);
}
@Override
public String toString() {
String instr = onTrue ? "jt" : "jf";
String inValue = conditionValue != null ? "|" + conditionValue : "";
return instr + "(" + getTargetLabel().getName() + inValue + ")";
}
@Override
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
return new ConditionalJumpInstruction(element, onTrue, lexicalScope, newLabel, conditionValue);
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.jet.lang.cfg.Label
import org.jetbrains.jet.lang.psi.JetElement
import java.util.Arrays
public class ConditionalJumpInstruction(
element: JetElement,
public val onTrue: Boolean,
lexicalScope: LexicalScope,
targetLabel: Label,
public val conditionValue: PseudoValue?) : AbstractJumpInstruction(element, targetLabel, lexicalScope) {
private var _nextOnTrue: Instruction? = null
private var _nextOnFalse: Instruction? = null
public var nextOnTrue: Instruction
get() = _nextOnTrue!!
set(value: Instruction) {
_nextOnTrue = outgoingEdgeTo(value)
}
public var nextOnFalse: Instruction
get() = _nextOnFalse!!
set(value: Instruction) {
_nextOnFalse = outgoingEdgeTo(value)
}
override val nextInstructions: Collection<Instruction>
get() = Arrays.asList(nextOnFalse, nextOnTrue)
override val inputValues: List<PseudoValue>
get() = ContainerUtil.createMaybeSingletonList(conditionValue)
override fun accept(visitor: InstructionVisitor) {
visitor.visitConditionalJump(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitConditionalJump(this)
}
override fun toString(): String {
val instr = if (onTrue) "jt" else "jf"
val inValue = conditionValue?.let { "|" + it } ?: ""
return "$instr(${targetLabel.getName()}$inValue)"
}
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction =
ConditionalJumpInstruction(element, onTrue, lexicalScope, newLabel, conditionValue)
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import kotlin.jvm.KotlinSignature;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import java.util.Collection;
import java.util.List;
public interface Instruction {
@NotNull
Pseudocode getOwner();
void setOwner(@NotNull Pseudocode owner);
@NotNull
Collection<Instruction> getPreviousInstructions();
@NotNull
Collection<Instruction> getNextInstructions();
void accept(@NotNull InstructionVisitor visitor);
<R> R accept(@NotNull InstructionVisitorWithResult<R> visitor);
@NotNull
Collection<Instruction> getCopies();
@NotNull
LexicalScope getLexicalScope();
@ReadOnly
@NotNull
List<PseudoValue> getInputValues();
@Nullable
PseudoValue getOutputValue();
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import kotlin.jvm.KotlinSignature
import org.jetbrains.annotations.Nullable
import org.jetbrains.annotations.ReadOnly
public trait Instruction {
public var owner: Pseudocode
public val previousInstructions: MutableCollection<Instruction>
public val nextInstructions: Collection<Instruction>
public val lexicalScope: LexicalScope
public val inputValues: List<PseudoValue>
public val outputValue: PseudoValue?
public fun getCopies(): Collection<Instruction>
public fun accept(visitor: InstructionVisitor)
public fun <R> accept(visitor: InstructionVisitorWithResult<R>): R
}

View File

@@ -1,128 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import com.google.common.collect.Sets;
import kotlin.jvm.KotlinSignature;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
public abstract class InstructionImpl implements Instruction {
private Pseudocode owner;
private final Collection<Instruction> previousInstructions = new LinkedHashSet<Instruction>();
private final Collection<Instruction> copies = Sets.newHashSet();
@NotNull
protected final LexicalScope lexicalScope;
private Instruction original;
protected boolean isDead = false;
protected InstructionImpl(@NotNull LexicalScope lexicalScope) {
this.lexicalScope = lexicalScope;
}
@Override
@NotNull
public Pseudocode getOwner() {
return owner;
}
@Override
public void setOwner(@NotNull Pseudocode owner) {
assert this.owner == null || this.owner == owner;
this.owner = owner;
}
@NotNull
@Override
public Collection<Instruction> getPreviousInstructions() {
return previousInstructions;
}
@Nullable
protected Instruction outgoingEdgeTo(@Nullable Instruction target) {
if (target != null) {
target.getPreviousInstructions().add(this);
}
return target;
}
public void die() {
isDead = true;
}
public boolean isDead() {
return isDead;
}
public final Instruction copy() {
return updateCopyInfo(createCopy());
}
@NotNull
protected abstract Instruction createCopy();
@NotNull
@Override
public Collection<Instruction> getCopies() {
if (original != null) {
Collection<Instruction> originalCopies = Sets.newHashSet(original.getCopies());
originalCopies.remove(this);
originalCopies.add(original);
return originalCopies;
}
return copies;
}
private void addCopy(@NotNull Instruction instruction) {
copies.add(instruction);
}
private void setOriginal(@NotNull Instruction original) {
assert this.original == null :
"Instruction can't have two originals: this.original = " + this.original + "; new original = " + original;
this.original = original;
}
@NotNull
@Override
public LexicalScope getLexicalScope() {
return lexicalScope;
}
protected Instruction updateCopyInfo(@NotNull Instruction instruction) {
addCopy(instruction);
((InstructionImpl)instruction).setOriginal(this);
return instruction;
}
@NotNull
@Override
public List<PseudoValue> getInputValues() {
return Collections.emptyList();
}
@Nullable
@Override
public PseudoValue getOutputValue() {
return null;
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import java.util.Collections
import java.util.LinkedHashSet
import java.util.HashSet
import com.google.common.collect.Sets
public abstract class InstructionImpl(public override val lexicalScope: LexicalScope): Instruction {
private var _owner: Pseudocode? = null
private val _copies = HashSet<Instruction>()
private var original: Instruction? = null
protected var _dead: Boolean = false
private fun setOriginalInstruction(value: Instruction?) {
assert(original == null) { "Instruction can't have two originals: this.original = ${original}; new original = $this" }
original = value
}
protected fun outgoingEdgeTo(target: Instruction?): Instruction? {
if (target != null) {
target.previousInstructions.add(this)
}
return target
}
protected fun updateCopyInfo(instruction: InstructionImpl): Instruction {
_copies.add(instruction)
instruction.setOriginalInstruction(this)
return instruction
}
protected abstract fun createCopy(): InstructionImpl
public fun die() {
_dead = true
}
public val dead: Boolean get() = _dead
public fun copy(): Instruction {
return updateCopyInfo(createCopy())
}
override var owner: Pseudocode
get() = _owner!!
set(value: Pseudocode) {
assert(_owner == null || _owner == value)
_owner = value
}
override val previousInstructions: MutableCollection<Instruction> = LinkedHashSet()
override val inputValues: List<PseudoValue> = Collections.emptyList()
override val outputValue: PseudoValue? = null
override fun getCopies(): Collection<Instruction> {
return original?.let { original ->
val originalCopies = Sets.newHashSet(original.getCopies())
originalCopies.remove(this)
originalCopies.add(original)
originalCopies
} ?: _copies
}
}

View File

@@ -1,114 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
public class InstructionVisitor {
public void visitInstructionWithReceiver(InstructionWithReceiver instruction) {
visitInstructionWithNext(instruction);
}
public void visitReadValue(ReadValueInstruction instruction) {
visitInstructionWithReceiver(instruction);
}
public void visitLocalFunctionDeclarationInstruction(LocalFunctionDeclarationInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitVariableDeclarationInstruction(VariableDeclarationInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
visitJump(instruction);
}
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
visitJump(instruction);
}
public void visitReturnValue(ReturnValueInstruction instruction) {
visitJump(instruction);
}
public void visitReturnNoValue(ReturnNoValueInstruction instruction) {
visitJump(instruction);
}
public void visitThrowExceptionInstruction(ThrowExceptionInstruction instruction) {
visitJump(instruction);
}
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
visitInstruction(instruction);
}
public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
visitInstruction(instruction);
}
public void visitSubroutineSink(SubroutineSinkInstruction instruction) {
visitInstruction(instruction);
}
public void visitJump(AbstractJumpInstruction instruction) {
visitInstruction(instruction);
}
public void visitInstructionWithNext(InstructionWithNext instruction) {
visitInstruction(instruction);
}
public void visitInstruction(Instruction instruction) {
}
public void visitSubroutineEnter(SubroutineEnterInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitWriteValue(WriteValueInstruction instruction) {
visitInstructionWithReceiver(instruction);
}
public void visitLoadUnitValue(LoadUnitValueInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitOperation(OperationInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitCallInstruction(CallInstruction instruction) {
visitOperation(instruction);
}
public void visitCompilationErrorInstruction(CompilationErrorInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitMarkInstruction(MarkInstruction instruction) {
visitInstructionWithNext(instruction);
}
public void visitMagic(MagicInstruction instruction) {
visitOperation(instruction);
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
public open class InstructionVisitor() {
public open fun visitInstructionWithReceiver(instruction: InstructionWithReceiver) {
visitInstructionWithNext(instruction)
}
public open fun visitReadValue(instruction: ReadValueInstruction) {
visitInstructionWithReceiver(instruction)
}
public open fun visitLocalFunctionDeclarationInstruction(instruction: LocalFunctionDeclarationInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitVariableDeclarationInstruction(instruction: VariableDeclarationInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitUnconditionalJump(instruction: UnconditionalJumpInstruction) {
visitJump(instruction)
}
public open fun visitConditionalJump(instruction: ConditionalJumpInstruction) {
visitJump(instruction)
}
public open fun visitReturnValue(instruction: ReturnValueInstruction) {
visitJump(instruction)
}
public open fun visitReturnNoValue(instruction: ReturnNoValueInstruction) {
visitJump(instruction)
}
public open fun visitThrowExceptionInstruction(instruction: ThrowExceptionInstruction) {
visitJump(instruction)
}
public open fun visitNondeterministicJump(instruction: NondeterministicJumpInstruction) {
visitInstruction(instruction)
}
public open fun visitUnsupportedElementInstruction(instruction: UnsupportedElementInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitSubroutineExit(instruction: SubroutineExitInstruction) {
visitInstruction(instruction)
}
public open fun visitSubroutineSink(instruction: SubroutineSinkInstruction) {
visitInstruction(instruction)
}
public open fun visitJump(instruction: AbstractJumpInstruction) {
visitInstruction(instruction)
}
public open fun visitInstructionWithNext(instruction: InstructionWithNext) {
visitInstruction(instruction)
}
public open fun visitInstruction(instruction: Instruction) {
}
public open fun visitSubroutineEnter(instruction: SubroutineEnterInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitWriteValue(instruction: WriteValueInstruction) {
visitInstructionWithReceiver(instruction)
}
public open fun visitLoadUnitValue(instruction: LoadUnitValueInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitOperation(instruction: OperationInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitCallInstruction(instruction: CallInstruction) {
visitOperation(instruction)
}
public open fun visitCompilationErrorInstruction(instruction: CompilationErrorInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitMarkInstruction(instruction: MarkInstruction) {
visitInstructionWithNext(instruction)
}
public open fun visitMagic(instruction: MagicInstruction) {
visitOperation(instruction)
}
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
public abstract class InstructionVisitorWithResult<R> {
public abstract R visitInstruction(Instruction instruction);
public R visitInstructionWithReceiver(InstructionWithReceiver instruction) {
return visitInstructionWithNext(instruction);
}
public R visitReadValue(ReadValueInstruction instruction) {
return visitInstructionWithReceiver(instruction);
}
public R visitLocalFunctionDeclarationInstruction(LocalFunctionDeclarationInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitVariableDeclarationInstruction(VariableDeclarationInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
return visitJump(instruction);
}
public R visitConditionalJump(ConditionalJumpInstruction instruction) {
return visitJump(instruction);
}
public R visitReturnValue(ReturnValueInstruction instruction) {
return visitJump(instruction);
}
public R visitReturnNoValue(ReturnNoValueInstruction instruction) {
return visitJump(instruction);
}
public R visitThrowExceptionInstruction(ThrowExceptionInstruction instruction) {
return visitJump(instruction);
}
public R visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
return visitInstruction(instruction);
}
public R visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitSubroutineExit(SubroutineExitInstruction instruction) {
return visitInstruction(instruction);
}
public R visitSubroutineSink(SubroutineSinkInstruction instruction) {
return visitInstruction(instruction);
}
public R visitJump(AbstractJumpInstruction instruction) {
return visitInstruction(instruction);
}
public R visitInstructionWithNext(InstructionWithNext instruction) {
return visitInstruction(instruction);
}
public R visitSubroutineEnter(SubroutineEnterInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitWriteValue(WriteValueInstruction instruction) {
return visitInstructionWithReceiver(instruction);
}
public R visitLoadUnitValue(LoadUnitValueInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitOperation(OperationInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitCallInstruction(CallInstruction instruction) {
return visitOperation(instruction);
}
public R visitCompilationErrorInstruction(CompilationErrorInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitMarkInstruction(MarkInstruction instruction) {
return visitInstructionWithNext(instruction);
}
public R visitMagic(MagicInstruction instruction) {
return visitOperation(instruction);
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
public abstract class InstructionVisitorWithResult<R>() {
public abstract fun visitInstruction(instruction: Instruction): R
public open fun visitInstructionWithReceiver(instruction: InstructionWithReceiver): R {
return visitInstructionWithNext(instruction)
}
public open fun visitReadValue(instruction: ReadValueInstruction): R {
return visitInstructionWithReceiver(instruction)
}
public open fun visitLocalFunctionDeclarationInstruction(instruction: LocalFunctionDeclarationInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitVariableDeclarationInstruction(instruction: VariableDeclarationInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitUnconditionalJump(instruction: UnconditionalJumpInstruction): R {
return visitJump(instruction)
}
public open fun visitConditionalJump(instruction: ConditionalJumpInstruction): R {
return visitJump(instruction)
}
public open fun visitReturnValue(instruction: ReturnValueInstruction): R {
return visitJump(instruction)
}
public open fun visitReturnNoValue(instruction: ReturnNoValueInstruction): R {
return visitJump(instruction)
}
public open fun visitThrowExceptionInstruction(instruction: ThrowExceptionInstruction): R {
return visitJump(instruction)
}
public open fun visitNondeterministicJump(instruction: NondeterministicJumpInstruction): R {
return visitInstruction(instruction)
}
public open fun visitUnsupportedElementInstruction(instruction: UnsupportedElementInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitSubroutineExit(instruction: SubroutineExitInstruction): R {
return visitInstruction(instruction)
}
public open fun visitSubroutineSink(instruction: SubroutineSinkInstruction): R {
return visitInstruction(instruction)
}
public open fun visitJump(instruction: AbstractJumpInstruction): R {
return visitInstruction(instruction)
}
public open fun visitInstructionWithNext(instruction: InstructionWithNext): R {
return visitInstruction(instruction)
}
public open fun visitSubroutineEnter(instruction: SubroutineEnterInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitWriteValue(instruction: WriteValueInstruction): R {
return visitInstructionWithReceiver(instruction)
}
public open fun visitLoadUnitValue(instruction: LoadUnitValueInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitOperation(instruction: OperationInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitCallInstruction(instruction: CallInstruction): R {
return visitOperation(instruction)
}
public open fun visitCompilationErrorInstruction(instruction: CompilationErrorInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitMarkInstruction(instruction: MarkInstruction): R {
return visitInstructionWithNext(instruction)
}
public open fun visitMagic(instruction: MagicInstruction): R {
return visitOperation(instruction)
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.Collection;
import java.util.Collections;
public abstract class InstructionWithNext extends JetElementInstructionImpl {
private Instruction next;
protected InstructionWithNext(@NotNull JetElement element, @NotNull LexicalScope lexicalScope) {
super(element, lexicalScope);
}
public Instruction getNext() {
return next;
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
return Collections.singleton(next);
}
public void setNext(Instruction next) {
this.next = outgoingEdgeTo(next);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
import java.util.Collections
import com.intellij.util.containers.ContainerUtil
public abstract class InstructionWithNext(
element: JetElement,
lexicalScope: LexicalScope
) : JetElementInstructionImpl(element, lexicalScope) {
public var next: Instruction? = null
set(value: Instruction?) {
$next = outgoingEdgeTo(value)
}
override val nextInstructions: Collection<Instruction>
get() = ContainerUtil.createMaybeSingletonList(next)
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;/**/
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.Collections;
import java.util.List;
public abstract class InstructionWithReceiver extends InstructionWithNext {
protected final PseudoValue receiverValue;
public InstructionWithReceiver(
@NotNull JetElement element,
@NotNull LexicalScope lexicalScope,
@Nullable PseudoValue receiverValue) {
super(element, lexicalScope);
this.receiverValue = receiverValue;
}
@NotNull
@Override
public List<PseudoValue> getInputValues() {
return receiverValue != null ? Collections.singletonList(receiverValue) : Collections.<PseudoValue>emptyList();
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
import com.intellij.util.containers.ContainerUtil
public abstract class InstructionWithReceiver(
element: JetElement,
lexicalScope: LexicalScope,
protected val receiverValue: PseudoValue?
) : InstructionWithNext(element, lexicalScope) {
override val inputValues: List<PseudoValue> = ContainerUtil.createMaybeSingletonList(receiverValue)
}

View File

@@ -28,10 +28,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
private JetControlFlowBuilder builder = null;
@@ -352,7 +349,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
@Override
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue inputValue) {
handleJumpInsideTryFinally(label);
add(new NondeterministicJumpInstruction(element, label, getCurrentScope(), inputValue));
add(new NondeterministicJumpInstruction(element, Collections.singletonList(label), getCurrentScope(), inputValue));
}
@Override
@@ -485,7 +482,8 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
@NotNull
private PseudoValue read(@NotNull JetExpression expression, @Nullable PseudoValue receiverValue) {
ReadValueInstruction instruction = new ReadValueInstruction(expression, getCurrentScope(), receiverValue, valueFactory);
ReadValueInstruction instruction =
ReadValueInstruction.object$.create(expression, getCurrentScope(), receiverValue, valueFactory);
add(instruction);
return instruction.getOutputValue();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,10 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetElement
public interface JetElementInstruction extends Instruction {
@NotNull
JetElement getElement();
public trait JetElementInstruction : Instruction {
public val element: JetElement
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
public abstract class JetElementInstructionImpl extends InstructionImpl implements JetElementInstruction {
@NotNull
protected final JetElement element;
public JetElementInstructionImpl(@NotNull JetElement element, LexicalScope lexicalScope) {
super(lexicalScope);
this.element = element;
}
@NotNull
@Override
public JetElement getElement() {
return element;
}
@NotNull
protected String render(PsiElement element) {
return element.getText().replaceAll("\\s+", " ");
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lang.psi.JetElement
public abstract class JetElementInstructionImpl(
public override val element: JetElement,
lexicalScope: LexicalScope
) : InstructionImpl(lexicalScope), JetElementInstruction {
protected fun render(element: PsiElement): String =
element.getText()?.replaceAll("\\s+", " ") ?: ""
}

View File

@@ -14,7 +14,6 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;/**/
package org.jetbrains.jet.lang.cfg.pseudocode
public interface JumpInstruction extends Instruction {
}
public trait JumpInstruction : Instruction

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetExpression;
public class LoadUnitValueInstruction extends InstructionWithNext {
public LoadUnitValueInstruction(@NotNull JetExpression expression, LexicalScope lexicalScope) {
super(expression, lexicalScope);
}
@Override
public void accept(InstructionVisitor visitor) {
visitor.visitLoadUnitValue(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitLoadUnitValue(this);
}
@Override
public String toString() {
return "read (Unit)";
}
@NotNull
@Override
protected Instruction createCopy() {
return new LoadUnitValueInstruction((JetExpression) element, lexicalScope);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetExpression
public class LoadUnitValueInstruction(
expression: JetExpression,
lexicalScope: LexicalScope
) : InstructionWithNext(expression, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitLoadUnitValue(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitLoadUnitValue(this)
}
override fun toString(): String =
"read (Unit)"
override fun createCopy(): InstructionImpl =
LoadUnitValueInstruction(element as JetExpression, lexicalScope)
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.ArrayList;
import java.util.Collection;
public class LocalFunctionDeclarationInstruction extends InstructionWithNext {
private final Pseudocode body;
private Instruction sink;
public LocalFunctionDeclarationInstruction(@NotNull JetElement element, @NotNull Pseudocode body, LexicalScope lexicalScope) {
super(element, lexicalScope);
this.body = body;
}
@NotNull
public Pseudocode getBody() {
return body;
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
if (sink != null) {
ArrayList<Instruction> instructions = Lists.newArrayList(sink);
instructions.addAll(super.getNextInstructions());
return instructions;
}
return super.getNextInstructions();
}
public void setSink(SubroutineSinkInstruction sink) {
this.sink = outgoingEdgeTo(sink);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitLocalFunctionDeclarationInstruction(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitLocalFunctionDeclarationInstruction(this);
}
@Override
public String toString() {
return "d" + "(" + render(element) + ")";
}
@NotNull
@Override
protected Instruction createCopy() {
return new LocalFunctionDeclarationInstruction(element, body, lexicalScope);
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import com.google.common.collect.Lists
import org.jetbrains.jet.lang.psi.JetElement
import java.util.ArrayList
public class LocalFunctionDeclarationInstruction(
element: JetElement,
public val body: Pseudocode,
lexicalScope: LexicalScope
) : InstructionWithNext(element, lexicalScope) {
public var sink: SubroutineSinkInstruction? = null
set(value: SubroutineSinkInstruction?) {
$sink = outgoingEdgeTo(value) as SubroutineSinkInstruction?
}
override val nextInstructions: Collection<Instruction>
get() {
if (sink != null) {
val instructions = Lists.newArrayList<Instruction>(sink)
instructions.addAll(super.nextInstructions)
return instructions
}
return super.nextInstructions
}
override fun accept(visitor: InstructionVisitor) {
visitor.visitLocalFunctionDeclarationInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitLocalFunctionDeclarationInstruction(this)
}
override fun toString(): String = "d(${render(element)})"
override fun createCopy(): InstructionImpl =
LocalFunctionDeclarationInstruction(element, body, lexicalScope)
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
// This instruciton is used to let the dead code detector know the syntactic structure of unreachable code
// otherwise only individual parts of expression would be reported as unreachable
// e.g. for (i in foo) {} -- only i and foo would be marked unreachable
public class MarkInstruction(
element: JetElement,
lexicalScope: LexicalScope
) : InstructionWithNext(element, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitMarkInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitMarkInstruction(this)
}
override fun createCopy() = MarkInstruction(element, lexicalScope)
override fun toString() = "mark(${render(element)})"
}

View File

@@ -1,131 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.*;
public class NondeterministicJumpInstruction extends JetElementInstructionImpl implements JumpInstruction {
private Instruction next;
private final List<Label> targetLabels;
private final Map<Label, Instruction> resolvedTargets;
private final PseudoValue inputValue;
public NondeterministicJumpInstruction(
@NotNull JetElement element,
List<Label> targetLabels,
LexicalScope lexicalScope,
@Nullable PseudoValue inputValue
) {
super(element, lexicalScope);
this.targetLabels = Lists.newArrayList(targetLabels);
resolvedTargets = Maps.newLinkedHashMap();
this.inputValue = inputValue;
}
public NondeterministicJumpInstruction(
@NotNull JetElement element,
Label targetLabel,
LexicalScope lexicalScope,
@Nullable PseudoValue inputValue
) {
this(element, Lists.newArrayList(targetLabel), lexicalScope, inputValue);
}
@NotNull
@Override
public List<PseudoValue> getInputValues() {
return Collections.singletonList(inputValue);
}
public List<Label> getTargetLabels() {
return targetLabels;
}
public Map<Label, Instruction> getResolvedTargets() {
return resolvedTargets;
}
public void setResolvedTarget(Label label, Instruction resolvedTarget) {
Instruction target = outgoingEdgeTo(resolvedTarget);
resolvedTargets.put(label, target);
}
public Instruction getNext() {
return next;
}
public void setNext(Instruction next) {
this.next = outgoingEdgeTo(next);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitNondeterministicJump(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitNondeterministicJump(this);
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
List<Instruction> targetInstructions = Lists.newArrayList(getResolvedTargets().values());
targetInstructions.add(getNext());
return targetInstructions;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("jmp?(");
for (Iterator<Label> iterator = targetLabels.iterator(); iterator.hasNext(); ) {
Label targetLabel = iterator.next();
sb.append(targetLabel.getName());
if (iterator.hasNext()) {
sb.append(", ");
}
}
if (inputValue != null) {
sb.append("|").append(inputValue);
}
sb.append(")");
return sb.toString();
}
@NotNull
@Override
protected Instruction createCopy() {
return createCopy(getTargetLabels());
}
@NotNull
public final Instruction copy(@NotNull List<Label> newTargetLabels) {
return updateCopyInfo(createCopy(newTargetLabels));
}
private Instruction createCopy(@NotNull List<Label> newTargetLabels) {
return new NondeterministicJumpInstruction(getElement(), newTargetLabels, lexicalScope, inputValue);
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import com.google.common.collect.Lists
import com.google.common.collect.Maps
import org.jetbrains.annotations.Nullable
import org.jetbrains.jet.lang.cfg.Label
import org.jetbrains.jet.lang.psi.JetElement
import java.util.*
import com.intellij.util.containers.ContainerUtil
public class NondeterministicJumpInstruction(
element: JetElement,
targetLabels: List<Label>,
lexicalScope: LexicalScope,
public val inputValue: PseudoValue?
) : JetElementInstructionImpl(element, lexicalScope), JumpInstruction {
private var _next: Instruction? = null
private val _resolvedTargets: MutableMap<Label, Instruction> = Maps.newLinkedHashMap()
public val targetLabels: List<Label> = Lists.newArrayList(targetLabels)
public val resolvedTargets: Map<Label, Instruction>
get() = _resolvedTargets
public fun setResolvedTarget(label: Label, resolvedTarget: Instruction) {
_resolvedTargets[label] = outgoingEdgeTo(resolvedTarget)!!
}
public var next: Instruction
get() = _next!!
set(value: Instruction) {
_next = outgoingEdgeTo(value)
}
override val nextInstructions: Collection<Instruction>
get() {
val targetInstructions = Lists.newArrayList(resolvedTargets.values())
targetInstructions.add(next)
return targetInstructions
}
override val inputValues: List<PseudoValue>
get() = ContainerUtil.createMaybeSingletonList(inputValue)
override fun accept(visitor: InstructionVisitor) {
visitor.visitNondeterministicJump(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitNondeterministicJump(this)
}
override fun toString(): String {
val inVal = if (inputValue != null) "|$inputValue" else ""
val labels = targetLabels.map { it.getName() }.makeString(", ")
return "jmp?($labels$inVal)"
}
override fun createCopy(): InstructionImpl {
return createCopy(targetLabels)
}
public fun copy(newTargetLabels: MutableList<Label>): Instruction {
return updateCopyInfo(createCopy(newTargetLabels))
}
private fun createCopy(newTargetLabels: List<Label>): InstructionImpl {
return NondeterministicJumpInstruction(element, newTargetLabels, lexicalScope, inputValue)
}
}

View File

@@ -41,6 +41,7 @@ public class PseudocodeImpl implements Pseudocode {
this.name = name;
}
@NotNull
@Override
public String getName() {
return name;
@@ -193,9 +194,9 @@ public class PseudocodeImpl implements Pseudocode {
}
private static boolean isDead(@NotNull Instruction instruction) {
if (!((InstructionImpl)instruction).isDead()) return false;
if (!((InstructionImpl)instruction).getDead()) return false;
for (Instruction copy : instruction.getCopies()) {
if (!((InstructionImpl)copy).isDead()) return false;
if (!((InstructionImpl)copy).getDead()) return false;
}
return true;
}
@@ -326,7 +327,7 @@ public class PseudocodeImpl implements Pseudocode {
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
Instruction nextInstruction = getNextPosition(currentPosition);
Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
if (instruction.onTrue()) {
if (instruction.getOnTrue()) {
instruction.setNextOnFalse(nextInstruction);
instruction.setNextOnTrue(jumpTarget);
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetElement;
public class ReadValueInstruction extends InstructionWithReceiver {
private final PseudoValue resultValue;
private ReadValueInstruction(
@NotNull JetElement element,
@NotNull LexicalScope lexicalScope,
@Nullable PseudoValue receiverValue,
@NotNull PseudoValue resultValue) {
super(element, lexicalScope, receiverValue);
this.resultValue = resultValue;
}
public ReadValueInstruction(
@NotNull JetElement element,
@NotNull LexicalScope lexicalScope,
@Nullable PseudoValue receiverValue,
@NotNull PseudoValueFactory valueFactory) {
super(element, lexicalScope, receiverValue);
this.resultValue = valueFactory.newValue(element, this);
}
@NotNull
@Override
public PseudoValue getOutputValue() {
return resultValue;
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitReadValue(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitReadValue(this);
}
@Override
public String toString() {
return "r(" + render(element) + (receiverValue != null ? ("|" + receiverValue) : "") + ") -> " + resultValue;
}
@NotNull
@Override
protected Instruction createCopy() {
return new ReadValueInstruction(element, lexicalScope, receiverValue, resultValue);
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.annotations.Nullable
import org.jetbrains.jet.lang.psi.JetElement
public class ReadValueInstruction private (
element: JetElement,
lexicalScope: LexicalScope,
receiverValue: PseudoValue?,
private var _outputValue: PseudoValue?
) : InstructionWithReceiver(element, lexicalScope, receiverValue) {
private fun newResultValue(factory: PseudoValueFactory) {
_outputValue = factory.newValue(element, this)
}
override val outputValue: PseudoValue
get() = _outputValue!!
override fun accept(visitor: InstructionVisitor) {
visitor.visitReadValue(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitReadValue(this)
}
override fun toString(): String {
val inVal = if (receiverValue != null) "|$receiverValue" else ""
return "r(${render(element)}$inVal) -> $outputValue"
}
override fun createCopy(): InstructionImpl =
ReadValueInstruction(element, lexicalScope, receiverValue, outputValue)
class object {
public fun create (
element: JetElement,
lexicalScope: LexicalScope,
receiverValue: PseudoValue?,
factory: PseudoValueFactory
): ReadValueInstruction {
return ReadValueInstruction(element, lexicalScope, receiverValue, null).let { instruction ->
instruction.newResultValue(factory)
instruction
}
}
}
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.psi.JetElement;
public class ReturnNoValueInstruction extends AbstractJumpInstruction {
public ReturnNoValueInstruction(@NotNull JetElement element, LexicalScope lexicalScope, Label targetLabel) {
super(element, targetLabel, lexicalScope);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitReturnNoValue(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitReturnNoValue(this);
}
@Override
public String toString() {
return "ret " + getTargetLabel();
}
@Override
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
return new ReturnNoValueInstruction(element, lexicalScope, newLabel);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.cfg.Label
import org.jetbrains.jet.lang.psi.JetElement
public class ReturnNoValueInstruction(
element: JetElement,
lexicalScope: LexicalScope,
targetLabel: Label
) : AbstractJumpInstruction(element, targetLabel, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitReturnNoValue(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitReturnNoValue(this)
}
override fun toString(): String = "ret $targetLabel"
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction =
ReturnNoValueInstruction(element, lexicalScope, newLabel)
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.psi.JetExpression;
import java.util.Collections;
import java.util.List;
public class ReturnValueInstruction extends AbstractJumpInstruction {
private final PseudoValue usedValue;
public ReturnValueInstruction(
@NotNull JetExpression returnExpression,
@NotNull LexicalScope lexicalScope,
@NotNull Label targetLabel,
@NotNull PseudoValue usedValue) {
super(returnExpression, targetLabel, lexicalScope);
this.usedValue = usedValue;
}
@NotNull
@Override
public List<PseudoValue> getInputValues() {
return Collections.singletonList(usedValue);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitReturnValue(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitReturnValue(this);
}
@Override
public String toString() {
return "ret(*|" + usedValue + ") " + getTargetLabel();
}
@Override
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
return new ReturnValueInstruction((JetExpression) element, lexicalScope, newLabel, usedValue);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.cfg.Label
import org.jetbrains.jet.lang.psi.JetExpression
import java.util.Collections
public class ReturnValueInstruction(
returnExpression: JetExpression,
lexicalScope: LexicalScope,
targetLabel: Label,
public val returnedValue: PseudoValue
) : AbstractJumpInstruction(returnExpression, targetLabel, lexicalScope) {
override val inputValues: List<PseudoValue> get() = Collections.singletonList(returnedValue)
override fun accept(visitor: InstructionVisitor) {
visitor.visitReturnValue(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitReturnValue(this)
}
override fun toString(): String {
return "ret(*|$returnedValue) $targetLabel"
}
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction {
return ReturnValueInstruction((element as JetExpression), lexicalScope, newLabel, returnedValue)
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
public class SubroutineEnterInstruction extends InstructionWithNext {
private final JetElement subroutine;
public SubroutineEnterInstruction(@NotNull JetElement subroutine, @NotNull LexicalScope lexicalScope) {
super(subroutine, lexicalScope);
this.subroutine = subroutine;
}
public JetElement getSubroutine() {
return subroutine;
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitSubroutineEnter(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitSubroutineEnter(this);
}
@Override
public String toString() {
return "<START>";
}
@NotNull
@Override
protected Instruction createCopy() {
return new SubroutineEnterInstruction(subroutine, lexicalScope);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
public class SubroutineEnterInstruction(
public val subroutine: JetElement,
lexicalScope: LexicalScope
) : InstructionWithNext(subroutine, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitSubroutineEnter(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitSubroutineEnter(this)
}
override fun toString(): String = "<START>"
override fun createCopy(): InstructionImpl =
SubroutineEnterInstruction(subroutine, lexicalScope)
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.Collection;
import java.util.Collections;
public class SubroutineExitInstruction extends InstructionImpl {
private final JetElement subroutine;
private final boolean isError;
private SubroutineSinkInstruction sinkInstruction;
public SubroutineExitInstruction(@NotNull JetElement subroutine, @NotNull LexicalScope lexicalScope, boolean isError) {
super(lexicalScope);
this.subroutine = subroutine;
this.isError = isError;
}
public JetElement getSubroutine() {
return subroutine;
}
public boolean isError() {
return isError;
}
public void setSink(SubroutineSinkInstruction instruction) {
sinkInstruction = (SubroutineSinkInstruction) outgoingEdgeTo(instruction);
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
assert sinkInstruction != null;
return Collections.<Instruction>singleton(sinkInstruction);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitSubroutineExit(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitSubroutineExit(this);
}
@Override
public String toString() {
return isError ? "<ERROR>" : "<END>";
}
@NotNull
@Override
protected Instruction createCopy() {
return new SubroutineExitInstruction(subroutine, lexicalScope, isError);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
import java.util.Collections
public class SubroutineExitInstruction(
public val subroutine: JetElement,
lexicalScope: LexicalScope,
public val isError: Boolean
) : InstructionImpl(lexicalScope) {
private var _sink: SubroutineSinkInstruction? = null
public var sink: SubroutineSinkInstruction
get() = _sink!!
set(value: SubroutineSinkInstruction) {
_sink = outgoingEdgeTo(value) as SubroutineSinkInstruction
}
override val nextInstructions: Collection<Instruction>
get() = Collections.singleton(sink)
override fun accept(visitor: InstructionVisitor) {
visitor.visitSubroutineExit(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitSubroutineExit(this)
}
override fun toString(): String = if (isError) "<ERROR>" else "<END>"
override fun createCopy(): InstructionImpl =
SubroutineExitInstruction(subroutine, lexicalScope, isError)
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.Collection;
import java.util.Collections;
public class SubroutineSinkInstruction extends InstructionImpl {
private final JetElement subroutine;
private final String debugLabel;
public SubroutineSinkInstruction(@NotNull JetElement subroutine, @NotNull LexicalScope lexicalScope, @NotNull String debugLabel) {
super(lexicalScope);
this.subroutine = subroutine;
this.debugLabel = debugLabel;
}
public JetElement getSubroutine() {
return subroutine;
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
return Collections.emptyList();
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitSubroutineSink(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitSubroutineSink(this);
}
@Override
public String toString() {
return debugLabel;
}
@NotNull
@Override
protected Instruction createCopy() {
return new SubroutineSinkInstruction(subroutine, lexicalScope, debugLabel);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
import java.util.Collections
public class SubroutineSinkInstruction(
public val subroutine: JetElement,
lexicalScope: LexicalScope,
private val debugLabel: String) : InstructionImpl(lexicalScope) {
override val nextInstructions: Collection<Instruction>
get() = Collections.emptyList()
override fun accept(visitor: InstructionVisitor) {
visitor.visitSubroutineSink(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitSubroutineSink(this)
}
override fun toString(): String = debugLabel
override fun createCopy(): InstructionImpl =
SubroutineSinkInstruction(subroutine, lexicalScope, debugLabel)
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.psi.JetThrowExpression;
import java.util.Collections;
import java.util.List;
public class ThrowExceptionInstruction extends AbstractJumpInstruction {
private final PseudoValue usedValue;
public ThrowExceptionInstruction(
@NotNull JetThrowExpression expression,
@NotNull LexicalScope lexicalScope,
@NotNull Label errorLabel,
@NotNull PseudoValue usedValue
) {
super(expression, errorLabel, lexicalScope);
this.usedValue = usedValue;
}
@Override
public String toString() {
return "throw (" + element.getText() + "|" + usedValue + ")";
}
@NotNull
@Override
public List<PseudoValue> getInputValues() {
return Collections.singletonList(usedValue);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitThrowExceptionInstruction(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitThrowExceptionInstruction(this);
}
@Override
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
return new ThrowExceptionInstruction((JetThrowExpression) element, lexicalScope, newLabel, usedValue);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.cfg.Label
import org.jetbrains.jet.lang.psi.JetThrowExpression
import java.util.Collections
public class ThrowExceptionInstruction(
expression: JetThrowExpression,
lexicalScope: LexicalScope,
errorLabel: Label,
public val thrownValue: PseudoValue
) : AbstractJumpInstruction(expression, errorLabel, lexicalScope) {
override val inputValues: List<PseudoValue> get() = Collections.singletonList(thrownValue)
override fun accept(visitor: InstructionVisitor) {
visitor.visitThrowExceptionInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitThrowExceptionInstruction(this)
}
override fun toString(): String {
return "throw (${element.getText()}|$thrownValue)"
}
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction {
return ThrowExceptionInstruction((element as JetThrowExpression), lexicalScope, newLabel, thrownValue)
}
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.psi.JetElement;
public class UnconditionalJumpInstruction extends AbstractJumpInstruction {
public UnconditionalJumpInstruction(@NotNull JetElement element, Label targetLabel, @NotNull LexicalScope lexicalScope) {
super(element, targetLabel, lexicalScope);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitUnconditionalJump(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitUnconditionalJump(this);
}
@Override
public String toString() {
return "jmp(" + getTargetLabel().getName() + ")";
}
@Override
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
return new UnconditionalJumpInstruction(element, newLabel, lexicalScope);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.cfg.Label
import org.jetbrains.jet.lang.psi.JetElement
public class UnconditionalJumpInstruction(
element: JetElement,
targetLabel: Label,
lexicalScope: LexicalScope
) : AbstractJumpInstruction(element, targetLabel, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitUnconditionalJump(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitUnconditionalJump(this)
}
override fun toString(): String = "jmp(${targetLabel.getName()})"
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction =
UnconditionalJumpInstruction(element, newLabel, lexicalScope)
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
public class UnsupportedElementInstruction extends InstructionWithNext {
protected UnsupportedElementInstruction(@NotNull JetElement element, @NotNull LexicalScope lexicalScope) {
super(element, lexicalScope);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitUnsupportedElementInstruction(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitUnsupportedElementInstruction(this);
}
@Override
public String toString() {
return "unsupported(" + element + " : " + render(element) + ")";
}
@NotNull
@Override
protected Instruction createCopy() {
return new UnsupportedElementInstruction(element, lexicalScope);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetElement
public class UnsupportedElementInstruction(
element: JetElement,
lexicalScope: LexicalScope
) : InstructionWithNext(element, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitUnsupportedElementInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitUnsupportedElementInstruction(this)
}
override fun toString(): String =
"unsupported(" + element + " : " + render(element) + ")"
override fun createCopy(): InstructionImpl =
UnsupportedElementInstruction(element, lexicalScope)
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.psi.JetVariableDeclaration;
public class VariableDeclarationInstruction extends InstructionWithNext {
protected VariableDeclarationInstruction(@NotNull JetParameter element, @NotNull LexicalScope lexicalScope) {
super(element, lexicalScope);
}
protected VariableDeclarationInstruction(@NotNull JetVariableDeclaration element, @NotNull LexicalScope lexicalScope) {
super(element, lexicalScope);
}
public JetDeclaration getVariableDeclarationElement() {
return (JetDeclaration) element;
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitVariableDeclarationInstruction(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitVariableDeclarationInstruction(this);
}
@Override
public String toString() {
return "v(" + render(element) + ")";
}
@NotNull
@Override
protected Instruction createCopy() {
if (element instanceof JetParameter) {
return new VariableDeclarationInstruction((JetParameter) element, lexicalScope);
}
return new VariableDeclarationInstruction((JetVariableDeclaration) element, lexicalScope);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.jet.lang.psi.JetDeclaration
import org.jetbrains.jet.lang.psi.JetParameter
import org.jetbrains.jet.lang.psi.JetVariableDeclaration
public class VariableDeclarationInstruction(
element: JetDeclaration,
lexicalScope: LexicalScope
) : InstructionWithNext(element, lexicalScope) {
{
assert(element is JetVariableDeclaration || element is JetParameter) { "Invalid element: ${render(element)}}" }
}
public val variableDeclarationElement: JetDeclaration
get() = element as JetDeclaration
override fun accept(visitor: InstructionVisitor) {
visitor.visitVariableDeclarationInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitVariableDeclarationInstruction(this)
}
override fun toString(): String = "v(${render(element)})"
override fun createCopy(): InstructionImpl =
VariableDeclarationInstruction(variableDeclarationElement, lexicalScope)
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class WriteValueInstruction extends InstructionWithReceiver {
@NotNull
private final JetElement lValue;
@NotNull
private final PseudoValue rValue;
public WriteValueInstruction(
@NotNull JetElement assignment,
@NotNull JetElement lValue,
@NotNull PseudoValue rValue,
@Nullable PseudoValue receiverValue,
@NotNull LexicalScope lexicalScope) {
super(assignment, lexicalScope, receiverValue);
this.lValue = lValue;
this.rValue = rValue;
}
@NotNull
public JetElement getlValue() {
return lValue;
}
@NotNull
@Override
public List<PseudoValue> getInputValues() {
return receiverValue != null ? Arrays.asList(rValue, receiverValue) : Collections.singletonList(rValue);
}
@Override
public void accept(@NotNull InstructionVisitor visitor) {
visitor.visitWriteValue(this);
}
@Override
public <R> R accept(@NotNull InstructionVisitorWithResult<R> visitor) {
return visitor.visitWriteValue(this);
}
@Override
public String toString() {
String lhs = lValue instanceof JetNamedDeclaration ? lValue.getName() : render(lValue);
return "w(" + lhs + "|" + (receiverValue != null ? (receiverValue + ", ") : "") + rValue.toString() + ")";
}
@NotNull
@Override
protected Instruction createCopy() {
return new WriteValueInstruction(element, lValue, rValue, receiverValue, lexicalScope);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode
import org.jetbrains.annotations.Nullable
import org.jetbrains.jet.lang.psi.JetElement
import org.jetbrains.jet.lang.psi.JetNamedDeclaration
import java.util.Arrays
import java.util.Collections
public class WriteValueInstruction(
assignment: JetElement,
public val lValue: JetElement,
public val rValue: PseudoValue,
receiverValue: PseudoValue?,
lexicalScope: LexicalScope
) : InstructionWithReceiver(assignment, lexicalScope, receiverValue) {
override val inputValues: List<PseudoValue>
get() = receiverValue?.let{ receiverValue -> Arrays.asList(receiverValue, rValue) } ?: Collections.singletonList(rValue)
override fun accept(visitor: InstructionVisitor) {
visitor.visitWriteValue(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitWriteValue(this)
}
override fun toString(): String {
val lhs = (lValue as? JetNamedDeclaration)?.getName() ?: render(lValue)
return "w($lhs|${inputValues.makeString(", ")})"
}
override fun createCopy(): InstructionImpl =
WriteValueInstruction(element, lValue, rValue, receiverValue, lexicalScope)
}

View File

@@ -20,19 +20,19 @@ import org.jetbrains.jet.lang.psi.JetElement
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
import kotlin.properties.Delegates
abstract class OperationInstruction protected(
public abstract class OperationInstruction protected(
element: JetElement,
lexicalScope: LexicalScope,
val usedValues: List<PseudoValue>
public override val inputValues: List<PseudoValue>
) : InstructionWithNext(element, lexicalScope) {
protected var resultValue: PseudoValue? = null
override fun getInputValues(): List<PseudoValue> = usedValues
override fun getOutputValue(): PseudoValue? = resultValue
override val outputValue: PseudoValue?
get() = resultValue
protected fun renderInstruction(name: String, desc: String): String =
"$name($desc" +
(if (usedValues.notEmpty) "|${usedValues.makeString(", ")})" else ")") +
(if (inputValues.notEmpty) "|${inputValues.makeString(", ")})" else ")") +
(if (resultValue != null) " -> $resultValue" else "")
protected fun setResult(value: PseudoValue?): OperationInstruction {
@@ -45,22 +45,22 @@ abstract class OperationInstruction protected(
}
}
class CallInstruction private(
public class CallInstruction private(
element: JetElement,
lexicalScope: LexicalScope,
val resolvedCall: ResolvedCall<*>,
usedValues: List<PseudoValue>
) : OperationInstruction(element, lexicalScope, usedValues) {
inputValues: List<PseudoValue>
) : OperationInstruction(element, lexicalScope, inputValues) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitCallInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R? {
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitCallInstruction(this)
}
override fun createCopy() =
CallInstruction(element, lexicalScope, resolvedCall, usedValues).setResult(resultValue)
CallInstruction(element, lexicalScope, resolvedCall, inputValues).setResult(resultValue)
override fun toString() =
renderInstruction("call", "${render(element)}, ${resolvedCall.getResultingDescriptor()!!.getName()}")
@@ -70,9 +70,9 @@ class CallInstruction private(
element: JetElement,
lexicalScope: LexicalScope,
resolvedCall: ResolvedCall<*>,
usedValues: List<PseudoValue>,
inputValues: List<PseudoValue>,
factory: PseudoValueFactory?
): CallInstruction = CallInstruction(element, lexicalScope, resolvedCall, usedValues).setResult(factory) as CallInstruction
): CallInstruction = CallInstruction(element, lexicalScope, resolvedCall, inputValues).setResult(factory) as CallInstruction
}
}
@@ -83,24 +83,25 @@ class CallInstruction private(
// pass more than one value to instruction which formally requires only one (e.g. jump)
// "Synthetic" means that the instruction does not correspond to some operation explicitly expressed by PSI element
// Examples: merging branches of 'if', 'when' and 'try' expressions, providing initial values for parameters, etc.
class MagicInstruction(
public class MagicInstruction(
element: JetElement,
lexicalScope: LexicalScope,
val synthetic: Boolean,
usedValues: List<PseudoValue>
) : OperationInstruction(element, lexicalScope, usedValues) {
override fun getOutputValue(): PseudoValue = resultValue!!
inputValues: List<PseudoValue>
) : OperationInstruction(element, lexicalScope, inputValues) {
override val outputValue: PseudoValue
get() = resultValue!!
override fun accept(visitor: InstructionVisitor) {
visitor.visitMagic(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R? {
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
return visitor.visitMagic(this)
}
override fun createCopy() =
MagicInstruction(element, lexicalScope, synthetic, usedValues).setResult(resultValue)
MagicInstruction(element, lexicalScope, synthetic, inputValues).setResult(resultValue)
override fun toString() = renderInstruction("magic", render(element))
@@ -110,47 +111,8 @@ class MagicInstruction(
valueElement: JetElement?,
lexicalScope: LexicalScope,
synthetic: Boolean,
usedValues: List<PseudoValue>,
inputValues: List<PseudoValue>,
factory: PseudoValueFactory
): MagicInstruction = MagicInstruction(element, lexicalScope, synthetic, usedValues).setResult(factory, valueElement) as MagicInstruction
): MagicInstruction = MagicInstruction(element, lexicalScope, synthetic, inputValues).setResult(factory, valueElement) as MagicInstruction
}
}
class CompilationErrorInstruction(
element: JetElement,
lexicalScope: LexicalScope,
val message: String
) : InstructionWithNext(element, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitCompilationErrorInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R? {
return visitor.visitCompilationErrorInstruction(this)
}
override fun createCopy() = CompilationErrorInstruction(element, lexicalScope, message)
override fun toString() = "error(${render(element)}, $message)"
}
// This instruciton is used to let the dead code detector know the syntactic structure of unreachable code
// otherwise only individual parts of expression would be reported as unreachable
// e.g. for (i in foo) {} -- only i and foo would be marked unreachable
class MarkInstruction(
element: JetElement,
lexicalScope: LexicalScope
) : InstructionWithNext(element, lexicalScope) {
override fun accept(visitor: InstructionVisitor) {
visitor.visitMarkInstruction(this)
}
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R? {
return visitor.visitMarkInstruction(this)
}
override fun createCopy() = MarkInstruction(element, lexicalScope)
override fun toString() = "mark(${render(element)})"
}

View File

@@ -21,7 +21,6 @@ import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.traverseFollowingInstructi
import java.util.HashSet
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder
import org.jetbrains.jet.lang.psi.JetFunction
import org.jetbrains.jet.lang.psi.JetBlockExpression
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
import org.jetbrains.jet.lang.psi.JetFunctionLiteral
@@ -41,6 +40,6 @@ fun JetExpression.isStatement(pseudocode: Pseudocode): Boolean {
}
val instruction = value.createdAt
if (considerUsedIfCreatedBeforeExit() && instruction.getNextInstructions().any { it == pseudocode.getExitInstruction() }) return false
return traverseFollowingInstructions(instruction, HashSet(), TraversalOrder.FORWARD) { value !in it.getInputValues() }
if (considerUsedIfCreatedBeforeExit() && instruction.nextInstructions.any { it == pseudocode.getExitInstruction() }) return false
return traverseFollowingInstructions(instruction, HashSet(), TraversalOrder.FORWARD) { value !in it.inputValues }
}

View File

@@ -109,7 +109,7 @@ public abstract class AbstractControlFlowTest extends AbstractPseudocodeTest {
//check edges directions
Collection<Instruction> instructions = pseudocode.getAllInstructions();
for (Instruction instruction : instructions) {
if (!((InstructionImpl)instruction).isDead()) {
if (!((InstructionImpl)instruction).getDead()) {
for (Instruction nextInstruction : instruction.getNextInstructions()) {
assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa",
nextInstruction.getPreviousInstructions().contains(instruction));

View File

@@ -45,7 +45,7 @@ public abstract class AbstractPseudoValueTest : AbstractPseudocodeTest() {
fun elementText(element: JetElement): String = element.getText()!!.replaceAll("\\s+", " ")
fun valueDescription(element: JetElement, value: PseudoValue): String {
return if (value.element != element) "COPY" else "NEW${value.createdAt.getInputValues().makeString(", ", "(", ")")}"
return if (value.element != element) "COPY" else "NEW${value.createdAt.inputValues.makeString(", ", "(", ")")}"
}
val elementToValues = getElementToValueMap(pseudocode)

View File

@@ -135,7 +135,7 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment {
@NotNull Set<Instruction> remainedAfterPostProcessInstructions
) {
boolean isRemovedThroughPostProcess = !remainedAfterPostProcessInstructions.contains(instruction);
assert isRemovedThroughPostProcess == ((InstructionImpl)instruction).isDead();
assert isRemovedThroughPostProcess == ((InstructionImpl)instruction).getDead();
return isRemovedThroughPostProcess ? "-" : " ";
}

View File

@@ -70,27 +70,27 @@ private fun List<Instruction>.getModifiedVarDescriptors(bindingContext: BindingC
}
private fun List<Instruction>.getExitPoints(): List<Instruction> =
filter { localInstruction -> localInstruction.getNextInstructions().any { it !in this } }
filter { localInstruction -> localInstruction.nextInstructions.any { it !in this } }
private fun List<Instruction>.getResultType(bindingContext: BindingContext, options: ExtractionOptions): JetType {
fun instructionToType(instruction: Instruction): JetType? {
val expression = when (instruction) {
is ReturnValueInstruction -> {
(instruction.getElement() as JetReturnExpression).getReturnedExpression()
(instruction.element as JetReturnExpression).getReturnedExpression()
}
is CallInstruction -> {
val callElement = instruction.resolvedCall.getCall().getCallElement() as? JetExpression
if (callElement is JetSimpleNameExpression) callElement.getParentByType(javaClass<JetExpression>(), true) else callElement
}
is ReadValueInstruction, is OperationInstruction -> {
(instruction as JetElementInstruction).getElement() as? JetExpression
(instruction as JetElementInstruction).element as? JetExpression
}
else -> null
}
if (expression == null) return null
if (options.inferUnitTypeForUnusedValues) {
val pseudocode = firstOrNull()?.getOwner()
val pseudocode = firstOrNull()?.owner
if (pseudocode != null && expression.isStatement(pseudocode)) return null
}
@@ -102,8 +102,8 @@ private fun List<Instruction>.getResultType(bindingContext: BindingContext, opti
}
private fun List<AbstractJumpInstruction>.checkEquivalence(checkPsi: Boolean): Boolean {
if (mapTo(HashSet<Label?>()) { it.getTargetLabel() }.size > 1) return false
return !checkPsi || mapTo(HashSet<String?>()) { it.getElement().getText() }.size <= 1
if (mapTo(HashSet<Label?>()) { it.targetLabel }.size > 1) return false
return !checkPsi || mapTo(HashSet<String?>()) { it.element.getText() }.size <= 1
}
private fun JetType.isMeaningful(): Boolean {
@@ -121,10 +121,10 @@ private fun List<Instruction>.analyzeControlFlow(
val defaultExits = ArrayList<Instruction>()
val jumpExits = ArrayList<AbstractJumpInstruction>()
exitPoints.forEach {
val e = (it as? UnconditionalJumpInstruction)?.getElement()
val e = (it as? UnconditionalJumpInstruction)?.element
val insn =
if (e != null && e !is JetBreakExpression && e !is JetContinueExpression) {
it.getPreviousInstructions().firstOrNull()
it.previousInstructions.firstOrNull()
}
else it
@@ -132,7 +132,7 @@ private fun List<Instruction>.analyzeControlFlow(
is ReturnValueInstruction -> valuedReturnExits.add(insn)
is AbstractJumpInstruction -> {
val element = insn.getElement()
val element = insn.element
if (element is JetReturnExpression
|| element is JetBreakExpression
|| element is JetContinueExpression) {
@@ -187,7 +187,7 @@ private fun List<Instruction>.analyzeControlFlow(
if (defaultExits.isNotEmpty()) {
if (valuedReturnExits.size != 1) return multipleExitsError
val element = valuedReturnExits.first!!.getElement()
val element = valuedReturnExits.first!!.element
return Pair(ConditionalJump(listOf(element), element), null)
}
@@ -198,7 +198,7 @@ private fun List<Instruction>.analyzeControlFlow(
if (jumpExits.isNotEmpty()) {
if (!jumpExits.checkEquivalence(true)) return multipleExitsError
val elements = jumpExits.map { it.getElement() }
val elements = jumpExits.map { it.element }
if (defaultExits.isNotEmpty()) return Pair(ConditionalJump(elements, elements.first!!), null)
return Pair(UnconditionalJump(elements, elements.first!!), null)
}
@@ -505,7 +505,7 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
val pseudocode = PseudocodeUtil.generatePseudocode(enclosingDeclaration, bindingContext)
val localInstructions = pseudocode.getInstructions().filter {
it is JetElementInstruction && it.getElement().isInsideOf(originalElements)
it is JetElementInstruction && it.element.isInsideOf(originalElements)
}
val replacementMap = HashMap<Int, Replacement>()